diff --git a/stepmania/src/arch/Threads/Threads_Pthreads.cpp b/stepmania/src/arch/Threads/Threads_Pthreads.cpp index 5f08f5bfa5..f6a8f0ee2e 100644 --- a/stepmania/src/arch/Threads/Threads_Pthreads.cpp +++ b/stepmania/src/arch/Threads/Threads_Pthreads.cpp @@ -222,6 +222,7 @@ MutexImpl *MakeMutex( RageMutex *pParent ) return new MutexImpl_Pthreads( pParent ); } +#if 0 SemaImpl_Pthreads::SemaImpl_Pthreads( int iInitialValue ) { sem_init( &sem, 0, iInitialValue ); @@ -267,6 +268,61 @@ bool SemaImpl_Pthreads::TryWait() RageException::Throw( "TryWait: sem_trywait failed: %s", strerror(errno) ); return true; } +#else +/* Use conditions, to work around OSX "forgetting" to implement semaphores. */ +SemaImpl_Pthreads::SemaImpl_Pthreads( int iInitialValue ) +{ + int ret = pthread_cond_init( &m_Cond, NULL ); + ASSERT_M( ret == 0, ssprintf( "SemaImpl_Pthreads: pthread_cond_init: %s", strerror(errno)) ); + ret = pthread_mutex_init( &m_Mutex, NULL ); + ASSERT_M( ret == 0, ssprintf( "SemaImpl_Pthreads: pthread_mutex_init: %s", strerror(errno)) ); + + m_iValue = iInitialValue; +} + +SemaImpl_Pthreads::~SemaImpl_Pthreads() +{ + pthread_cond_destroy( &m_Cond ); + pthread_mutex_destroy( &m_Mutex ); +} + +void SemaImpl_Pthreads::Post() +{ + pthread_mutex_lock( &m_Mutex ); + ++m_iValue; + if( m_iValue == 1 ) + pthread_cond_signal( &m_Cond ); + pthread_mutex_unlock( &m_Mutex ); +} + +bool SemaImpl_Pthreads::Wait() +{ + pthread_mutex_lock( &m_Mutex ); + while( !m_iValue ) + pthread_cond_wait( &m_Cond, &m_Mutex ); + + --m_iValue; + pthread_mutex_unlock( &m_Mutex); + + return true; +} + +bool SemaImpl_Pthreads::TryWait() +{ + pthread_mutex_lock( &m_Mutex ); + if( !m_iValue ) + { + pthread_mutex_unlock( &m_Mutex); + return false; + } + + --m_iValue; + pthread_mutex_unlock( &m_Mutex); + + return true; +} + +#endif SemaImpl *MakeSemaphore( int iInitialValue ) { diff --git a/stepmania/src/arch/Threads/Threads_Pthreads.h b/stepmania/src/arch/Threads/Threads_Pthreads.h index 299f9aaf61..d17716abd7 100644 --- a/stepmania/src/arch/Threads/Threads_Pthreads.h +++ b/stepmania/src/arch/Threads/Threads_Pthreads.h @@ -53,6 +53,7 @@ private: pthread_mutex_t mutex; }; +#if 0 class SemaImpl_Pthreads: public SemaImpl { public: @@ -66,6 +67,24 @@ public: private: sem_t sem; }; +#else +class SemaImpl_Pthreads: public SemaImpl +{ +public: + SemaImpl_Pthreads( int iInitialValue ); + ~SemaImpl_Pthreads(); + int GetValue() const { return m_iValue; } + void Post(); + bool Wait(); + bool TryWait(); + +private: + pthread_cond_t m_Cond; + pthread_mutex_t m_Mutex; + unsigned m_iValue; +}; + +#endif #endif