00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014
00015 #include <string.h>
00016 #endif
00017
00018 #include "db_int.h"
00019 #include "dbinc/mutex_int.h"
00020
00021 static int __mutex_free_int __P((DB_ENV *, int, db_mutex_t *));
00022
00023
00024
00025
00026
00027
00028
00029 int
00030 __mutex_alloc(dbenv, alloc_id, flags, indxp)
00031 DB_ENV *dbenv;
00032 int alloc_id;
00033 u_int32_t flags;
00034 db_mutex_t *indxp;
00035 {
00036 int ret;
00037
00038
00039 *indxp = MUTEX_INVALID;
00040
00041
00042
00043
00044
00045
00046
00047 if (alloc_id != MTX_APPLICATION &&
00048 (F_ISSET(dbenv, DB_ENV_NOLOCKING) ||
00049 (!F_ISSET(dbenv, DB_ENV_THREAD) &&
00050 (LF_ISSET(DB_MUTEX_THREAD) || F_ISSET(dbenv, DB_ENV_PRIVATE)))))
00051 return (0);
00052
00053
00054
00055
00056
00057 if (MUTEX_ON(dbenv))
00058 return (__mutex_alloc_int(dbenv, 1, alloc_id, flags, indxp));
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 if (dbenv->mutex_iq == NULL) {
00069 dbenv->mutex_iq_max = 50;
00070 if ((ret = __os_calloc(dbenv, dbenv->mutex_iq_max,
00071 sizeof(dbenv->mutex_iq[0]), &dbenv->mutex_iq)) != 0)
00072 return (ret);
00073 } else if (dbenv->mutex_iq_next == dbenv->mutex_iq_max - 1) {
00074 dbenv->mutex_iq_max *= 2;
00075 if ((ret = __os_realloc(dbenv,
00076 dbenv->mutex_iq_max * sizeof(dbenv->mutex_iq[0]),
00077 &dbenv->mutex_iq)) != 0)
00078 return (ret);
00079 }
00080 *indxp = dbenv->mutex_iq_next + 1;
00081 dbenv->mutex_iq[dbenv->mutex_iq_next].alloc_id = alloc_id;
00082 dbenv->mutex_iq[dbenv->mutex_iq_next].flags = flags;
00083 ++dbenv->mutex_iq_next;
00084
00085 return (0);
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095 int
00096 __mutex_alloc_int(dbenv, locksys, alloc_id, flags, indxp)
00097 DB_ENV *dbenv;
00098 int locksys, alloc_id;
00099 u_int32_t flags;
00100 db_mutex_t *indxp;
00101 {
00102 DB_MUTEX *mutexp;
00103 DB_MUTEXMGR *mtxmgr;
00104 DB_MUTEXREGION *mtxregion;
00105 int ret;
00106
00107 mtxmgr = dbenv->mutex_handle;
00108 mtxregion = mtxmgr->reginfo.primary;
00109 ret = 0;
00110
00111
00112
00113
00114
00115
00116 if (locksys)
00117 MUTEX_SYSTEM_LOCK(dbenv);
00118
00119 if (mtxregion->mutex_next == MUTEX_INVALID) {
00120 __db_err(dbenv,
00121 "unable to allocate memory for mutex; resize mutex region");
00122 if (locksys)
00123 MUTEX_SYSTEM_UNLOCK(dbenv);
00124 return (ENOMEM);
00125 }
00126
00127 *indxp = mtxregion->mutex_next;
00128 mutexp = MUTEXP_SET(*indxp);
00129 mtxregion->mutex_next = mutexp->mutex_next_link;
00130
00131 --mtxregion->stat.st_mutex_free;
00132 ++mtxregion->stat.st_mutex_inuse;
00133 if (mtxregion->stat.st_mutex_inuse > mtxregion->stat.st_mutex_inuse_max)
00134 mtxregion->stat.st_mutex_inuse_max =
00135 mtxregion->stat.st_mutex_inuse;
00136 if (locksys)
00137 MUTEX_SYSTEM_UNLOCK(dbenv);
00138
00139
00140 memset(mutexp, 0, sizeof(*mutexp));
00141
00142 F_SET(mutexp, DB_MUTEX_ALLOCATED);
00143 if (LF_ISSET(DB_MUTEX_LOGICAL_LOCK))
00144 F_SET(mutexp, DB_MUTEX_LOGICAL_LOCK);
00145
00146 #ifdef DIAGNOSTIC
00147 mutexp->alloc_id = alloc_id;
00148 #else
00149 COMPQUIET(alloc_id, 0);
00150 #endif
00151
00152 if ((ret = __mutex_init(dbenv, *indxp, flags)) != 0)
00153 (void)__mutex_free_int(dbenv, locksys, indxp);
00154
00155 return (ret);
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 int
00165 __mutex_free(dbenv, indxp)
00166 DB_ENV *dbenv;
00167 db_mutex_t *indxp;
00168 {
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 if (!MUTEX_ON(dbenv) || *indxp == MUTEX_INVALID)
00183 return (0);
00184
00185 return (__mutex_free_int(dbenv, 1, indxp));
00186 }
00187
00188
00189
00190
00191
00192 static int
00193 __mutex_free_int(dbenv, locksys, indxp)
00194 DB_ENV *dbenv;
00195 int locksys;
00196 db_mutex_t *indxp;
00197 {
00198 DB_MUTEX *mutexp;
00199 DB_MUTEXMGR *mtxmgr;
00200 DB_MUTEXREGION *mtxregion;
00201 db_mutex_t mutex;
00202 int ret;
00203
00204 mutex = *indxp;
00205 *indxp = MUTEX_INVALID;
00206
00207 mtxmgr = dbenv->mutex_handle;
00208 mtxregion = mtxmgr->reginfo.primary;
00209 mutexp = MUTEXP_SET(mutex);
00210
00211 DB_ASSERT(F_ISSET(mutexp, DB_MUTEX_ALLOCATED));
00212 F_CLR(mutexp, DB_MUTEX_ALLOCATED);
00213
00214 ret = __mutex_destroy(dbenv, mutex);
00215
00216 if (locksys)
00217 MUTEX_SYSTEM_LOCK(dbenv);
00218
00219
00220 mutexp->mutex_next_link = mtxregion->mutex_next;
00221 mtxregion->mutex_next = mutex;
00222 ++mtxregion->stat.st_mutex_free;
00223 --mtxregion->stat.st_mutex_inuse;
00224
00225 if (locksys)
00226 MUTEX_SYSTEM_UNLOCK(dbenv);
00227
00228 return (ret);
00229 }