From e4b251d90df06d1dcd1a1cdda5ff47c3535a98a1 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 15 Jan 2008 15:05:35 -0500 Subject: [svn-r14419] Description: Streamline threadsafety code to be simpler and reduce latency of holding locks. Tested on: Mac OS X/32 10.5.1 (amazon) w/threadsafe --- src/H5TS.c | 54 +++++++++++++++++++++--------------------------------- src/H5TSprivate.h | 1 - 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/src/H5TS.c b/src/H5TS.c index e311c29..6d8ff64 100644 --- a/src/H5TS.c +++ b/src/H5TS.c @@ -96,10 +96,6 @@ H5TS_first_thread_init(void) { H5_g.H5_libinit_g = FALSE; - /* set the owner objects to initial values */ - H5_g.init_lock.owner_thread = pthread_self(); - H5_g.init_lock.owner_valid = FALSE; - /* initialize global API mutex lock */ pthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL); pthread_cond_init(&H5_g.init_lock.cond_var, NULL); @@ -150,26 +146,17 @@ H5TS_mutex_lock(H5TS_mutex_t *mutex) if (ret_value) return ret_value; - if (mutex->owner_valid && pthread_equal(pthread_self(), mutex->owner_thread)) { + if(mutex->lock_count && pthread_equal(pthread_self(), mutex->owner_thread)) { /* already owned by self - increment count */ mutex->lock_count++; - } else if (!mutex->owner_valid) { - /* no one else has locked it - set owner and grab lock */ + } else { + /* if owned by other thread, wait for condition signal */ + while(mutex->lock_count) + pthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock); + + /* After we've received the signal, take ownership of the mutex */ mutex->owner_thread = pthread_self(); - mutex->owner_valid = TRUE; mutex->lock_count = 1; - } else { - /* if already locked by someone else */ - for (;;) { - pthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock); - - if (!mutex->owner_valid) { - mutex->owner_thread = pthread_self(); - mutex->owner_valid = TRUE; - mutex->lock_count = 1; - break; - } - } } return pthread_mutex_unlock(&mutex->atomic_lock); @@ -204,26 +191,27 @@ H5TS_mutex_lock(H5TS_mutex_t *mutex) herr_t H5TS_mutex_unlock(H5TS_mutex_t *mutex) { - herr_t ret_value; + unsigned lock_count; /* Mutex's lock count */ + herr_t ret_value; /* Return value */ ret_value = pthread_mutex_lock(&mutex->atomic_lock); - if (ret_value) - return ret_value; + if(ret_value) + return ret_value; - mutex->lock_count--; + lock_count = --mutex->lock_count; - if (mutex->lock_count == 0) { - mutex->owner_valid = FALSE; - ret_value = pthread_cond_signal(&mutex->cond_var); + ret_value = pthread_mutex_unlock(&mutex->atomic_lock); - if (ret_value) { - pthread_mutex_unlock(&mutex->atomic_lock); - return ret_value; - } - } + if(lock_count == 0) { + int err; - return pthread_mutex_unlock(&mutex->atomic_lock); + err = pthread_cond_signal(&mutex->cond_var); + if(err != 0) + ret_value = err; + } /* end if */ + + return ret_value; } /*-------------------------------------------------------------------------- diff --git a/src/H5TSprivate.h b/src/H5TSprivate.h index f817120..0d0b620 100644 --- a/src/H5TSprivate.h +++ b/src/H5TSprivate.h @@ -37,7 +37,6 @@ typedef struct H5TS_mutex_struct { pthread_t owner_thread; /* current lock owner */ - unsigned owner_valid; /* if current lock owner info is valid */ pthread_mutex_t atomic_lock; /* lock for atomicity of new mechanism */ pthread_cond_t cond_var; /* condition variable */ unsigned int lock_count; -- cgit v0.12