Optimize epicsThreadOnce() routines.

Don't call epicsThreadGetIdSelf() unnecessarily, check for the value
EPICS_THREAD_ONCE_DONE first, since that's the most common state.
This commit is contained in:
Andrew Johnson
2010-05-14 17:26:54 -05:00
parent 6cd22d4efe
commit 6b64304570
4 changed files with 68 additions and 60 deletions
+16 -14
View File
@@ -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);
}
+16 -14
View File
@@ -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 );
}
+19 -17
View File
@@ -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");
}
+17 -15
View File
@@ -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);
}