00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009
00010 #ifdef HAVE_MUTEX_PTHREAD
00011
00012 #ifndef lint
00013 static const char revid[] = "$Id: mut__pthread_8c-source.html,v 1.1 2008/06/08 10:20:55 sebdiaz Exp $";
00014 #endif
00015
00016 #ifndef NO_SYSTEM_INCLUDES
00017 #include <sys/types.h>
00018
00019 #include <errno.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #endif
00023
00024 #include "db_int.h"
00025
00026 #ifdef DIAGNOSTIC
00027 #undef MSG1
00028 #define MSG1 "mutex_lock: ERROR: lock currently in use: pid: %lu.\n"
00029 #undef MSG2
00030 #define MSG2 "mutex_unlock: ERROR: lock already unlocked\n"
00031 #ifndef STDERR_FILENO
00032 #define STDERR_FILENO 2
00033 #endif
00034 #endif
00035
00036 #ifdef HAVE_MUTEX_SOLARIS_LWP
00037 #define pthread_cond_signal _lwp_cond_signal
00038 #define pthread_cond_wait _lwp_cond_wait
00039 #define pthread_mutex_lock _lwp_mutex_lock
00040 #define pthread_mutex_trylock _lwp_mutex_trylock
00041 #define pthread_mutex_unlock _lwp_mutex_unlock
00042 #define pthread_self _lwp_self
00043 #endif
00044 #ifdef HAVE_MUTEX_UI_THREADS
00045 #define pthread_cond_signal cond_signal
00046 #define pthread_cond_wait cond_wait
00047 #define pthread_mutex_lock mutex_lock
00048 #define pthread_mutex_trylock mutex_trylock
00049 #define pthread_mutex_unlock mutex_unlock
00050 #define pthread_self thr_self
00051 #endif
00052
00053
00054
00055
00056
00057
00058
00059 int
00060 __db_pthread_mutex_init(dbenv, mutexp, flags)
00061 DB_ENV *dbenv;
00062 MUTEX *mutexp;
00063 u_int32_t flags;
00064 {
00065 int ret;
00066
00067 ret = 0;
00068 memset(mutexp, 0, sizeof(*mutexp));
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 if (LF_ISSET(MUTEX_THREAD) || F_ISSET(dbenv, DB_ENV_PRIVATE)) {
00079 if (!F_ISSET(dbenv, DB_ENV_THREAD)) {
00080 F_SET(mutexp, MUTEX_IGNORE);
00081 return (0);
00082 }
00083 F_SET(mutexp, MUTEX_THREAD);
00084 }
00085
00086 #ifdef HAVE_MUTEX_PTHREADS
00087 {
00088 pthread_condattr_t condattr, *condattrp = NULL;
00089 pthread_mutexattr_t mutexattr, *mutexattrp = NULL;
00090
00091 if (!F_ISSET(mutexp, MUTEX_THREAD)) {
00092 ret = pthread_condattr_init(&condattr);
00093 if (ret == 0)
00094 ret = pthread_condattr_setpshared(
00095 &condattr, PTHREAD_PROCESS_SHARED);
00096 condattrp = &condattr;
00097
00098 if (ret == 0)
00099 ret = pthread_mutexattr_init(&mutexattr);
00100 if (ret == 0)
00101 ret = pthread_mutexattr_setpshared(
00102 &mutexattr, PTHREAD_PROCESS_SHARED);
00103 mutexattrp = &mutexattr;
00104 }
00105
00106 if (ret == 0)
00107 ret = pthread_mutex_init(&mutexp->mutex, mutexattrp);
00108 if (mutexattrp != NULL)
00109 pthread_mutexattr_destroy(mutexattrp);
00110 if (LF_ISSET(MUTEX_SELF_BLOCK)) {
00111 if (ret == 0)
00112 ret = pthread_cond_init(&mutexp->cond, condattrp);
00113
00114 F_SET(mutexp, MUTEX_SELF_BLOCK);
00115 if (condattrp != NULL)
00116 pthread_condattr_destroy(condattrp);
00117 }}
00118 #endif
00119 #ifdef HAVE_MUTEX_SOLARIS_LWP
00120
00121
00122
00123
00124
00125
00126
00127
00128 if (F_ISSET(mutexp, MUTEX_THREAD)) {
00129 static lwp_mutex_t mi = DEFAULTMUTEX;
00130
00131 mutexp->mutex = mi;
00132 } else {
00133 static lwp_mutex_t mi = SHAREDMUTEX;
00134
00135 mutexp->mutex = mi;
00136 }
00137 if (LF_ISSET(MUTEX_SELF_BLOCK)) {
00138 if (F_ISSET(mutexp, MUTEX_THREAD)) {
00139 static lwp_cond_t ci = DEFAULTCV;
00140
00141 mutexp->cond = ci;
00142 } else {
00143 static lwp_cond_t ci = SHAREDCV;
00144
00145 mutexp->cond = ci;
00146 }
00147 F_SET(mutexp, MUTEX_SELF_BLOCK);
00148 }
00149 #endif
00150 #ifdef HAVE_MUTEX_UI_THREADS
00151 {
00152 int type;
00153
00154 type = F_ISSET(mutexp, MUTEX_THREAD) ? USYNC_THREAD : USYNC_PROCESS;
00155
00156 ret = mutex_init(&mutexp->mutex, type, NULL);
00157 if (ret == 0 && LF_ISSET(MUTEX_SELF_BLOCK)) {
00158 ret = cond_init(&mutexp->cond, type, NULL);
00159
00160 F_SET(mutexp, MUTEX_SELF_BLOCK);
00161 }}
00162 #endif
00163
00164 mutexp->spins = CDB___os_spin();
00165
00166 return (ret);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 int
00176 __db_pthread_mutex_lock(mutexp)
00177 MUTEX *mutexp;
00178 {
00179 u_int32_t nspins;
00180 int ret, waited;
00181
00182 if (!DB_GLOBAL(db_mutexlocks) || F_ISSET(mutexp, MUTEX_IGNORE))
00183 return (0);
00184
00185
00186 for (nspins = mutexp->spins; nspins > 0; --nspins)
00187 if (pthread_mutex_trylock(&mutexp->mutex) == 0)
00188 break;
00189
00190 if (nspins == 0 && (ret = pthread_mutex_lock(&mutexp->mutex)) != 0)
00191 return (ret);
00192
00193 if (F_ISSET(mutexp, MUTEX_SELF_BLOCK)) {
00194 for (waited = 0; mutexp->locked != 0; waited = 1) {
00195 ret = pthread_cond_wait(&mutexp->cond, &mutexp->mutex);
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 if (ret != 0 && ret != ETIME && ret != ETIMEDOUT)
00207 return (ret);
00208 }
00209
00210 if (waited)
00211 ++mutexp->mutex_set_wait;
00212 else
00213 ++mutexp->mutex_set_nowait;
00214
00215 #ifdef DIAGNOSTIC
00216 mutexp->locked = (u_int32_t)pthread_self();
00217 #else
00218 mutexp->locked = 1;
00219 #endif
00220 if ((ret = pthread_mutex_unlock(&mutexp->mutex)) != 0)
00221 return (ret);
00222 } else {
00223 if (nspins == mutexp->spins)
00224 ++mutexp->mutex_set_nowait;
00225 else
00226 ++mutexp->mutex_set_wait;
00227 #ifdef DIAGNOSTIC
00228 if (mutexp->locked) {
00229 char msgbuf[128];
00230 (void)snprintf(msgbuf,
00231 sizeof(msgbuf), MSG1, (u_long)mutexp->locked);
00232 (void)write(STDERR_FILENO, msgbuf, strlen(msgbuf));
00233 }
00234 mutexp->locked = (u_int32_t)pthread_self();
00235 #else
00236 mutexp->locked = 1;
00237 #endif
00238 }
00239 return (0);
00240 }
00241
00242
00243
00244
00245
00246
00247
00248 int
00249 __db_pthread_mutex_unlock(mutexp)
00250 MUTEX *mutexp;
00251 {
00252 int ret;
00253
00254 if (!DB_GLOBAL(db_mutexlocks) || F_ISSET(mutexp, MUTEX_IGNORE))
00255 return (0);
00256
00257 #ifdef DIAGNOSTIC
00258 if (!mutexp->locked)
00259 (void)write(STDERR_FILENO, MSG2, sizeof(MSG2) - 1);
00260 #endif
00261
00262 if (F_ISSET(mutexp, MUTEX_SELF_BLOCK)) {
00263 if ((ret = pthread_mutex_lock(&mutexp->mutex)) != 0)
00264 return (ret);
00265
00266 mutexp->locked = 0;
00267
00268 if ((ret = pthread_mutex_unlock(&mutexp->mutex)) != 0)
00269 return (ret);
00270
00271 if ((ret = pthread_cond_signal(&mutexp->cond)) != 0)
00272 return (ret);
00273 } else {
00274 mutexp->locked = 0;
00275
00276 if ((ret = pthread_mutex_unlock(&mutexp->mutex)) != 0)
00277 return (ret);
00278 }
00279
00280 return (0);
00281 }
00282
00283 #endif