Give mutex(9) the ability to recurse on a per-instance basis.
Now the MTX_RECURSE flag can be passed to the mtx_*_flag() calls. This helps in cases we want to narrow down to specific calls the possibility to recurse for some locks. Sponsored by: EMC / Isilon storage division Reviewed by: jeff, alc Tested by: pho
This commit is contained in:
parent
c7aebda8a1
commit
ac6b769be9
@ -225,8 +225,10 @@ or
|
||||
lock, respectively, and also accept a
|
||||
.Fa flags
|
||||
argument.
|
||||
In both cases, the only flag presently available for lock acquires is
|
||||
.Dv MTX_QUIET .
|
||||
In both cases, the only flags presently available for lock acquires are
|
||||
.Dv MTX_QUIET
|
||||
and
|
||||
.Dv MTX_RECURSE .
|
||||
If the
|
||||
.Dv MTX_QUIET
|
||||
bit is turned on in the
|
||||
@ -235,6 +237,12 @@ argument, then if
|
||||
.Dv KTR_LOCK
|
||||
tracing is being done,
|
||||
it will be silenced during the lock acquire.
|
||||
If the
|
||||
.Dv MTX_RECURSE
|
||||
bit is turned on in the
|
||||
.Fa flags
|
||||
argument, then the mutex can be acquired recursively.
|
||||
.Pp
|
||||
.Pp
|
||||
The
|
||||
.Fn mtx_trylock
|
||||
|
@ -218,13 +218,14 @@ __mtx_lock_flags(volatile uintptr_t *c, int opts, const char *file, int line)
|
||||
KASSERT(LOCK_CLASS(&m->lock_object) == &lock_class_mtx_sleep,
|
||||
("mtx_lock() of spin mutex %s @ %s:%d", m->lock_object.lo_name,
|
||||
file, line));
|
||||
WITNESS_CHECKORDER(&m->lock_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
|
||||
file, line, NULL);
|
||||
WITNESS_CHECKORDER(&m->lock_object, (opts & ~MTX_RECURSE) |
|
||||
LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL);
|
||||
|
||||
__mtx_lock(m, curthread, opts, file, line);
|
||||
LOCK_LOG_LOCK("LOCK", &m->lock_object, opts, m->mtx_recurse, file,
|
||||
line);
|
||||
WITNESS_LOCK(&m->lock_object, opts | LOP_EXCLUSIVE, file, line);
|
||||
WITNESS_LOCK(&m->lock_object, (opts & ~MTX_RECURSE) | LOP_EXCLUSIVE,
|
||||
file, line);
|
||||
curthread->td_locks++;
|
||||
}
|
||||
|
||||
@ -271,9 +272,11 @@ __mtx_lock_spin_flags(volatile uintptr_t *c, int opts, const char *file,
|
||||
("mtx_lock_spin() of sleep mutex %s @ %s:%d",
|
||||
m->lock_object.lo_name, file, line));
|
||||
if (mtx_owned(m))
|
||||
KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0,
|
||||
KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0 ||
|
||||
(opts & MTX_RECURSE) != 0,
|
||||
("mtx_lock_spin: recursed on non-recursive mutex %s @ %s:%d\n",
|
||||
m->lock_object.lo_name, file, line));
|
||||
opts &= ~MTX_RECURSE;
|
||||
WITNESS_CHECKORDER(&m->lock_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE,
|
||||
file, line, NULL);
|
||||
__mtx_lock_spin(m, curthread, opts, file, line);
|
||||
@ -335,12 +338,14 @@ _mtx_trylock_flags_(volatile uintptr_t *c, int opts, const char *file, int line)
|
||||
("mtx_trylock() of spin mutex %s @ %s:%d", m->lock_object.lo_name,
|
||||
file, line));
|
||||
|
||||
if (mtx_owned(m) && (m->lock_object.lo_flags & LO_RECURSABLE) != 0) {
|
||||
if (mtx_owned(m) && ((m->lock_object.lo_flags & LO_RECURSABLE) != 0 ||
|
||||
(opts & MTX_RECURSE) != 0)) {
|
||||
m->mtx_recurse++;
|
||||
atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
|
||||
rval = 1;
|
||||
} else
|
||||
rval = _mtx_obtain_lock(m, (uintptr_t)curthread);
|
||||
opts &= ~MTX_RECURSE;
|
||||
|
||||
LOCK_LOG_TRY("LOCK", &m->lock_object, opts, rval, file, line);
|
||||
if (rval) {
|
||||
@ -391,15 +396,18 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
|
||||
m = mtxlock2mtx(c);
|
||||
|
||||
if (mtx_owned(m)) {
|
||||
KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0,
|
||||
KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0 ||
|
||||
(opts & MTX_RECURSE) != 0,
|
||||
("_mtx_lock_sleep: recursed on non-recursive mutex %s @ %s:%d\n",
|
||||
m->lock_object.lo_name, file, line));
|
||||
opts &= ~MTX_RECURSE;
|
||||
m->mtx_recurse++;
|
||||
atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
|
||||
if (LOCK_LOG_TEST(&m->lock_object, opts))
|
||||
CTR1(KTR_LOCK, "_mtx_lock_sleep: %p recursing", m);
|
||||
return;
|
||||
}
|
||||
opts &= ~MTX_RECURSE;
|
||||
|
||||
#ifdef HWPMC_HOOKS
|
||||
PMC_SOFT_CALL( , , lock, failed);
|
||||
|
Loading…
x
Reference in New Issue
Block a user