From: <ka...@us...> - 2011-05-31 06:24:55
|
Revision: 5594 http://paintown.svn.sourceforge.net/paintown/?rev=5594&view=rev Author: kazzmir Date: 2011-05-31 06:24:48 +0000 (Tue, 31 May 2011) Log Message: ----------- use condition variables in futures Modified Paths: -------------- trunk/src/util/thread.cpp trunk/src/util/thread.h Modified: trunk/src/util/thread.cpp =================================================================== --- trunk/src/util/thread.cpp 2011-05-31 05:17:50 UTC (rev 5593) +++ trunk/src/util/thread.cpp 2011-05-31 06:24:48 UTC (rev 5594) @@ -6,6 +6,7 @@ LockObject::LockObject(){ initializeLock(&lock); + initializeCondition(&condition); } void LockObject::acquire() const { @@ -17,8 +18,23 @@ releaseLock((Lock*) &lock); } +void LockObject::wait(volatile bool & check) const { + int ok = 0; + /* only wait if check is false. if so then keep waiting until the condition + * was successful as well. + */ + while (!check || ok != 0){ + ok = conditionWait((Condition*) &condition, (Lock*) &lock); + } +} + +void LockObject::signal() const { + conditionSignal((Condition*) &condition); +} + LockObject::~LockObject(){ destroyLock(&lock); + destroyCondition(&condition); } ScopedLock::ScopedLock(const LockObject & lock): @@ -52,7 +68,23 @@ void destroyLock(Lock * lock){ SDL_DestroyMutex(*lock); } + +void initializeCondition(Condition * condition){ + *condition = SDL_CreateCond(); +} +void destroyCondition(Condition * condition){ + SDL_DestroyCond(*condition); +} + +int conditionWait(Condition * condition, Lock * lock){ + return SDL_CondWait(*condition, *lock); +} + +int conditionSignal(Condition * condition){ + return SDL_CondBroadcast(*condition); +} + /* void initializeSemaphore(Semaphore * semaphore, unsigned int value){ *semaphore = SDL_CreateSemaphore(value); @@ -103,6 +135,24 @@ return 0; } +void initializeCondition(Condition * condition){ + *condition = al_create_cond(); +} + +void destroyCondition(Condition * condition){ + al_destroy_cond(*condition); +} + +int conditionWait(Condition * condition, Lock * lock){ + al_wait_cond(*condition, *lock); + return 0; +} + +int conditionSignal(Condition * condition){ + al_broadcast_cond(*condition); + return 0; +} + struct AllegroThreadStuff{ AllegroThreadStuff(const ThreadFunction & function, void * arg): function(function), @@ -115,7 +165,10 @@ static void * allegro_start_thread(ALLEGRO_THREAD * self, void * _stuff){ AllegroThreadStuff * stuff = (AllegroThreadStuff*) _stuff; - return stuff->function(stuff->arg); + ThreadFunction function = stuff->function; + void * arg = stuff->arg; + delete stuff; + return function(arg); } bool createThread(Id * thread, void * attributes, ThreadFunction function, void * arg){ @@ -125,6 +178,7 @@ al_start_thread(*thread); return true; } else { + delete stuff; return false; } } @@ -156,6 +210,22 @@ return pthread_mutex_unlock(lock); } +void initializeCondition(Condition * condition){ + pthread_cond_init(condition, NULL); +} + +void destroyCondition(Condition * condition){ + pthread_cond_destroy(condition); +} + +int conditionWait(Condition * condition, Lock * lock){ + return pthread_cond_wait(condition, lock); +} + +int conditionSignal(Condition * condition){ + return pthread_cond_broadcast(condition); +} + #if 0 void initializeSemaphore(Semaphore * semaphore, unsigned int value){ sem_init(semaphore, 0, value); Modified: trunk/src/util/thread.h =================================================================== --- trunk/src/util/thread.h 2011-05-31 05:17:50 UTC (rev 5593) +++ trunk/src/util/thread.h 2011-05-31 06:24:48 UTC (rev 5594) @@ -15,6 +15,7 @@ #include "load_exception.h" #include "token_exception.h" #include "mugen/exception.h" +#include "funcs.h" #include "debug.h" namespace Util{ @@ -25,15 +26,18 @@ typedef SDL_mutex* Lock; typedef SDL_Thread* Id; typedef int (*ThreadFunction)(void*); + typedef SDL_cond* Condition; // typedef SDL_semaphore* Semaphore; #elif USE_ALLEGRO5 typedef ALLEGRO_MUTEX* Lock; typedef ALLEGRO_THREAD* Id; typedef void * (*ThreadFunction)(void*); + typedef ALLEGRO_COND* Condition; // typedef SDL_semaphore* Semaphore; #else typedef pthread_mutex_t Lock; typedef pthread_t Id; + typedef pthread_cond_t Condition; // typedef sem_t Semaphore; typedef void * (*ThreadFunction)(void*); #endif @@ -42,6 +46,11 @@ bool isUninitialized(Id thread); void initializeLock(Lock * lock); + void initializeCondition(Condition * condition); + void destroyCondition(Condition * condition); + int conditionWait(Condition * condition, Lock * lock); + int conditionSignal(Condition * condition); + /* void initializeSemaphore(Semaphore * semaphore, unsigned int value); void destroySemaphore(Semaphore * semaphore); @@ -64,9 +73,13 @@ void acquire() const; void release() const; + void wait(volatile bool & check) const; + void signal() const; + virtual ~LockObject(); Lock lock; + Condition condition; }; /* acquires/releases the lock in RAII fashion */ @@ -151,6 +164,7 @@ Future(): thing(0), thread(Thread::uninitializedValue), + done(false), exception(NULL){ /* future will increase the count */ // Thread::initializeSemaphore(&future, 0); @@ -169,6 +183,7 @@ X out; Exception::Base * failed = NULL; future.acquire(); + future.wait(done); // Thread::semaphoreDecrease(&future); if (exception != NULL){ failed = exception; @@ -192,9 +207,13 @@ } protected: + bool isDone(){ + Thread::ScopedLock scoped(future); + return done; + } + static void * runit(void * arg){ Future<X> * me = (Future<X>*) arg; - me->future.acquire(); try{ me->compute(); } catch (const LoadException & load){ @@ -206,6 +225,9 @@ } catch (const Exception::Base & base){ me->exception = new Exception::Base(base); } + me->future.acquire(); + me->done = true; + me->future.signal(); me->future.release(); // Thread::semaphoreIncrease(&me->future); return NULL; @@ -215,12 +237,12 @@ this->thing = x; } - virtual void compute() = 0; X thing; Thread::Id thread; Thread::LockObject future; + volatile bool done; /* if any exceptions occur, throw them from `get' */ Exception::Base * exception; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |