From 2fd82ded2669bb43856b4c7e7dc873c76bbf04c0 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Tue, 1 Oct 2002 20:09:17 +0000 Subject: [PATCH] removed double test lock optimization --- src/libCom/osi/os/WIN32/osdMutex.c | 63 ++++++----------------------- src/libCom/osi/os/WIN32/osdTime.cpp | 44 ++++++++++---------- 2 files changed, 35 insertions(+), 72 deletions(-) diff --git a/src/libCom/osi/os/WIN32/osdMutex.c b/src/libCom/osi/os/WIN32/osdMutex.c index 75716a733..2a0b39ecb 100644 --- a/src/libCom/osi/os/WIN32/osdMutex.c +++ b/src/libCom/osi/os/WIN32/osdMutex.c @@ -33,8 +33,6 @@ typedef struct epicsWin32CS { CRITICAL_SECTION mutex; HANDLE unlockSignal; - DWORD threadId; - unsigned recursionCount; LONG waitingCount; } epicsWin32CS; @@ -75,8 +73,6 @@ epicsShareFunc epicsMutexId epicsShareAPI } else { InitializeCriticalSection ( &pSem->os.cs.mutex ); - pSem->os.cs.threadId = 0; - pSem->os.cs.recursionCount = 0u; pSem->os.cs.waitingCount = 0u; } } @@ -115,19 +111,10 @@ epicsShareFunc void epicsShareAPI epicsMutexUnlock ( epicsMutexId pSem ) { if ( thisIsNT ) { - //assert ( pSem->threadId == GetCurrentThreadId () ); - if ( pSem->os.cs.recursionCount == 1 ) { - pSem->os.cs.threadId = 0; - pSem->os.cs.recursionCount = 0; - LeaveCriticalSection ( &pSem->os.cs.mutex ); - if ( pSem->os.cs.waitingCount ) { - DWORD status = SetEvent ( pSem->os.cs.unlockSignal ); - assert ( status ); - } - } - else { - assert ( pSem->os.cs.recursionCount > 1u ); - pSem->os.cs.recursionCount--; + LeaveCriticalSection ( &pSem->os.cs.mutex ); + if ( pSem->os.cs.waitingCount ) { + DWORD status = SetEvent ( pSem->os.cs.unlockSignal ); + assert ( status ); } } else { @@ -143,19 +130,10 @@ epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLock ( epicsMutexId pSem ) { if ( thisIsNT ) { - DWORD thisThread = GetCurrentThreadId (); - if ( pSem->os.cs.threadId == thisThread ) { - assert ( pSem->os.cs.recursionCount < UINT_MAX ); - pSem->os.cs.recursionCount++; - } - else { - EnterCriticalSection ( &pSem->os.cs.mutex ); - pSem->os.cs.threadId = thisThread; - pSem->os.cs.recursionCount = 1u; - } + EnterCriticalSection ( &pSem->os.cs.mutex ); } else { - DWORD status = WaitForSingleObject ( pSem->os.mutex, INFINITE); + DWORD status = WaitForSingleObject ( pSem->os.mutex, INFINITE ); if ( status != WAIT_OBJECT_0 ) { return epicsMutexLockError; } @@ -172,15 +150,9 @@ epicsShareFunc epicsMutexLockStatus epicsShareAPI static const unsigned mSecPerSec = 1000u; if ( thisIsNT ) { - DWORD thisThread = GetCurrentThreadId (); DWORD begin = GetTickCount (); - if ( pSem->os.cs.threadId == thisThread ) { - assert ( pSem->os.cs.recursionCount < UINT_MAX ); - pSem->os.cs.recursionCount++; - return epicsMutexLockOK; - } - else if ( ! TryEnterCriticalSection ( &pSem->os.cs.mutex ) ) { + if ( ! TryEnterCriticalSection ( &pSem->os.cs.mutex ) ) { DWORD delay = 0; DWORD tmo; @@ -198,6 +170,7 @@ epicsShareFunc epicsMutexLockStatus epicsShareAPI } assert ( pSem->os.cs.waitingCount < 0x7FFFFFFF ); + // this causes a cache flush on MP systems InterlockedIncrement ( &pSem->os.cs.waitingCount ); while ( ! TryEnterCriticalSection ( &pSem->os.cs.mutex ) ) { @@ -215,17 +188,16 @@ epicsShareFunc epicsMutexLockStatus epicsShareAPI if ( delay >= tmo ) { assert ( pSem->os.cs.waitingCount > 0 ); + // this causes a cache flush on MP systems InterlockedDecrement ( &pSem->os.cs.waitingCount ); return epicsMutexLockTimeout; } } assert ( pSem->os.cs.waitingCount > 0 ); + // this causes a cache flush on MP systems InterlockedDecrement ( &pSem->os.cs.waitingCount ); } - - pSem->os.cs.threadId = thisThread; - pSem->os.cs.recursionCount = 1; } else { DWORD tmo; @@ -261,14 +233,7 @@ epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexTryLock ( epicsMutexId pSem ) { if ( thisIsNT ) { - DWORD thisThread = GetCurrentThreadId (); - if ( pSem->os.cs.threadId == thisThread ) { - assert ( pSem->os.cs.recursionCount < UINT_MAX ); - pSem->os.cs.recursionCount++; - } - else if ( TryEnterCriticalSection ( &pSem->os.cs.mutex ) ) { - pSem->os.cs.threadId = thisThread; - pSem->os.cs.recursionCount = 1; + if ( TryEnterCriticalSection ( &pSem->os.cs.mutex ) ) { return epicsMutexLockOK; } else { @@ -295,10 +260,8 @@ epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexTryLock ( epicsMutex epicsShareFunc void epicsShareAPI epicsMutexShow ( epicsMutexId pSem, unsigned level ) { if ( thisIsNT ) { - printf ("epicsMutex: recursion=%u, waiting=%d, threadid=%d %s\n", - pSem->os.cs.recursionCount, pSem->os.cs.waitingCount, pSem->os.cs.threadId, - pSem->os.cs.threadId==GetCurrentThreadId()? - "owned by this thread":"" ); + printf ("epicsMutex: win32 critical section at %p\n", + (void * ) & pSem->os.cs.mutex ); } else { printf ( "epicsMutex: win32 mutex at %p\n", diff --git a/src/libCom/osi/os/WIN32/osdTime.cpp b/src/libCom/osi/os/WIN32/osdTime.cpp index a2649073f..0b7da0cb7 100644 --- a/src/libCom/osi/os/WIN32/osdTime.cpp +++ b/src/libCom/osi/os/WIN32/osdTime.cpp @@ -69,7 +69,6 @@ private: }; static currentTime * pCurrentTime = 0; -static bool osdTimeInitSuccess = false; static epicsThreadOnceId osdTimeOnceFlag = EPICS_THREAD_ONCE_INIT; static const LONGLONG FILE_TIME_TICKS_PER_SEC = 10000000; static const LONGLONG EPICS_TIME_TICKS_PER_SEC = 1000000000; @@ -80,25 +79,29 @@ static const LONGLONG ET_TICKS_PER_FT_TICK = // static void osdTimeInit ( void * ) { - pCurrentTime = new currentTime (); + static bool osdTimeInitSuccess = false; - // set here to avoid recursion problems - osdTimeInitSuccess = true; + // avoid recursion problems + if ( ! osdTimeInitSuccess ) { + osdTimeInitSuccess = true; - pCurrentTime->startPLL (); + pCurrentTime = new currentTime (); - // self test FILETIME conversion only if - // its a debug build -# if defined ( _DEBUG ) - { - epicsTime ts0 = epicsTime::getCurrent (); - FILETIME ft = ts0; - epicsTime ts1 = ft; - double diff = fabs ( ts0 - ts1 ); - // we expect to loose 100 nS of precision when moving to and from win32 filetime - assert ( diff <= 100e-9 ); + pCurrentTime->startPLL (); + + // self test FILETIME conversion only if + // its a debug build +# if defined ( _DEBUG ) + { + epicsTime ts0 = epicsTime::getCurrent (); + FILETIME ft = ts0; + epicsTime ts1 = ft; + double diff = fabs ( ts0 - ts1 ); + // we expect to loose 100 nS of precision when moving to and from win32 filetime + assert ( diff <= 100e-9 ); + } +# endif } -# endif } // @@ -106,12 +109,9 @@ static void osdTimeInit ( void * ) // extern "C" epicsShareFunc int epicsShareAPI epicsTimeGetCurrent ( epicsTimeStamp *pDest ) { - // double test avoids recursion problems - if ( ! osdTimeInitSuccess ) { - epicsThreadOnce ( & osdTimeOnceFlag, osdTimeInit, 0 ); - if ( ! ( osdTimeInitSuccess && pCurrentTime ) ) { - return epicsTimeERROR; - } + epicsThreadOnce ( & osdTimeOnceFlag, osdTimeInit, 0 ); + if ( ! pCurrentTime ) { + return epicsTimeERROR; } pCurrentTime->getCurrentTime ( *pDest );