db

mut_tas.c

Go to the documentation of this file.
00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996, 1997, 1998, 1999, 2000
00005  * Sleepycat Software. All rights reserved.
00006  */
00007 
00008 #include "config.h"
00009 
00010 #ifdef HAVE_MUTEX_TAS
00011 
00012 #ifndef lint
00013 static const char revid[] = "$Id: mut__tas_8c-source.html,v 1.1 2008年06月08日 10:20:55 sebdiaz Exp $";
00014 #endif /* not lint */
00015 
00016 #ifndef NO_SYSTEM_INCLUDES
00017 #include <sys/types.h>
00018 
00019 #include <errno.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <unistd.h>
00023 #endif
00024 
00025 #include "db_int.h"
00026 
00027 #ifdef HAVE_MUTEX_68K_GCC_ASSEMBLY
00028 #include "68K.gcc"
00029 #endif
00030 #ifdef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY
00031 #include "alpha.gcc"
00032 #endif
00033 #ifdef HAVE_MUTEX_HPPA_GCC_ASSEMBLY
00034 #include "parisc.gcc"
00035 #endif
00036 #ifdef HAVE_MUTEX_IA64_GCC_ASSEMBLY
00037 #include "ia64.gcc"
00038 #endif
00039 #ifdef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY
00040 #include "sco.cc"
00041 #endif
00042 #ifdef HAVE_MUTEX_SPARC_GCC_ASSEMBLY
00043 #include "sparc.gcc"
00044 #endif
00045 #ifdef HAVE_MUTEX_X86_GCC_ASSEMBLY
00046 #include "x86.gcc"
00047 #endif
00048 
00049 #ifdef DIAGNOSTIC
00050 #undef MSG1
00051 #define MSG1 "mutex_lock: ERROR: lock currently in use: pid: %lu.\n"
00052 #undef MSG2
00053 #define MSG2 "mutex_unlock: ERROR: lock already unlocked\n"
00054 #ifndef STDERR_FILENO
00055 #define STDERR_FILENO 2
00056 #endif
00057 #endif
00058 
00059 /*
00060  * CDB___db_tas_mutex_init --
00061  * Initialize a MUTEX.
00062  *
00063  * PUBLIC: int CDB___db_tas_mutex_init __P((DB_ENV *, MUTEX *, u_int32_t));
00064  */
00065 int
00066 CDB___db_tas_mutex_init(dbenv, mutexp, flags)
00067 DB_ENV *dbenv;
00068 MUTEX *mutexp;
00069 u_int32_t flags;
00070 {
00071 /* Check alignment. */
00072 DB_ASSERT(((db_alignp_t)mutexp & (MUTEX_ALIGN - 1)) == 0);
00073 
00074 memset(mutexp, 0, sizeof(*mutexp));
00075 
00076 /*
00077  * If this is a thread lock or the process has told us that there are
00078  * no other processes in the environment, use thread-only locks, they
00079  * are faster in some cases.
00080  *
00081  * This is where we decide to ignore locks we don't need to set -- if
00082  * the application isn't threaded, there aren't any threads to block.
00083  */
00084 if (LF_ISSET(MUTEX_THREAD) || F_ISSET(dbenv, DB_ENV_PRIVATE)) {
00085 if (!F_ISSET(dbenv, DB_ENV_THREAD)) {
00086 F_SET(mutexp, MUTEX_IGNORE);
00087 return (0);
00088 }
00089 F_SET(mutexp, MUTEX_THREAD);
00090 }
00091 
00092 /* Initialize the lock. */
00093 if (MUTEX_INIT(&mutexp->tas))
00094 return (CDB___os_get_errno());
00095 
00096 mutexp->spins = CDB___os_spin();
00097 
00098 return (0);
00099 }
00100 
00101 /*
00102  * CDB___db_tas_mutex_lock
00103  * Lock on a mutex, logically blocking if necessary.
00104  *
00105  * PUBLIC: int CDB___db_tas_mutex_lock __P((MUTEX *));
00106  */
00107 int
00108 CDB___db_tas_mutex_lock(mutexp)
00109 MUTEX *mutexp;
00110 {
00111 u_long ms;
00112 int nspins;
00113 
00114 if (!DB_GLOBAL(db_mutexlocks) || F_ISSET(mutexp, MUTEX_IGNORE))
00115 return (0);
00116 
00117 ms = 1;
00118 
00119 loop: /* Attempt to acquire the resource for N spins. */
00120 for (nspins = mutexp->spins; nspins > 0; --nspins) {
00121 #ifdef HAVE_MUTEX_HPPA_MSEM_INIT
00122 relock:
00123 #endif
00124 if (!MUTEX_SET(&mutexp->tas))
00125 continue;
00126 #ifdef HAVE_MUTEX_HPPA_MSEM_INIT
00127 /* 
00128  * HP semaphores are unlocked automatically when a holding
00129  * process exits. If the mutex appears to be locked
00130  * (mutexp->locked != 0) but we got here, assume this has
00131  * happened. Stick our own pid into mutexp->locked and
00132  * lock again. (The default state of the mutexes used to
00133  * block in __lock_get_internal is locked, so exiting with
00134  * a locked mutex is reasonable behavior for a process that
00135  * happened to initialize or use one of them.)
00136  */
00137 if (mutexp->locked != 0) {
00138 mutexp->locked = (u_int32_t)getpid();
00139 goto relock;
00140 }
00141 /* 
00142  * If we make it here, locked == 0, the diagnostic won't fire,
00143  * and we were really unlocked by someone calling the
00144  * DB mutex unlock function.
00145  */
00146 #endif
00147 #ifdef DIAGNOSTIC
00148 if (mutexp->locked != 0) {
00149 char msgbuf[128];
00150 (void)snprintf(msgbuf,
00151 sizeof(msgbuf), MSG1, (u_long)mutexp->locked);
00152 (void)write(STDERR_FILENO, msgbuf, strlen(msgbuf));
00153 }
00154 #endif
00155 #if defined(DIAGNOSTIC) || defined(HAVE_MUTEX_HPPA_MSEM_INIT)
00156 mutexp->locked = (u_int32_t)getpid();
00157 #endif
00158 if (ms == 1)
00159 ++mutexp->mutex_set_nowait;
00160 else
00161 ++mutexp->mutex_set_wait;
00162 return (0);
00163 }
00164 
00165 /* Yield the processor; wait 1ms initially, up to 1 second. */
00166 CDB___os_yield(NULL, ms * USEC_PER_MS);
00167 if ((ms <<= 1) > MS_PER_SEC)
00168 ms = MS_PER_SEC;
00169 
00170 goto loop;
00171 }
00172 
00173 /*
00174  * CDB___db_tas_mutex_unlock --
00175  * Release a lock.
00176  *
00177  * PUBLIC: int CDB___db_tas_mutex_unlock __P((MUTEX *));
00178  */
00179 int
00180 CDB___db_tas_mutex_unlock(mutexp)
00181 MUTEX *mutexp;
00182 {
00183 if (!DB_GLOBAL(db_mutexlocks) || F_ISSET(mutexp, MUTEX_IGNORE))
00184 return (0);
00185 
00186 #ifdef DIAGNOSTIC
00187 if (!mutexp->locked)
00188 (void)write(STDERR_FILENO, MSG2, sizeof(MSG2) - 1);
00189 #endif
00190 #if defined(DIAGNOSTIC) || defined(HAVE_MUTEX_HPPA_MSEM_INIT)
00191 mutexp->locked = 0;
00192 #endif
00193 
00194 MUTEX_UNSET(&mutexp->tas);
00195 
00196 return (0);
00197 }
00198 #endif /* HAVE_MUTEX_TAS */

Generated on Sun Jun 8 10:56:38 2008 for GNUmifluz by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /