2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1999-2009 Oracle. All rights reserved.
15 * Allocate a mutex from the mutex region.
17 * PUBLIC: int __mutex_alloc __P((ENV *, int, u_int32_t, db_mutex_t *));
20 __mutex_alloc(env, alloc_id, flags, indxp)
28 /* The caller may depend on us to initialize. */
29 *indxp = MUTEX_INVALID;
32 * If this is not an application lock, and we've turned off locking,
33 * or the ENV handle isn't thread-safe, and this is a thread lock
34 * or the environment isn't multi-process by definition, there's no
35 * need to mutex at all.
37 if (alloc_id != MTX_APPLICATION &&
38 (F_ISSET(env->dbenv, DB_ENV_NOLOCKING) ||
39 (!F_ISSET(env, ENV_THREAD) &&
40 (LF_ISSET(DB_MUTEX_PROCESS_ONLY) ||
41 F_ISSET(env, ENV_PRIVATE)))))
44 /* Private environments never share mutexes. */
45 if (F_ISSET(env, ENV_PRIVATE))
46 LF_SET(DB_MUTEX_PROCESS_ONLY);
49 * If we have a region in which to allocate the mutexes, lock it and
53 return (__mutex_alloc_int(env, 1, alloc_id, flags, indxp));
56 * We have to allocate some number of mutexes before we have a region
57 * in which to allocate them. We handle this by saving up the list of
58 * flags and allocating them as soon as we have a handle.
60 * The list of mutexes to alloc is maintained in pairs: first the
61 * alloc_id argument, second the flags passed in by the caller.
63 if (env->mutex_iq == NULL) {
64 env->mutex_iq_max = 50;
65 if ((ret = __os_calloc(env, env->mutex_iq_max,
66 sizeof(env->mutex_iq[0]), &env->mutex_iq)) != 0)
68 } else if (env->mutex_iq_next == env->mutex_iq_max - 1) {
69 env->mutex_iq_max *= 2;
70 if ((ret = __os_realloc(env,
71 env->mutex_iq_max * sizeof(env->mutex_iq[0]),
72 &env->mutex_iq)) != 0)
75 *indxp = env->mutex_iq_next + 1; /* Correct for MUTEX_INVALID. */
76 env->mutex_iq[env->mutex_iq_next].alloc_id = alloc_id;
77 env->mutex_iq[env->mutex_iq_next].flags = flags;
84 * __mutex_alloc_int --
85 * Internal routine to allocate a mutex.
87 * PUBLIC: int __mutex_alloc_int
88 * PUBLIC: __P((ENV *, int, int, u_int32_t, db_mutex_t *));
91 __mutex_alloc_int(env, locksys, alloc_id, flags, indxp)
93 int locksys, alloc_id;
100 DB_MUTEXREGION *mtxregion;
104 mtxmgr = env->mutex_handle;
105 mtxregion = mtxmgr->reginfo.primary;
109 * If we're not initializing the mutex region, then lock the region to
110 * allocate new mutexes. Drop the lock before initializing the mutex,
111 * mutex initialization may require a system call.
114 MUTEX_SYSTEM_LOCK(env);
116 if (mtxregion->mutex_next == MUTEX_INVALID) {
118 "unable to allocate memory for mutex; resize mutex region");
120 MUTEX_SYSTEM_UNLOCK(env);
124 *indxp = mtxregion->mutex_next;
125 mutexp = MUTEXP_SET(mtxmgr, *indxp);
127 ((uintptr_t)mutexp & (dbenv->mutex_align - 1)) == 0);
128 mtxregion->mutex_next = mutexp->mutex_next_link;
130 --mtxregion->stat.st_mutex_free;
131 ++mtxregion->stat.st_mutex_inuse;
132 if (mtxregion->stat.st_mutex_inuse > mtxregion->stat.st_mutex_inuse_max)
133 mtxregion->stat.st_mutex_inuse_max =
134 mtxregion->stat.st_mutex_inuse;
136 MUTEX_SYSTEM_UNLOCK(env);
138 /* Initialize the mutex. */
139 memset(mutexp, 0, sizeof(*mutexp));
140 F_SET(mutexp, DB_MUTEX_ALLOCATED |
141 LF_ISSET(DB_MUTEX_LOGICAL_LOCK |
142 DB_MUTEX_PROCESS_ONLY | DB_MUTEX_SHARED));
145 * If the mutex is associated with a single process, set the process
146 * ID. If the application ever calls DbEnv::failchk, we'll need the
147 * process ID to know if the mutex is still in use.
149 if (LF_ISSET(DB_MUTEX_PROCESS_ONLY))
150 dbenv->thread_id(dbenv, &mutexp->pid, NULL);
152 #ifdef HAVE_STATISTICS
153 mutexp->alloc_id = alloc_id;
155 COMPQUIET(alloc_id, 0);
158 if ((ret = __mutex_init(env, *indxp, flags)) != 0)
159 (void)__mutex_free_int(env, locksys, indxp);
168 * PUBLIC: int __mutex_free __P((ENV *, db_mutex_t *));
171 __mutex_free(env, indxp)
176 * There is no explicit ordering in how the regions are cleaned up
177 * up and/or discarded when an environment is destroyed (either a
178 * private environment is closed or a public environment is removed).
179 * The way we deal with mutexes is to clean up all remaining mutexes
180 * when we close the mutex environment (because we have to be able to
181 * do that anyway, after a crash), which means we don't have to deal
182 * with region cleanup ordering on normal environment destruction.
183 * All that said, what it really means is we can get here without a
184 * mpool region. It's OK, the mutex has been, or will be, destroyed.
186 * If the mutex has never been configured, we're done.
188 if (!MUTEX_ON(env) || *indxp == MUTEX_INVALID)
191 return (__mutex_free_int(env, 1, indxp));
195 * __mutex_free_int --
196 * Internal routine to free a mutex.
198 * PUBLIC: int __mutex_free_int __P((ENV *, int, db_mutex_t *));
201 __mutex_free_int(env, locksys, indxp)
208 DB_MUTEXREGION *mtxregion;
213 *indxp = MUTEX_INVALID;
215 mtxmgr = env->mutex_handle;
216 mtxregion = mtxmgr->reginfo.primary;
217 mutexp = MUTEXP_SET(mtxmgr, mutex);
219 DB_ASSERT(env, F_ISSET(mutexp, DB_MUTEX_ALLOCATED));
220 F_CLR(mutexp, DB_MUTEX_ALLOCATED);
222 ret = __mutex_destroy(env, mutex);
225 MUTEX_SYSTEM_LOCK(env);
227 /* Link the mutex on the head of the free list. */
228 mutexp->mutex_next_link = mtxregion->mutex_next;
229 mtxregion->mutex_next = mutex;
230 ++mtxregion->stat.st_mutex_free;
231 --mtxregion->stat.st_mutex_inuse;
234 MUTEX_SYSTEM_UNLOCK(env);