Revision: 7360 http://playerstage.svn.sourceforge.net/playerstage/?rev=7360&view=rev Author: rtv Date: 2009-03-03 18:40:23 +0000 (Tue, 03 Mar 2009)
Log Message: ----------- fixed thread pool implementation Modified Paths: -------------- code/stage/trunk/CMakeLists.txt code/stage/trunk/config.h.in code/stage/trunk/libstage/model_gripper.cc code/stage/trunk/libstage/stage.hh code/stage/trunk/libstage/world.cc code/stage/trunk/libstage/worldgui.cc code/stage/trunk/worlds/fasr.world Modified: code/stage/trunk/CMakeLists.txt =================================================================== --- code/stage/trunk/CMakeLists.txt 2009-03-02 02:06:19 UTC (rev 7359) +++ code/stage/trunk/CMakeLists.txt 2009-03-03 18:40:23 UTC (rev 7360) @@ -14,6 +14,8 @@ OPTION (BUILD_LSPTEST "Build Player plugin tests" OFF) OPTION (CPACK_CFG "[release building] generate CPack configuration files" OFF) +OPTION (BUILD_GUI "WARNING: turning this off breaks the build right now. Build FLTK-based GUI. If OFF, build a gui-less Stage useful e.g. for headless compute clusters." ON ) + cmake_minimum_required( VERSION 2.4 FATAL_ERROR ) IF (CMAKE_MAJOR_VERSION EQUAL 2 AND NOT CMAKE_MINOR_VERSION LESS 6) @@ -75,6 +77,10 @@ MESSAGE( ${INDENT} "Libpng not detected" ) ENDIF( LIBPNG_FOUND ) +MESSAGE( STATUS "BUILD_GUI is ${BUILD_GUI}" ) + +IF( BUILD_GUI ) + ## the FLTK package script is not useful - it finds an X11-based FLTK on OS X. ## so we can't do this stuff #find_package( FLTK REQUIRED ) @@ -125,6 +131,8 @@ SET (FLTK_FOUND TRUE) +ENDIF( BUILD_GUI ) + #MESSAGE( ${INDENT} "Checking for OpenGL" ) find_package( OpenGL REQUIRED ) IF( NOT OPENGL_GLU_FOUND ) @@ -157,6 +165,8 @@ # SET(APPLE_LIBRARIES "-Wl,-dylib_file,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib") #ENDIF (APPLE) +MESSAGE( STATUS "Installation directory CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}" ) + # all targets need these include directories include_directories( . libstage Modified: code/stage/trunk/config.h.in =================================================================== --- code/stage/trunk/config.h.in 2009-03-02 02:06:19 UTC (rev 7359) +++ code/stage/trunk/config.h.in 2009-03-03 18:40:23 UTC (rev 7360) @@ -6,5 +6,7 @@ #define APIVERSION "@APIVERSION@" #define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@" +#cmakedefine BUILD_GUI + #endif Modified: code/stage/trunk/libstage/model_gripper.cc =================================================================== --- code/stage/trunk/libstage/model_gripper.cc 2009-03-02 02:06:19 UTC (rev 7359) +++ code/stage/trunk/libstage/model_gripper.cc 2009-03-03 18:40:23 UTC (rev 7360) @@ -93,6 +93,9 @@ FixBlocks(); + // Update() is not reentrant + thread_safe = false; + // default size Geom geom; geom.pose.x = 0.0; @@ -205,6 +208,8 @@ void ModelGripper::Update() { + //return; + // no work to do if we're unsubscribed if( subs < 1 ) { Modified: code/stage/trunk/libstage/stage.hh =================================================================== --- code/stage/trunk/libstage/stage.hh 2009-03-02 02:06:19 UTC (rev 7359) +++ code/stage/trunk/libstage/stage.hh 2009-03-03 18:40:23 UTC (rev 7360) @@ -897,7 +897,11 @@ stg_usec_t sim_time; ///< the current sim time in this world in ms GHashTable* superregions; SuperRegion* sr_cached; ///< The last superregion looked up by this world - GList* update_list; ///< Models that have a subscriber or controller, and need to be updated + // GList* update_list; ///< Models that have a subscriber or controller, and need to be updated + + GList* reentrant_update_list; ///< It is safe to call these model's Update() in parallel + GList* nonreentrant_update_list; ///< It is NOT safe to call these model's Update() in parallel + long unsigned int updates; ///< the number of simulated time steps executed so far Worldfile* wf; ///< If set, points to the worldfile used to create this world @@ -984,25 +988,13 @@ /** Returns true iff the current time is greater than the time we should quit */ bool PastQuitTime(); + + void StartUpdatingModel( Model* mod ); + void StopUpdatingModel( Model* mod ); - void StartUpdatingModel( Model* mod ) - { - if( ! g_list_find( update_list, mod ) ) - update_list = g_list_append( update_list, mod ); - } + void StartUpdatingModelPose( Model* mod ); + void StopUpdatingModelPose( Model* mod ); - void StopUpdatingModel( Model* mod ) - { update_list = g_list_remove( update_list, mod ); } - - void StartUpdatingModelPose( Model* mod ) - { - if( ! g_list_find( velocity_list, mod ) ) - velocity_list = g_list_append( velocity_list, mod ); - } - - void StopUpdatingModelPose( Model* mod ) - { velocity_list = g_list_remove( velocity_list, mod ); } - static void update_thread_entry( Model* mod, World* world ); public: Modified: code/stage/trunk/libstage/world.cc =================================================================== --- code/stage/trunk/libstage/world.cc 2009-03-02 02:06:19 UTC (rev 7359) +++ code/stage/trunk/libstage/world.cc 2009-03-03 18:40:23 UTC (rev 7360) @@ -102,7 +102,9 @@ superregions( g_hash_table_new( (GHashFunc)PointIntHash, (GEqualFunc)PointIntEqual ) ), sr_cached(NULL), - update_list( NULL ), + // update_list( NULL ), + reentrant_update_list( NULL ), + nonreentrant_update_list( NULL ), updates( 0 ), wf( NULL ) { @@ -377,8 +379,11 @@ g_hash_table_remove_all( models_by_name ); - g_list_free( update_list ); - update_list = NULL; + g_list_free( reentrant_update_list ); + reentrant_update_list = NULL; + + g_list_free( nonreentrant_update_list ); + nonreentrant_update_list = NULL; g_list_free( ray_list ); ray_list = NULL; @@ -432,29 +437,27 @@ // something that takes charge LISTMETHOD( charge_list, Model*, UpdateCharge ); - // then update all sensors + // then update all models on the update lists + LISTMETHOD( nonreentrant_update_list, Model*, UpdateIfDue ); + if( worker_threads == 0 ) // do all the work in this thread { - LISTMETHOD( update_list, Model*, UpdateIfDue ); + LISTMETHOD( reentrant_update_list, Model*, UpdateIfDue ); } else // use worker threads { // push the update for every model that needs it into the thread pool - for( GList* it = update_list; it; it=it->next ) + for( GList* it = reentrant_update_list; it; it=it->next ) { Model* mod = (Model*)it->data; if( mod->UpdateDue() ) { - if( mod->thread_safe ) // do update in a worker thread - { - g_mutex_lock( thread_mutex ); - update_jobs_pending++; - g_mutex_unlock( thread_mutex ); - g_thread_pool_push( threadpool, mod, NULL ); - } - else - mod->Update(); // do update in this thread + // printf( "updating model %s in WORKER thread\n", mod->Token() ); + g_mutex_lock( thread_mutex ); + update_jobs_pending++; + g_mutex_unlock( thread_mutex ); + g_thread_pool_push( threadpool, mod, NULL ); } } @@ -953,3 +956,41 @@ { g_hash_table_insert( option_table, (void*)opt->htname, opt ); } + +void World::StartUpdatingModel( Model* mod ) +{ + //if( ! g_list_find( update_list, mod ) ) + // update_list = g_list_append( update_list, mod ); + + if( mod->thread_safe ) + { + if( ! g_list_find( reentrant_update_list, mod ) ) + reentrant_update_list = g_list_append( reentrant_update_list, mod ); + } + else + { + if( ! g_list_find( nonreentrant_update_list, mod ) ) + nonreentrant_update_list = g_list_append( nonreentrant_update_list, mod ); + } +} + +void World::StopUpdatingModel( Model* mod ) +{ + // update_list = g_list_remove( update_list, mod ); + + if( mod->thread_safe ) + reentrant_update_list = g_list_remove( reentrant_update_list, mod ); + else + nonreentrant_update_list = g_list_remove( nonreentrant_update_list, mod ); +} + +void World::StartUpdatingModelPose( Model* mod ) +{ + if( ! g_list_find( velocity_list, mod ) ) + velocity_list = g_list_append( velocity_list, mod ); +} + +void World::StopUpdatingModelPose( Model* mod ) +{ + velocity_list = g_list_remove( velocity_list, mod ); +} Modified: code/stage/trunk/libstage/worldgui.cc =================================================================== --- code/stage/trunk/libstage/worldgui.cc 2009-03-02 02:06:19 UTC (rev 7359) +++ code/stage/trunk/libstage/worldgui.cc 2009-03-03 18:40:23 UTC (rev 7360) @@ -845,11 +845,17 @@ std::set<Option*, Option::optComp> options; std::vector<Option*> modOpts; - for( GList* it=update_list; it; it=it->next ) + for( GList* it=reentrant_update_list; it; it=it->next ) { modOpts = ((Model*)it->data)->getOptions(); options.insert( modOpts.begin(), modOpts.end() ); } + + for( GList* it=nonreentrant_update_list; it; it=it->next ) + { + modOpts = ((Model*)it->data)->getOptions(); + options.insert( modOpts.begin(), modOpts.end() ); + } drawOptions.assign( options.begin(), options.end() ); Modified: code/stage/trunk/worlds/fasr.world =================================================================== --- code/stage/trunk/worlds/fasr.world 2009-03-02 02:06:19 UTC (rev 7359) +++ code/stage/trunk/worlds/fasr.world 2009-03-03 18:40:23 UTC (rev 7360) @@ -13,8 +13,8 @@ resolution 0.02 # threads may speed things up here depending on available CPU cores & workload - threadpool 0 -# threadpool 3 +# threadpool 0 + threadpool 0 # configure the GUI window @@ -72,7 +72,7 @@ define autorob pioneer2dx ( - sicklaser( samples 32 range_max 5 laser_return 2 watts 30 ) + sicklaser( samples 16 range_max 5 laser_return 2 watts 30 ) ctrl "fasr" joules 100000 joules_capacity 400000 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H _______________________________________________ Playerstage-commit mailing list Playerstage-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/playerstage-commit