diff options
Diffstat (limited to 'bdb/mutex/mut_pthread.c')
-rw-r--r-- | bdb/mutex/mut_pthread.c | 145 |
1 files changed, 89 insertions, 56 deletions
diff --git a/bdb/mutex/mut_pthread.c b/bdb/mutex/mut_pthread.c index 3de4abcefc5..4a55ce0ca03 100644 --- a/bdb/mutex/mut_pthread.c +++ b/bdb/mutex/mut_pthread.c @@ -1,14 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2000 + * Copyright (c) 1999-2002 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: mut_pthread.c,v 11.33 2001/01/09 00:56:16 ubell Exp $"; +static const char revid[] = "$Id: mut_pthread.c,v 11.53 2002/08/13 19:56:47 sue Exp $"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -36,7 +36,11 @@ static const char revid[] = "$Id: mut_pthread.c,v 11.33 2001/01/09 00:56:16 ubel #define pthread_mutex_lock _lwp_mutex_lock #define pthread_mutex_trylock _lwp_mutex_trylock #define pthread_mutex_unlock _lwp_mutex_unlock -#define pthread_self _lwp_self +/* + * _lwp_self returns the LWP process ID which isn't a unique per-thread + * identifier. Use pthread_self instead, it appears to work even if we + * are not a pthreads application. + */ #define pthread_mutex_destroy(x) 0 #endif #ifdef HAVE_MUTEX_UI_THREADS @@ -53,20 +57,31 @@ static const char revid[] = "$Id: mut_pthread.c,v 11.33 2001/01/09 00:56:16 ubel /* * __db_pthread_mutex_init -- - * Initialize a MUTEX. + * Initialize a DB_MUTEX. * - * PUBLIC: int __db_pthread_mutex_init __P((DB_ENV *, MUTEX *, u_int32_t)); + * PUBLIC: int __db_pthread_mutex_init __P((DB_ENV *, DB_MUTEX *, u_int32_t)); */ int __db_pthread_mutex_init(dbenv, mutexp, flags) DB_ENV *dbenv; - MUTEX *mutexp; + DB_MUTEX *mutexp; u_int32_t flags; { + u_int32_t save; int ret; ret = 0; + + /* + * The only setting/checking of the MUTEX_MPOOL flags is in the mutex + * mutex allocation code (__db_mutex_alloc/free). Preserve only that + * flag. This is safe because even if this flag was never explicitly + * set, but happened to be set in memory, it will never be checked or + * acted upon. + */ + save = F_ISSET(mutexp, MUTEX_MPOOL); memset(mutexp, 0, sizeof(*mutexp)); + F_SET(mutexp, save); /* * If this is a thread lock or the process has told us that there are @@ -81,7 +96,6 @@ __db_pthread_mutex_init(dbenv, mutexp, flags) F_SET(mutexp, MUTEX_IGNORE); return (0); } - F_SET(mutexp, MUTEX_THREAD); } #ifdef HAVE_MUTEX_PTHREADS @@ -89,18 +103,13 @@ __db_pthread_mutex_init(dbenv, mutexp, flags) pthread_condattr_t condattr, *condattrp = NULL; pthread_mutexattr_t mutexattr, *mutexattrp = NULL; - if (!F_ISSET(mutexp, MUTEX_THREAD)) { - ret = pthread_condattr_init(&condattr); - if (ret == 0) - ret = pthread_condattr_setpshared( - &condattr, PTHREAD_PROCESS_SHARED); - condattrp = &condattr; - - if (ret == 0) - ret = pthread_mutexattr_init(&mutexattr); + if (!LF_ISSET(MUTEX_THREAD)) { + ret = pthread_mutexattr_init(&mutexattr); +#ifndef HAVE_MUTEX_THREAD_ONLY if (ret == 0) ret = pthread_mutexattr_setpshared( &mutexattr, PTHREAD_PROCESS_SHARED); +#endif mutexattrp = &mutexattr; } @@ -108,14 +117,27 @@ __db_pthread_mutex_init(dbenv, mutexp, flags) ret = pthread_mutex_init(&mutexp->mutex, mutexattrp); if (mutexattrp != NULL) pthread_mutexattr_destroy(mutexattrp); - if (LF_ISSET(MUTEX_SELF_BLOCK)) { + if (ret == 0 && LF_ISSET(MUTEX_SELF_BLOCK)) { + if (!LF_ISSET(MUTEX_THREAD)) { + ret = pthread_condattr_init(&condattr); +#ifndef HAVE_MUTEX_THREAD_ONLY + if (ret == 0) { + condattrp = &condattr; + ret = pthread_condattr_setpshared( + &condattr, PTHREAD_PROCESS_SHARED); + } +#endif + } + if (ret == 0) ret = pthread_cond_init(&mutexp->cond, condattrp); F_SET(mutexp, MUTEX_SELF_BLOCK); if (condattrp != NULL) - pthread_condattr_destroy(condattrp); - }} + (void)pthread_condattr_destroy(condattrp); + } + + } #endif #ifdef HAVE_MUTEX_SOLARIS_LWP /* @@ -126,7 +148,7 @@ __db_pthread_mutex_init(dbenv, mutexp, flags) * initialization values doesn't have surrounding braces. There's not * much we can do. */ - if (F_ISSET(mutexp, MUTEX_THREAD)) { + if (LF_ISSET(MUTEX_THREAD)) { static lwp_mutex_t mi = DEFAULTMUTEX; mutexp->mutex = mi; @@ -136,7 +158,7 @@ __db_pthread_mutex_init(dbenv, mutexp, flags) mutexp->mutex = mi; } if (LF_ISSET(MUTEX_SELF_BLOCK)) { - if (F_ISSET(mutexp, MUTEX_THREAD)) { + if (LF_ISSET(MUTEX_THREAD)) { static lwp_cond_t ci = DEFAULTCV; mutexp->cond = ci; @@ -152,7 +174,7 @@ __db_pthread_mutex_init(dbenv, mutexp, flags) { int type; - type = F_ISSET(mutexp, MUTEX_THREAD) ? USYNC_THREAD : USYNC_PROCESS; + type = LF_ISSET(MUTEX_THREAD) ? USYNC_THREAD : USYNC_PROCESS; ret = mutex_init(&mutexp->mutex, type, NULL); if (ret == 0 && LF_ISSET(MUTEX_SELF_BLOCK)) { @@ -162,12 +184,15 @@ __db_pthread_mutex_init(dbenv, mutexp, flags) }} #endif - mutexp->spins = __os_spin(); -#ifdef MUTEX_SYSTEM_RESOURCES + mutexp->spins = __os_spin(dbenv); +#ifdef HAVE_MUTEX_SYSTEM_RESOURCES mutexp->reg_off = INVALID_ROFF; #endif if (ret == 0) F_SET(mutexp, MUTEX_INITED); + else + __db_err(dbenv, + "unable to initialize mutex: %s", strerror(ret)); return (ret); } @@ -176,17 +201,17 @@ __db_pthread_mutex_init(dbenv, mutexp, flags) * __db_pthread_mutex_lock * Lock on a mutex, logically blocking if necessary. * - * PUBLIC: int __db_pthread_mutex_lock __P((DB_ENV *, MUTEX *)); + * PUBLIC: int __db_pthread_mutex_lock __P((DB_ENV *, DB_MUTEX *)); */ int __db_pthread_mutex_lock(dbenv, mutexp) DB_ENV *dbenv; - MUTEX *mutexp; + DB_MUTEX *mutexp; { u_int32_t nspins; int i, ret, waited; - if (!dbenv->db_mutexlocks || F_ISSET(mutexp, MUTEX_IGNORE)) + if (F_ISSET(dbenv, DB_ENV_NOLOCKING) || F_ISSET(mutexp, MUTEX_IGNORE)) return (0); /* Attempt to acquire the resource for N spins. */ @@ -195,7 +220,7 @@ __db_pthread_mutex_lock(dbenv, mutexp) break; if (nspins == 0 && (ret = pthread_mutex_lock(&mutexp->mutex)) != 0) - return (ret); + goto err; if (F_ISSET(mutexp, MUTEX_SELF_BLOCK)) { for (waited = 0; mutexp->locked != 0; waited = 1) { @@ -210,8 +235,14 @@ __db_pthread_mutex_lock(dbenv, mutexp) * call, and Solaris delivers the signal to the wrong * LWP. */ - if (ret != 0 && ret != ETIME && ret != ETIMEDOUT) + if (ret != 0 && ret != EINTR && +#ifdef ETIME + ret != ETIME && +#endif + ret != ETIMEDOUT) { + (void)pthread_mutex_unlock(&mutexp->mutex); return (ret); + } } if (waited) @@ -238,11 +269,14 @@ __db_pthread_mutex_lock(dbenv, mutexp) ret = pthread_mutex_unlock(&mutexp->mutex); } while (ret == EFAULT && --i > 0); if (ret != 0) - return (ret); + goto err; } else { if (nspins == mutexp->spins) ++mutexp->mutex_set_nowait; - else + else if (nspins > 0) { + ++mutexp->mutex_set_spin; + mutexp->mutex_set_spins += mutexp->spins - nspins; + } else ++mutexp->mutex_set_wait; #ifdef DIAGNOSTIC if (mutexp->locked) { @@ -257,22 +291,25 @@ __db_pthread_mutex_lock(dbenv, mutexp) #endif } return (0); + +err: __db_err(dbenv, "unable to lock mutex: %s", strerror(ret)); + return (ret); } /* * __db_pthread_mutex_unlock -- * Release a lock. * - * PUBLIC: int __db_pthread_mutex_unlock __P((DB_ENV *, MUTEX *)); + * PUBLIC: int __db_pthread_mutex_unlock __P((DB_ENV *, DB_MUTEX *)); */ int __db_pthread_mutex_unlock(dbenv, mutexp) DB_ENV *dbenv; - MUTEX *mutexp; + DB_MUTEX *mutexp; { int i, ret; - if (!dbenv->db_mutexlocks || F_ISSET(mutexp, MUTEX_IGNORE)) + if (F_ISSET(dbenv, DB_ENV_NOLOCKING) || F_ISSET(mutexp, MUTEX_IGNORE)) return (0); #ifdef DIAGNOSTIC @@ -282,47 +319,43 @@ __db_pthread_mutex_unlock(dbenv, mutexp) if (F_ISSET(mutexp, MUTEX_SELF_BLOCK)) { if ((ret = pthread_mutex_lock(&mutexp->mutex)) != 0) - return (ret); + goto err; mutexp->locked = 0; if ((ret = pthread_cond_signal(&mutexp->cond)) != 0) return (ret); - /* See comment above; workaround for [#2471]. */ - i = PTHREAD_UNLOCK_ATTEMPTS; - do { - ret = pthread_mutex_unlock(&mutexp->mutex); - } while (ret == EFAULT && --i > 0); - if (ret != 0) - return (ret); - } else { + } else mutexp->locked = 0; - /* See comment above; workaround for [#2471]. */ - i = PTHREAD_UNLOCK_ATTEMPTS; - do { - ret = pthread_mutex_unlock(&mutexp->mutex); - } while (ret == EFAULT && --i > 0); - if (ret != 0) - return (ret); - } + /* See comment above; workaround for [#2471]. */ + i = PTHREAD_UNLOCK_ATTEMPTS; + do { + ret = pthread_mutex_unlock(&mutexp->mutex); + } while (ret == EFAULT && --i > 0); + return (ret); - return (0); +err: __db_err(dbenv, "unable to unlock mutex: %s", strerror(ret)); + return (ret); } /* * __db_pthread_mutex_destroy -- - * Destroy a MUTEX. + * Destroy a DB_MUTEX. * - * PUBLIC: int __db_pthread_mutex_destroy __P((MUTEX *)); + * PUBLIC: int __db_pthread_mutex_destroy __P((DB_MUTEX *)); */ int __db_pthread_mutex_destroy(mutexp) - MUTEX *mutexp; + DB_MUTEX *mutexp; { + int ret; + if (F_ISSET(mutexp, MUTEX_IGNORE)) return (0); - return (pthread_mutex_destroy(&mutexp->mutex)); + if ((ret = pthread_mutex_destroy(&mutexp->mutex)) != 0) + __db_err(NULL, "unable to destroy mutex: %s", strerror(ret)); + return (ret); } |