From d894ed6d0dd5e750566d783f399213c84b40345e Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 19 May 2000 09:51:50 -0500 Subject: [svn-r2276] Modifed thread-safety code to more closely align with rest of HDF5 coding standards. --- src/H5.c | 25 +++---- src/H5E.c | 6 +- src/H5TS.c | 198 +++++++++++++++++++++++++++++++----------------------- src/H5TSprivate.h | 54 +++++++++++++++ src/H5private.h | 35 +++------- src/Makefile.in | 4 +- 6 files changed, 191 insertions(+), 131 deletions(-) create mode 100644 src/H5TSprivate.h diff --git a/src/H5.c b/src/H5.c index ee0da0c..40d1573 100644 --- a/src/H5.c +++ b/src/H5.c @@ -43,14 +43,9 @@ FILE *fdopen(int fd, const char *mode); /* statically initialize block for pthread_once call used in initializing */ /* the first global mutex */ #ifdef H5_HAVE_THREADSAFE -pthread_once_t H5_first_init_g = PTHREAD_ONCE_INIT; -pthread_key_t H5_errstk_key_g; -pthread_key_t H5_cancel_key_g; -hbool_t H5_allow_concurrent_g = FALSE; /* concurrent APIs override this */ - H5_api_t H5_g; #else -hbool_t H5_libinit_g = FALSE; +hbool_t H5_libinit_g = FALSE; #endif hbool_t dont_atexit_g = FALSE; @@ -164,9 +159,9 @@ H5_term_library(void) #ifdef H5_HAVE_THREADSAFE /* explicit locking of the API */ - pthread_once(&H5_first_init_g, H5_first_thread_init); + pthread_once(&H5TS_first_init_g, H5TS_first_thread_init); - H5_mutex_lock(&H5_g.init_lock); + H5TS_mutex_lock(&H5_g.init_lock); if (!H5_g.H5_libinit_g) return; #else @@ -217,7 +212,7 @@ H5_term_library(void) #ifdef H5_HAVE_THREADSAFE H5_g.H5_libinit_g = FALSE; - H5_mutex_unlock(&H5_g.init_lock); + H5TS_mutex_unlock(&H5_g.init_lock); #else H5_libinit_g = FALSE; #endif @@ -256,16 +251,16 @@ H5dont_atexit(void) /* locking code explicitly since FUNC_ENTER is not called */ #ifdef H5_HAVE_THREADSAFE - pthread_once(&H5_first_init_g, H5_first_thread_init); + pthread_once(&H5TS_first_init_g, H5TS_first_thread_init); - H5_mutex_lock(&H5_g.init_lock); + H5TS_mutex_lock(&H5_g.init_lock); #endif H5_trace(FALSE, "H5dont_atexit", ""); if (dont_atexit_g) return FAIL; dont_atexit_g = TRUE; H5_trace(TRUE, NULL, "e", SUCCEED); #ifdef H5_HAVE_THREADSAFE - H5_mutex_unlock(&H5_g.init_lock); + H5TS_mutex_unlock(&H5_g.init_lock); #endif return(SUCCEED); } @@ -521,13 +516,13 @@ H5close (void) */ /* Explicitly lock the call since FUNC_ENTER is not called */ #ifdef H5_HAVE_THREADSAFE - pthread_once(&H5_first_init_g, H5_first_thread_init); + pthread_once(&H5TS_first_init_g, H5TS_first_thread_init); - H5_mutex_lock(&H5_g.init_lock); + H5TS_mutex_lock(&H5_g.init_lock); #endif H5_term_library(); #ifdef H5_HAVE_THREADSAFE - H5_mutex_unlock(&H5_g.init_lock); + H5TS_mutex_unlock(&H5_g.init_lock); #endif return SUCCEED; } diff --git a/src/H5E.c b/src/H5E.c index cc7b482..2d216b2 100644 --- a/src/H5E.c +++ b/src/H5E.c @@ -197,12 +197,12 @@ void *H5E_auto_data_g = NULL; H5E_t *H5E_get_stack() { H5E_t *estack; - if (estack = pthread_getspecific(H5_errstk_key_g)) { + if ((estack = pthread_getspecific(H5TS_errstk_key_g))!=NULL) { return estack; } else { /* no associated value with current thread - create one */ estack = (H5E_t *)malloc(sizeof(H5E_t)); - pthread_setspecific(H5_errstk_key_g, (void *)estack); + pthread_setspecific(H5TS_errstk_key_g, (void *)estack); return estack; } } @@ -359,7 +359,7 @@ H5Eprint(FILE *stream) if (!stream) stream = stderr; #ifdef H5_HAVE_THREADSAFE fprintf (stream, "HDF5-DIAG: Error detected in thread %d." - ,pthread_self()); + ,(int)pthread_self()); #else fprintf (stream, "HDF5-DIAG: Error detected in thread 0."); #endif diff --git a/src/H5TS.c b/src/H5TS.c index e7317bc..37b7244 100644 --- a/src/H5TS.c +++ b/src/H5TS.c @@ -22,11 +22,30 @@ static char RcsId[] = "@(#)$Revision$"; #ifdef H5_HAVE_THREADSAFE +/* Module specific data structures */ + +/* cancelability structure */ +typedef struct H5TS_cancel_struct { + int previous_state; + unsigned int cancel_count; +} H5TS_cancel_t; + +/* Global variable definitions */ +pthread_once_t H5TS_first_init_g = PTHREAD_ONCE_INIT; +pthread_key_t H5TS_errstk_key_g; +pthread_key_t H5TS_cancel_key_g; +hbool_t H5TS_allow_concurrent_g = FALSE; /* concurrent APIs override this */ + +/* Local function definitions */ +#ifdef NOT_USED +static void H5TS_mutex_init(H5TS_mutex_t *mutex); +#endif /* NOT_USED */ + /*-------------------------------------------------------------------------- * NAME - * H5_first_thread_init + * H5TS_first_thread_init * USAGE - * H5_first_thread_init() + * H5TS_first_thread_init() * * RETURNS * @@ -42,26 +61,29 @@ static char RcsId[] = "@(#)$Revision$"; * *-------------------------------------------------------------------------- */ -void H5_first_thread_init() { - /* initialize global API mutex lock */ - H5_g.H5_libinit_g = FALSE; - H5_g.init_lock.owner_thread = NULL; - pthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL); - pthread_cond_init(&H5_g.init_lock.cond_var, NULL); - H5_g.init_lock.lock_count = 0; - - /* initialize key for thread-specific error stacks */ - pthread_key_create(&H5_errstk_key_g, NULL); - - /* initialize key for thread cancellability mechanism */ - pthread_key_create(&H5_cancel_key_g, NULL); +void +H5TS_first_thread_init(void) +{ + /* initialize global API mutex lock */ + H5_g.H5_libinit_g = FALSE; + H5_g.init_lock.owner_thread = NULL; + pthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL); + pthread_cond_init(&H5_g.init_lock.cond_var, NULL); + H5_g.init_lock.lock_count = 0; + + /* initialize key for thread-specific error stacks */ + pthread_key_create(&H5TS_errstk_key_g, NULL); + + /* initialize key for thread cancellability mechanism */ + pthread_key_create(&H5TS_cancel_key_g, NULL); } +#ifdef NOT_USED /*-------------------------------------------------------------------------- * NAME - * H5_mutex_init + * H5TS_mutex_init * USAGE - * H5_mutex_init(&mutex_var) + * H5TS_mutex_init(&mutex_var) * * RETURNS * @@ -77,18 +99,21 @@ void H5_first_thread_init() { * *-------------------------------------------------------------------------- */ -void H5_mutex_init(H5_mutex_t *H5_mutex) { - (*H5_mutex).owner_thread = NULL; - pthread_mutex_init(&(*H5_mutex).atomic_lock, NULL); - pthread_cond_init(&(*H5_mutex).cond_var, NULL); - (*H5_mutex).lock_count = 0; +static void +H5TS_mutex_init(H5TS_mutex_t *mutex) +{ + (*mutex).owner_thread = NULL; + pthread_mutex_init(&(*mutex).atomic_lock, NULL); + pthread_cond_init(&(*mutex).cond_var, NULL); + (*mutex).lock_count = 0; } +#endif /* NOT_USED */ /*-------------------------------------------------------------------------- * NAME - * H5_mutex_lock + * H5TS_mutex_lock * USAGE - * H5_mutex_lock(&mutex_var) + * H5TS_mutex_lock(&mutex_var) * * RETURNS * @@ -104,36 +129,38 @@ void H5_mutex_init(H5_mutex_t *H5_mutex) { * *-------------------------------------------------------------------------- */ -void H5_mutex_lock(H5_mutex_t *H5_mutex) { - pthread_mutex_lock(&(*H5_mutex).atomic_lock); - if (pthread_equal(pthread_self(), (*H5_mutex).owner_thread)) { - /* already owned by self - increment count */ - (*H5_mutex).lock_count++; - } else { - if ((*H5_mutex).owner_thread == NULL) { - /* no one else has locked it - set owner and grab lock */ - (*H5_mutex).owner_thread = pthread_self(); - (*H5_mutex).lock_count = 1; +void +H5TS_mutex_lock(H5TS_mutex_t *mutex) +{ + pthread_mutex_lock(&(*mutex).atomic_lock); + if (pthread_equal(pthread_self(), (*mutex).owner_thread)) { + /* already owned by self - increment count */ + (*mutex).lock_count++; } else { - /* if already locked by someone else */ - while (1) { - pthread_cond_wait(&(*H5_mutex).cond_var, &(*H5_mutex).atomic_lock); - if ((*H5_mutex).owner_thread == NULL) { - (*H5_mutex).owner_thread = pthread_self(); - (*H5_mutex).lock_count = 1; - break; - } /* else do nothing and loop back to wait on condition*/ - } + if ((*mutex).owner_thread == NULL) { + /* no one else has locked it - set owner and grab lock */ + (*mutex).owner_thread = pthread_self(); + (*mutex).lock_count = 1; + } else { + /* if already locked by someone else */ + while (1) { + pthread_cond_wait(&(*mutex).cond_var, &(*mutex).atomic_lock); + if ((*mutex).owner_thread == NULL) { + (*mutex).owner_thread = pthread_self(); + (*mutex).lock_count = 1; + break; + } /* else do nothing and loop back to wait on condition*/ + } + } } - } - pthread_mutex_unlock(&(*H5_mutex).atomic_lock); + pthread_mutex_unlock(&(*mutex).atomic_lock); } /*-------------------------------------------------------------------------- * NAME - * H5_mutex_unlock + * H5TS_mutex_unlock * USAGE - * H5_mutex_unlock(&mutex_var) + * H5TS_mutex_unlock(&mutex_var) * * RETURNS * @@ -149,21 +176,23 @@ void H5_mutex_lock(H5_mutex_t *H5_mutex) { * *-------------------------------------------------------------------------- */ -void H5_mutex_unlock(H5_mutex_t *H5_mutex) { - pthread_mutex_lock(&(*H5_mutex).atomic_lock); - (*H5_mutex).lock_count--; - if ((*H5_mutex).lock_count == 0) { - (*H5_mutex).owner_thread = NULL; - pthread_cond_signal(&(*H5_mutex).cond_var); - } - pthread_mutex_unlock(&(*H5_mutex).atomic_lock); +void +H5TS_mutex_unlock(H5TS_mutex_t *mutex) +{ + pthread_mutex_lock(&(*mutex).atomic_lock); + (*mutex).lock_count--; + if ((*mutex).lock_count == 0) { + (*mutex).owner_thread = NULL; + pthread_cond_signal(&(*mutex).cond_var); + } + pthread_mutex_unlock(&(*mutex).atomic_lock); } /*-------------------------------------------------------------------------- * NAME - * H5_cancel_count_inc + * H5TS_cancel_count_inc * USAGE - * H5_cancel_count_inc() + * H5TS_cancel_count_inc() * * RETURNS * @@ -184,34 +213,33 @@ void H5_mutex_unlock(H5_mutex_t *H5_mutex) { *-------------------------------------------------------------------------- */ void -H5_cancel_count_inc(void) +H5TS_cancel_count_inc(void) { - H5_cancel_t *cancel_counter; - - if (cancel_counter = pthread_getspecific(H5_cancel_key_g)) { - /* do nothing here */ - } else { - /* first time thread calls library - create new counter and associate - with key - */ - cancel_counter = (H5_cancel_t *)malloc(sizeof(H5_cancel_t)); - cancel_counter->cancel_count = 0; - pthread_setspecific(H5_cancel_key_g, (void *)cancel_counter); - } - - if (cancel_counter->cancel_count == 0) { - /* thread entering library */ - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, - &(cancel_counter->previous_state)); - } - cancel_counter->cancel_count++; + H5TS_cancel_t *cancel_counter; + + if ((cancel_counter = pthread_getspecific(H5TS_cancel_key_g))!=NULL) { + /* do nothing here */ + } else { + /* first time thread calls library - create new counter and associate + * with key + */ + cancel_counter = (H5TS_cancel_t *)malloc(sizeof(H5TS_cancel_t)); + cancel_counter->cancel_count = 0; + pthread_setspecific(H5TS_cancel_key_g, (void *)cancel_counter); + } + + if (cancel_counter->cancel_count == 0) { + /* thread entering library */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &(cancel_counter->previous_state)); + } + cancel_counter->cancel_count++; } /*-------------------------------------------------------------------------- * NAME - * H5_cancel_count_dec + * H5TS_cancel_count_dec * USAGE - * H5_cancel_count_dec() + * H5TS_cancel_count_dec() * * RETURNS * @@ -230,14 +258,14 @@ H5_cancel_count_inc(void) *-------------------------------------------------------------------------- */ void -H5_cancel_count_dec(void) +H5TS_cancel_count_dec(void) { - H5_cancel_t *cancel_counter = pthread_getspecific(H5_cancel_key_g); + H5TS_cancel_t *cancel_counter = pthread_getspecific(H5TS_cancel_key_g); - if (cancel_counter->cancel_count == 1) { - pthread_setcancelstate(cancel_counter->previous_state, NULL); - } - cancel_counter->cancel_count--; + if (cancel_counter->cancel_count == 1) { + pthread_setcancelstate(cancel_counter->previous_state, NULL); + } + cancel_counter->cancel_count--; } #endif diff --git a/src/H5TSprivate.h b/src/H5TSprivate.h new file mode 100644 index 0000000..601b6f0 --- /dev/null +++ b/src/H5TSprivate.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * Copyright (C) 2000 National Center for Supercomputing Applications. + * All rights reserved. + * + *------------------------------------------------------------------------- + * + * Created: H5TSprivate.h + * May 2 2000 + * Chee Wai LEE + * + * Purpose: Private non-prototype header. + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +#ifndef _H5TSprivate_H +#define _H5TSprivate_H + +/* Public headers needed by this file */ +#ifdef LATER +#include /*Public API prototypes */ +#endif /* LATER */ + +/* Library level data structures */ + +typedef struct H5TS_mutex_struct { + pthread_t owner_thread; /* current lock owner */ + pthread_mutex_t atomic_lock; /* lock for atomicity of new mechanism */ + pthread_cond_t cond_var; /* condition variable */ + unsigned int lock_count; +} H5TS_mutex_t; + +/* Extern global variables */ +extern pthread_once_t H5TS_first_init_g; +extern pthread_key_t H5TS_errstk_key_g; + +#if defined c_plusplus || defined __cplusplus +extern "C" +{ +#endif /* c_plusplus || __cplusplus */ + +__DLL__ void H5TS_first_thread_init(void); +__DLL__ void H5TS_mutex_lock(H5TS_mutex_t *mutex); +__DLL__ void H5TS_mutex_unlock(H5TS_mutex_t *mutex); +__DLL__ void H5TS_cancel_count_inc(void); +__DLL__ void H5TS_cancel_count_dec(void); + +#if defined c_plusplus || defined __cplusplus +} +#endif /* c_plusplus || __cplusplus */ + +#endif /* _H5TSprivate_H */ + diff --git a/src/H5private.h b/src/H5private.h index 60e234d..6f451f7 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -879,61 +879,44 @@ __DLL__ void H5_trace(hbool_t returning, const char *func, const char *type, /* Lock headers */ #ifdef H5_HAVE_THREADSAFE -typedef struct H5_mutex_struct { - pthread_t owner_thread; /* current lock owner */ - pthread_mutex_t atomic_lock; /* lock for atomicity of new mechanism */ - pthread_cond_t cond_var; /* condition variable */ - unsigned int lock_count; -} H5_mutex_t; - -/* cancelability structure */ -typedef struct H5_cancel_struct { - int previous_state; - unsigned int cancel_count; -} H5_cancel_t; + +/* Include required thread-safety header */ +#include /* replacement structure for original global variable */ typedef struct H5_api_struct { - H5_mutex_t init_lock; /* API entrance mutex */ + H5TS_mutex_t init_lock; /* API entrance mutex */ hbool_t H5_libinit_g; } H5_api_t; - /* Macro for first thread initialization */ #define H5_FIRST_THREAD_INIT \ - pthread_once(&H5_first_init_g, H5_first_thread_init); + pthread_once(&H5TS_first_init_g, H5TS_first_thread_init); /* Macros for threadsafe HDF-5 Phase I locks */ #define H5_INIT_GLOBAL H5_g.H5_libinit_g #define H5_API_LOCK_BEGIN \ if (H5_IS_API(FUNC)) { \ - H5_mutex_lock(&H5_g.init_lock); + H5TS_mutex_lock(&H5_g.init_lock); #define H5_API_LOCK_END } #define H5_API_UNLOCK_BEGIN \ if (H5_IS_API(FUNC)) { \ - H5_mutex_unlock(&H5_g.init_lock); + H5TS_mutex_unlock(&H5_g.init_lock); #define H5_API_UNLOCK_END } /* Macros for thread cancellation-safe mechanism */ #define H5_API_UNSET_CANCEL \ if (H5_IS_API(FUNC)) { \ - H5_cancel_count_inc(); \ + H5TS_cancel_count_inc(); \ } #define H5_API_SET_CANCEL \ if (H5_IS_API(FUNC)) { \ - H5_cancel_count_dec(); \ + H5TS_cancel_count_dec(); \ } -/* Extern global variables */ -extern pthread_once_t H5_first_init_g; -extern pthread_key_t H5_errstk_key_g; -extern pthread_key_t H5_cancel_key_g; -extern hbool_t H5_allow_concurrent_g; extern H5_api_t H5_g; -void H5_first_thread_init(void); - #else /* disable any first thread init mechanism */ diff --git a/src/Makefile.in b/src/Makefile.in index f5e7643..a2dd70e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -49,8 +49,8 @@ PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h H5FLprivate.h \ H5Gprivate.h H5Gpkg.h H5HGprivate.h H5HLprivate.h H5Iprivate.h \ H5MFprivate.h H5MMprivate.h H5Oprivate.h H5Pprivate.h H5Rprivate.h \ - H5RAprivate.h H5Sprivate.h H5Tprivate.h H5TBprivate.h H5Tpkg.h \ - H5Vprivate.h H5Zprivate.h H5config.h + H5RAprivate.h H5Sprivate.h H5Tprivate.h H5TBprivate.h H5Tpkg.h + H5TSprivate.h H5Vprivate.h H5Zprivate.h H5config.h ## Number format detection ## The LD_LIBRARY_PATH setting is a klutch. -- cgit v0.12