Revision: 2447 http://rigsofrods.svn.sourceforge.net/rigsofrods/?rev=2447&view=rev Author: rorthomas Date: 2012-02-04 15:38:52 +0000 (Sat, 04 Feb 2012) Log Message: ----------- improved threading, added remove tests
Modified Paths: -------------- trunk/source/main/physics/BeamFactory.cpp trunk/source/main/physics/threading/BeamWorker.cpp trunk/source/main/physics/threading/BeamWorker.h trunk/source/main/physics/threading/BeamWorkerManager.cpp trunk/source/main/physics/threading/BeamWorkerManager.h Modified: trunk/source/main/physics/BeamFactory.cpp =================================================================== --- trunk/source/main/physics/BeamFactory.cpp 2012-02-04 14:00:06 UTC (rev 2446) +++ trunk/source/main/physics/BeamFactory.cpp 2012-02-04 15:38:52 UTC (rev 2447) @@ -80,14 +80,8 @@ tdr = new TwoDReplay(); - // TEST for Beamworker, add example instances - /* - for(int i=0; i < 60; i++) - { - new BeamWorker(); - //new BeamWorker(); - } - */ + // TEST for Beamworker + //BeamWorkerManager::getSingleton(); } BeamFactory::~BeamFactory() Modified: trunk/source/main/physics/threading/BeamWorker.cpp =================================================================== --- trunk/source/main/physics/threading/BeamWorker.cpp 2012-02-04 14:00:06 UTC (rev 2446) +++ trunk/source/main/physics/threading/BeamWorker.cpp 2012-02-04 15:38:52 UTC (rev 2447) @@ -41,7 +41,7 @@ return NULL; } -BeamWorker::BeamWorker() +BeamWorker::BeamWorker() : running(true), test1(0) { pthread_create(&thread, NULL, threadWorkerEntry, (void*)this); } @@ -66,7 +66,7 @@ try { // additional exception handler required, otherwise RoR just crashes upon exception - while (1) + while (running) { // sync threads syncBeamThreads(); @@ -80,15 +80,21 @@ // TODO: error handling } LOG("TR| BeamWorker exiting: " + TOSTRING(ThreadID::getID())); + delete(this); } void BeamWorker::_doWork() { - int seconds = Ogre::Math::RangeRandom(1, 10); + float seconds = Ogre::Math::RangeRandom(0.1f, 2.0f); LOG("TR| BeamWorker doing work: " + TOSTRING(ThreadID::getID()) + " sleeping " + TOSTRING(seconds) + " seconds"); - sleep(seconds); + test1 += seconds; + if(test1 > 5) + killWorker(); + + sleepMilliSeconds(seconds); + #if 0 float dtperstep=dt/(Real)steps; Modified: trunk/source/main/physics/threading/BeamWorker.h =================================================================== --- trunk/source/main/physics/threading/BeamWorker.h 2012-02-04 14:00:06 UTC (rev 2446) +++ trunk/source/main/physics/threading/BeamWorker.h 2012-02-04 15:38:52 UTC (rev 2447) @@ -32,15 +32,16 @@ { protected: pthread_t thread; + bool running; + + float test1; public: BeamWorker(); ~BeamWorker(); // called from the new thread, do not execute manually void _startWorkerLoop(); + void killWorker() { running=false; } protected: - float tdt; - float ttdt; - // method to work off one beam void _doWork(); }; Modified: trunk/source/main/physics/threading/BeamWorkerManager.cpp =================================================================== --- trunk/source/main/physics/threading/BeamWorkerManager.cpp 2012-02-04 14:00:06 UTC (rev 2446) +++ trunk/source/main/physics/threading/BeamWorkerManager.cpp 2012-02-04 15:38:52 UTC (rev 2447) @@ -26,8 +26,9 @@ #include <Ogre.h> #include "Settings.h" #include "utils.h" +#include <unistd.h> +#include <time.h> - using namespace Ogre; void *threadWorkerManagerEntry(void* ptr) @@ -41,6 +42,7 @@ BeamWorkerManager::BeamWorkerManager() : threads() , threadsSize(0) + , targetThreadSize(4096) , done_count(0) , done_count_mutex() , done_count_cv() @@ -67,24 +69,37 @@ void BeamWorkerManager::_startWorkerLoop() { LOG("worker manager started in thread " + TOSTRING(ThreadID::getID())); + int rc = 0; + struct timespec timeout; while (1) { MUTEX_LOCK(&done_count_mutex); while (done_count < threadsSize) { LOG("TR| worker loop continued, waiting for more threads | threads waiting: " + TOSTRING(done_count) + " / " + TOSTRING(threadsSize)); - pthread_cond_wait(&done_count_cv, &done_count_mutex); + + // set timeout + timeout.tv_sec = time(NULL); + timeout.tv_nsec = 5000; + + // then wait for signal or time + rc = pthread_cond_timedwait(&done_count_cv, &done_count_mutex, &timeout); } + LOG("TR| worker loop done | threads waiting: " + TOSTRING(done_count) + " / " + TOSTRING(threadsSize)); MUTEX_UNLOCK(&done_count_mutex); LOG("TR| worker loop lock acquired, all threads sleeping..."); // we got through, all threads should be stopped by now + // create new threads? + _checkRunThreads(); + // TODO: make modifications on truck array in here - sleep(3); + if(threadsSize < 409) + sleepMilliSeconds(100); // reset counter, continue all threads via signal - LOG("TR| worker loop: unpausing all threads"); + LOG("TR| worker loop: un-pausing all threads"); MUTEX_LOCK(&done_count_mutex); done_count=0; // send signals to the threads @@ -97,6 +112,12 @@ } } +void BeamWorkerManager::_checkRunThreads() +{ + for(int i=threadsSize; i < targetThreadSize; i++) + new BeamWorker(); +} + void BeamWorkerManager::addThread(BeamThread *bthread) { // threadID is not valid in this context! @@ -108,7 +129,7 @@ wd.threadID = -1; LOG("TR| add Thread: " + TOSTRING(bthread)); threads[bthread] = wd; - threadsSize++; + threadsSize = threads.size(); MUTEX_UNLOCK(&api_mutex); } @@ -116,13 +137,25 @@ { // threadID is not valid in this context! MUTEX_LOCK(&api_mutex); - pthread_cond_destroy(&threads[bthread].work_cv); - pthread_mutex_destroy(&threads[bthread].work_mutex); - LOG("TR| remove Thread: " + TOSTRING(bthread)); - threads[bthread].bthread = NULL; - threads[bthread].threadID = 0; - threadsSize--; + threadMap::iterator it = threads.find(bthread); + if(it == threads.end()) + { + LOG("unknown thread calling remove: class " + TOSTRING((unsigned long)bthread)); + return; + } + LOG("TR| remove Thread: " + TOSTRING((unsigned long)bthread)); + workerData_t &wd = it->second; + pthread_cond_destroy(&wd.work_cv); + pthread_mutex_destroy(&wd.work_mutex); + threads.erase(it); + threadsSize = threads.size(); MUTEX_UNLOCK(&api_mutex); + + // trigger main thread so it wont wait for eternity for the now missing thread + MUTEX_LOCK(&done_count_mutex); + pthread_cond_signal(&done_count_cv); + MUTEX_UNLOCK(&done_count_mutex); + } void BeamWorkerManager::syncThreads(BeamThread *bthread) @@ -132,7 +165,7 @@ threadMap::iterator it = threads.find(bthread); if(it == threads.end()) { - LOG("unknown thread calling: " + TOSTRING(tid) + " / class " + TOSTRING(bthread)); + LOG("unknown thread calling: " + TOSTRING(tid) + " / class " + TOSTRING((unsigned long)bthread)); return; } Modified: trunk/source/main/physics/threading/BeamWorkerManager.h =================================================================== --- trunk/source/main/physics/threading/BeamWorkerManager.h 2012-02-04 14:00:06 UTC (rev 2446) +++ trunk/source/main/physics/threading/BeamWorkerManager.h 2012-02-04 15:38:52 UTC (rev 2447) @@ -33,7 +33,6 @@ { friend class BeamThread; friend class RoRSingleton<BeamWorkerManager>; - static const int MAX_THREADS = 256; protected: typedef struct workerData_t { @@ -46,10 +45,8 @@ typedef std::map <BeamThread*, workerData_t> threadMap; threadMap threads; int threadsSize; + int targetThreadSize; - void *classInstanceData[MAX_THREADS]; - int instanceSize; - int done_count; pthread_mutex_t api_mutex; pthread_mutex_t done_count_mutex; @@ -65,6 +62,7 @@ public: void _startWorkerLoop(); + void _checkRunThreads(); }; #endif //__BeamWorkerManager_H__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Try before you buy = See our experts in action! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-dev2 _______________________________________________ Rigsofrods-devel mailing list Rigsofrods-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rigsofrods-devel