From 6b6430457081d729c3885e259dada1a7af709f4e Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 14 May 2010 17:26:54 -0500 Subject: [PATCH] Optimize epicsThreadOnce() routines. Don't call epicsThreadGetIdSelf() unnecessarily, check for the value EPICS_THREAD_ONCE_DONE first, since that's the most common state. --- src/libCom/osi/os/RTEMS/osdThread.c | 30 +++++++++++----------- src/libCom/osi/os/WIN32/osdThread.c | 30 +++++++++++----------- src/libCom/osi/os/posix/osdThread.c | 36 ++++++++++++++------------- src/libCom/osi/os/vxWorks/osdThread.c | 32 +++++++++++++----------- 4 files changed, 68 insertions(+), 60 deletions(-) diff --git a/src/libCom/osi/os/RTEMS/osdThread.c b/src/libCom/osi/os/RTEMS/osdThread.c index 20bdffd3e..26f42587f 100644 --- a/src/libCom/osi/os/RTEMS/osdThread.c +++ b/src/libCom/osi/os/RTEMS/osdThread.c @@ -479,22 +479,24 @@ void epicsThreadOnce(epicsThreadOnceId *id, void(*func)(void *), void *arg) if (!initialized) epicsThreadInit(); epicsMutexMustLock(onceMutex); - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - epicsMutexUnlock(onceMutex); - func(arg); - epicsMutexMustLock(onceMutex); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - epicsMutexUnlock(onceMutex); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ + if (*id != EPICS_THREAD_ONCE_DONE) { + if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ + *id = epicsThreadGetIdSelf(); /* mark active */ epicsMutexUnlock(onceMutex); - epicsThreadSleep(epicsThreadSleepQuantum()); + func(arg); epicsMutexMustLock(onceMutex); - } + *id = EPICS_THREAD_ONCE_DONE; /* mark done */ + } else if (*id == epicsThreadGetIdSelf()) { + epicsMutexUnlock(onceMutex); + cantProceed("Recursive epicsThreadOnce() initialization\n"); + } else + while (*id != EPICS_THREAD_ONCE_DONE) { + /* Another thread is in the above func(arg) call. */ + epicsMutexUnlock(onceMutex); + epicsThreadSleep(epicsThreadSleepQuantum()); + epicsMutexMustLock(onceMutex); + } + } epicsMutexUnlock(onceMutex); } diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/libCom/osi/os/WIN32/osdThread.c index 887a31170..f12a894ba 100644 --- a/src/libCom/osi/os/WIN32/osdThread.c +++ b/src/libCom/osi/os/WIN32/osdThread.c @@ -1009,22 +1009,24 @@ epicsShareFunc void epicsShareAPI epicsThreadOnce ( EnterCriticalSection ( & pGbl->mutex ); - if ( *id == EPICS_THREAD_ONCE_INIT ) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - LeaveCriticalSection ( & pGbl->mutex ); - func ( arg ); - EnterCriticalSection ( & pGbl->mutex ); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if ( *id == epicsThreadGetIdSelf() ) { - LeaveCriticalSection ( & pGbl->mutex ); - cantProceed( "Recursive epicsThreadOnce() initialization\n" ); - } else - while ( *id != EPICS_THREAD_ONCE_DONE ) { - /* Another thread is in the above func(arg) call. */ + if ( *id != EPICS_THREAD_ONCE_DONE ) { + if ( *id == EPICS_THREAD_ONCE_INIT ) { /* first call */ + *id = epicsThreadGetIdSelf(); /* mark active */ LeaveCriticalSection ( & pGbl->mutex ); - epicsThreadSleep ( epicsThreadSleepQuantum() ); + func ( arg ); EnterCriticalSection ( & pGbl->mutex ); - } + *id = EPICS_THREAD_ONCE_DONE; /* mark done */ + } else if ( *id == epicsThreadGetIdSelf() ) { + LeaveCriticalSection ( & pGbl->mutex ); + cantProceed( "Recursive epicsThreadOnce() initialization\n" ); + } else + while ( *id != EPICS_THREAD_ONCE_DONE ) { + /* Another thread is in the above func(arg) call. */ + LeaveCriticalSection ( & pGbl->mutex ); + epicsThreadSleep ( epicsThreadSleepQuantum() ); + EnterCriticalSection ( & pGbl->mutex ); + } + } LeaveCriticalSection ( & pGbl->mutex ); } diff --git a/src/libCom/osi/os/posix/osdThread.c b/src/libCom/osi/os/posix/osdThread.c index 073bdb626..df0321ae2 100644 --- a/src/libCom/osi/os/posix/osdThread.c +++ b/src/libCom/osi/os/posix/osdThread.c @@ -335,27 +335,29 @@ epicsShareFunc void epicsShareAPI epicsThreadOnce(epicsThreadOnceId *id, void (* exit(-1); } - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - func(arg); - status = mutexLock(&onceLock); - checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ + if (*id != EPICS_THREAD_ONCE_DONE) { + if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ + *id = epicsThreadGetIdSelf(); /* mark active */ status = pthread_mutex_unlock(&onceLock); checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - epicsThreadSleep(epicsThreadSleepQuantum()); + func(arg); status = mutexLock(&onceLock); checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); - } + *id = EPICS_THREAD_ONCE_DONE; /* mark done */ + } else if (*id == epicsThreadGetIdSelf()) { + status = pthread_mutex_unlock(&onceLock); + checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); + cantProceed("Recursive epicsThreadOnce() initialization\n"); + } else + while (*id != EPICS_THREAD_ONCE_DONE) { + /* Another thread is in the above func(arg) call. */ + status = pthread_mutex_unlock(&onceLock); + checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); + epicsThreadSleep(epicsThreadSleepQuantum()); + status = mutexLock(&onceLock); + checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); + } + } status = pthread_mutex_unlock(&onceLock); checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadOnce"); } diff --git a/src/libCom/osi/os/vxWorks/osdThread.c b/src/libCom/osi/os/vxWorks/osdThread.c index acd1b40fe..064052ab8 100644 --- a/src/libCom/osi/os/vxWorks/osdThread.c +++ b/src/libCom/osi/os/vxWorks/osdThread.c @@ -125,24 +125,26 @@ void epicsThreadOnce(epicsThreadOnceId *id, void (*func)(void *), void *arg) epicsThreadInit(); result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); assert(result == OK); - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - semGive(epicsThreadOnceMutex); - func(arg); - result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); - assert(result == OK); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - semGive(epicsThreadOnceMutex); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ + if (*id != EPICS_THREAD_ONCE_DONE) { + if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ + *id = epicsThreadGetIdSelf(); /* mark active */ semGive(epicsThreadOnceMutex); - epicsThreadSleep(epicsThreadSleepQuantum()); + func(arg); result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); assert(result == OK); - } + *id = EPICS_THREAD_ONCE_DONE; /* mark done */ + } else if (*id == epicsThreadGetIdSelf()) { + semGive(epicsThreadOnceMutex); + cantProceed("Recursive epicsThreadOnce() initialization\n"); + } else + while (*id != EPICS_THREAD_ONCE_DONE) { + /* Another thread is in the above func(arg) call. */ + semGive(epicsThreadOnceMutex); + epicsThreadSleep(epicsThreadSleepQuantum()); + result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); + assert(result == OK); + } + } semGive(epicsThreadOnceMutex); }