From: <axl...@us...> - 2009-05-14 02:03:30
|
Revision: 240 http://hgengine.svn.sourceforge.net/hgengine/?rev=240&view=rev Author: axlecrusher Date: 2009-05-14 01:47:52 +0000 (Thu, 14 May 2009) Log Message: ----------- recursive lock semaphore??? Modified Paths: -------------- Mercury2/src/MSemaphore.cpp Mercury2/src/MSemaphore.h Mercury2/src/MercuryThreads.cpp Modified: Mercury2/src/MSemaphore.cpp =================================================================== --- Mercury2/src/MSemaphore.cpp 2009-05-13 02:26:18 UTC (rev 239) +++ Mercury2/src/MSemaphore.cpp 2009-05-14 01:47:52 UTC (rev 240) @@ -1,4 +1,5 @@ #include <MSemaphore.h> +#include <MercuryThreads.h> MSemaphore::MSemaphore() :m_counter(0) @@ -6,10 +7,9 @@ } #ifndef WIN32 -unsigned long MSemaphore::Read() -{ - return __sync_or_and_fetch(&m_counter, 0); -} +#define SYNC_OR_AND_FETCH(d,v) __sync_or_and_fetch(d,v) +#define COMPARE_AND_SWAP(d,o,n) __sync_val_compare_and_swap(d,o,n) +#define SYNC_AND_AND_FETCH(d,v) __sync_and_and_fetch(d,v) unsigned long MSemaphore::ReadAndClear() { @@ -28,7 +28,7 @@ void MSemaphore::WaitAndSet(unsigned long value, unsigned long newVal) { - while ( !__sync_bool_compare_and_swap(&m_counter, value, newVal) ); + while( (unsigned long)__sync_val_compare_and_swap(&m_counter, value, newVal) != value ); } #else @@ -70,11 +70,8 @@ return Old; } -unsigned long MSemaphore::Read() -{ - return OrAndFetch(&m_counter, 0); -// return MyInterlockedOr(&m_counter, 0); -} +#define SYNC_OR_AND_FETCH(d,v) OrAndFetch(d,v) +#define COMPARE_AND_SWAP(d,o,n) InterlockedCompareExchange(d, n, o) unsigned long MSemaphore::ReadAndClear() { @@ -93,21 +90,48 @@ void MSemaphore::WaitAndSet(unsigned long value, unsigned long newVal) { - InterlockedCompareExchange(&m_counter, newVal, value); -// while ( !__sync_bool_compare_and_swap(&m_counter, value, newVal) ); + while ( InterlockedCompareExchange(Destination, newVal, value) != value ); } #endif +unsigned long MSemaphore::Read() +{ + return SYNC_OR_AND_FETCH(&m_counter, 0); +} + +void MSemaphore::Wait() +{ + uint32_t thread = MercuryThread::Current(); + if ( COMPARE_AND_SWAP(&m_thread, 0, thread) == thread) //recursive lock + { + ++m_lockCount; + return; + } + WaitAndSet(0,1); + ++m_lockCount; +} + +void MSemaphore::UnLock() +{ + uint32_t thread = MercuryThread::Current(); + if ( SYNC_OR_AND_FETCH(&m_thread, 0) == thread) //unlock given from correct thread + { + --m_lockCount; + if (m_lockCount == 0) WaitAndSet(1,0); + SYNC_AND_AND_FETCH(&m_thread, 0 ); + } +} + MSemaphoreLock::MSemaphoreLock(MSemaphore* s) :m_s(s) { - m_s->WaitAndSet(0,1); + m_s->Wait(); } MSemaphoreLock::~MSemaphoreLock() { - m_s->WaitAndSet(1,0); + m_s->UnLock(); } MSemaphoreIncOnDestroy::MSemaphoreIncOnDestroy(MSemaphore* s) Modified: Mercury2/src/MSemaphore.h =================================================================== --- Mercury2/src/MSemaphore.h 2009-05-13 02:26:18 UTC (rev 239) +++ Mercury2/src/MSemaphore.h 2009-05-14 01:47:52 UTC (rev 240) @@ -17,13 +17,19 @@ unsigned long Decrement(); unsigned long Increment(); void WaitAndSet(unsigned long value, unsigned long newVal); - + + void Wait(); + void UnLock(); private: + //what exactly needs to be volatile + uint32_t m_lockCount; #ifndef WIN32 - int32_t m_counter; + uint32_t m_counter; + uint32_t m_thread; #else - volatile LONG m_counter; + volatile LONG m_counter; //align to 32bit boundary + volatile LONG m_thread; #endif }; Modified: Mercury2/src/MercuryThreads.cpp =================================================================== --- Mercury2/src/MercuryThreads.cpp 2009-05-13 02:26:18 UTC (rev 239) +++ Mercury2/src/MercuryThreads.cpp 2009-05-14 01:47:52 UTC (rev 240) @@ -119,6 +119,12 @@ } } +unsigned long MercuryThread::Current() +{ + return pthread_self(); +} + + //Mutex functions MercuryMutex::MercuryMutex( ) :m_name("(null)") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |