diff --git a/Sources/Plasma/CoreLib/hsThread.h b/Sources/Plasma/CoreLib/hsThread.h index d45625f6..02745ed6 100644 --- a/Sources/Plasma/CoreLib/hsThread.h +++ b/Sources/Plasma/CoreLib/hsThread.h @@ -44,6 +44,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "HeadSpin.h" #include +#include typedef uint32_t hsMilliseconds; @@ -117,49 +118,41 @@ class hsSemaphore { #else pthread_mutex_t fPMutex; pthread_cond_t fPCond; - int32_t fCounter; + int32_t fCounter; #endif #endif public: - hsSemaphore(int initialValue=0, const char* name=nil); + hsSemaphore(int initialValue=0, const char* name=nullptr); ~hsSemaphore(); #ifdef HS_BUILD_FOR_WIN32 HANDLE GetHandle() const { return fSemaH; } #endif - bool TryWait(); - bool Wait(hsMilliseconds timeToWait = kPosInfinity32); - void Signal(); + bool Wait(hsMilliseconds timeToWait = kPosInfinity32); + void Signal(); }; ////////////////////////////////////////////////////////////////////////////// class hsEvent { -#if HS_BUILD_FOR_UNIX -#ifndef PSEUDO_EVENT - pthread_mutex_t fMutex; - pthread_cond_t fCond; - bool fTriggered; -#else - enum { kRead, kWrite }; - int fFds[2]; - std::mutex fWaitLock; - std::mutex fSignalLock; -#endif // PSEUDO_EVENT -#elif HS_BUILD_FOR_WIN32 - HANDLE fEvent; -#endif + std::mutex fMutex; + std::condition_variable fCondition; + public: - hsEvent(); - ~hsEvent(); + hsEvent() { } -#ifdef HS_BUILD_FOR_WIN32 - HANDLE GetHandle() const { return fEvent; } -#endif + inline void Wait() + { + std::unique_lock lock(fMutex); + fCondition.wait(lock); + } - bool Wait(hsMilliseconds timeToWait = kPosInfinity32); - void Signal(); + inline void Signal() + { + std::unique_lock lock(fMutex); + fCondition.notify_one(); + } }; ////////////////////////////////////////////////////////////////////////////// diff --git a/Sources/Plasma/CoreLib/hsThread_Unix.cpp b/Sources/Plasma/CoreLib/hsThread_Unix.cpp index c6eb1a09..a6b3e72d 100644 --- a/Sources/Plasma/CoreLib/hsThread_Unix.cpp +++ b/Sources/Plasma/CoreLib/hsThread_Unix.cpp @@ -242,21 +242,6 @@ hsSemaphore::~hsSemaphore() #endif } -bool hsSemaphore::TryWait() -{ -#ifdef USE_SEMA - int status = ::sem_trywait(fPSema); - if (status != 0) { - return errno != EAGAIN; - } - return true; -#else - int status = ::pthread_mutex_trylock(&fPMutex); - hsThrowIfOSErr(status); - return status==EBUSY ? false : true; -#endif -} - bool hsSemaphore::Wait(hsMilliseconds timeToWait) { #ifdef USE_SEMA // SHOULDN'T THIS USE timeToWait??!?!? -rje @@ -328,180 +313,6 @@ void hsSemaphore::Signal() #endif } - -/////////////////////////////////////////////////////////////// - -#ifndef PSEUDO_EVENT - -hsEvent::hsEvent() : fTriggered(false) -{ -#ifdef EVENT_LOGGING - InitEventLoggingFile(); -#endif - int status = ::pthread_mutex_init(&fMutex, nil); - hsAssert(status == 0, "hsEvent Mutex Init"); - hsThrowIfOSErr(status); - - // fCond = PTHREAD_COND_INITIALIZER; - status = ::pthread_cond_init(&fCond, nil); - hsAssert(status == 0, "hsEvent Cond Init"); - hsThrowIfOSErr(status); -} - -hsEvent::~hsEvent() -{ - int status = ::pthread_cond_destroy(&fCond); - hsAssert(status == 0, "hsEvent Cond De-Init"); - hsThrowIfOSErr(status); - - status = ::pthread_mutex_destroy(&fMutex); - hsAssert(status == 0, "hsEvent Mutex De-Init"); - hsThrowIfOSErr(status); -} - -bool hsEvent::Wait(hsMilliseconds timeToWait) -{ - bool retVal = true; - int status = ::pthread_mutex_lock(&fMutex); - hsAssert(status == 0, "hsEvent Mutex Lock"); - hsThrowIfOSErr(status); - -#ifdef EVENT_LOGGING - fprintf(gEventLoggingFile,"Event: %p - In Wait (pre trig check), Triggered: %d, t=%f\n",this,fTriggered,hsTimer::GetSeconds()); -#endif - - if ( !fTriggered ) - { - if (timeToWait == kPosInfinity32) - { - status = ::pthread_cond_wait(&fCond, &fMutex); - hsAssert(status == 0, "hsEvent Cond Wait"); - hsThrowIfOSErr(status); - } - else - { timespec spec; - int result; - - result = ::clock_gettime(CLOCK_REALTIME, &spec); - hsThrowIfFalse(result == 0); - - spec.tv_sec += timeToWait / 1000; - spec.tv_nsec += (timeToWait % 1000) * 1000 * 1000; - while (spec.tv_nsec >= 1000 * 1000 * 1000) - { spec.tv_sec += 1; - spec.tv_nsec -= 1000 * 1000 * 1000; - } - - status = ::pthread_cond_timedwait(&fCond, &fMutex, &spec); - - if (status == ETIMEDOUT) - { - // It's a conditional paired with a variable! - // Pthread docs all use a variable in conjunction with the conditional - retVal = fTriggered; - status = 0; -#ifdef EVENT_LOGGING - fprintf(gEventLoggingFile,"Event: %p - In Wait (wait timed out), Triggered: %d, t=%f\n",this,fTriggered,hsTimer::GetSeconds()); -#endif - } - else - { -#ifdef EVENT_LOGGING - fprintf(gEventLoggingFile,"Event: %p - In Wait (wait recvd signal), Triggered: %d, t=%f\n",this,fTriggered,hsTimer::GetSeconds()); -#endif - } - - hsAssert(status == 0, "hsEvent Cond Wait"); - hsThrowIfOSErr(status); - } - } - else - { -#ifdef EVENT_LOGGING - fprintf(gEventLoggingFile,"Event: %p - In Wait (post triggerd), Triggered: %d, t=%f\n",this,fTriggered,hsTimer::GetSeconds()); -#endif - } - - fTriggered = false; - status = ::pthread_mutex_unlock(&fMutex); - hsAssert(status == 0, "hsEvent Mutex Unlock"); - hsThrowIfOSErr(status); - return retVal; -} - -void hsEvent::Signal() -{ - int status = ::pthread_mutex_lock(&fMutex); - hsAssert(status == 0, "hsEvent Mutex Lock"); - hsThrowIfOSErr(status); -#ifdef EVENT_LOGGING - fprintf(gEventLoggingFile,"Event: %p - In Signal, Triggered: %d, t=%f\n",this,fTriggered,hsTimer::GetSeconds()); -#endif - fTriggered = true; - status = ::pthread_cond_broadcast(&fCond); - hsAssert(status == 0, "hsEvent Cond Broadcast"); - hsThrowIfOSErr(status); - status = ::pthread_mutex_unlock(&fMutex); - hsAssert(status == 0, "hsEvent Mutex Unlock"); - hsThrowIfOSErr(status); -} - -#else - -hsEvent::hsEvent() -{ - pipe( fFds ); -} - -hsEvent::~hsEvent() -{ - close( fFds[kRead] ); - close( fFds[kWrite] ); -} - -bool hsEvent::Wait( hsMilliseconds timeToWait ) -{ - std::lock_guard lock(fWaitLock); - - fd_set fdset; - FD_ZERO( &fdset ); - FD_SET( fFds[kRead], &fdset ); - - int ans; - if( timeToWait==kPosInfinity32 ) - { - ans = select( fFds[kRead]+1, &fdset, nil, nil, nil ); - } - else - { - struct timeval tv; - tv.tv_sec = timeToWait / 1000; - tv.tv_usec = ( timeToWait % 1000 ) * 1000; - - ans = select( fFds[kRead]+1, &fdset, nil, nil, &tv ); - } - - bool signaled = false; - - if ( ans>0 ) - { - char buf[2]; - int n = read( fFds[kRead], buf, 1 ); - signaled = ( n==1 ); - } - - return signaled; -} - -void hsEvent::Signal() -{ - std::lock_guard lock(fSignalLock); - write( fFds[kWrite], "*", 1 ); -} - - -#endif - void hsSleep::Sleep(uint32_t millis) { uint32_t secs = millis / 1000; diff --git a/Sources/Plasma/CoreLib/hsThread_Win.cpp b/Sources/Plasma/CoreLib/hsThread_Win.cpp index 90f7d617..a4717713 100644 --- a/Sources/Plasma/CoreLib/hsThread_Win.cpp +++ b/Sources/Plasma/CoreLib/hsThread_Win.cpp @@ -147,13 +147,6 @@ hsSemaphore::~hsSemaphore() ::CloseHandle(fSemaH); } -bool hsSemaphore::TryWait() -{ - DWORD result = ::WaitForSingleObject(fSemaH, 0); - hsAssert(result != WAIT_ABANDONED, "hsSemaphore -> Abandoned Semaphore"); - return result == WAIT_OBJECT_0; -} - bool hsSemaphore::Wait(hsMilliseconds timeToWait) { if (timeToWait == kPosInfinity32) @@ -176,43 +169,6 @@ void hsSemaphore::Signal() /////////////////////////////////////////////////////////////// -hsEvent::hsEvent() -{ - fEvent = ::CreateEvent(nil,true,false,nil); - if (fEvent == nil) - throw hsOSException(-1); -} - -hsEvent::~hsEvent() -{ - ::CloseHandle(fEvent); -} - -bool hsEvent::Wait(hsMilliseconds timeToWait) -{ - if (timeToWait == kPosInfinity32) - timeToWait = INFINITE; - - DWORD result =::WaitForSingleObject(fEvent, timeToWait); - - if (result == WAIT_OBJECT_0) - { - ::ResetEvent(fEvent); - return true; - } - else - { hsThrowIfFalse(result == WAIT_TIMEOUT); - return false; - } -} - -void hsEvent::Signal() -{ - ::SetEvent(fEvent); -} - -/////////////////////////////////////////////////////////////// - void hsSleep::Sleep(uint32_t millis) { ::Sleep(millis);