Add a new kernel option MUTEX_WAKE_ALL that changes the mutex unlock code

to awaken all waiters when a contested mutex is released instead of just
the highest priority waiter.  If the various threads are awakened in
sequence then each thread may acquire and release the lock in question
without contention resulting in fewer expensive unlock and lock
operations.  This old behavior of waking just the highest priority is
still used if this option is specified.  Making the algorithm conditional
on a kernel option will allows us to benchmark both cases later and
determine which one should be used by default.

Requested by:	tanimura-san
This commit is contained in:
John Baldwin 2004-04-06 19:12:24 +00:00
parent 94008858f8
commit 535eb30962
2 changed files with 11 additions and 0 deletions

@ -97,6 +97,7 @@ MAC_STUB opt_dontuse.h
MAC_TEST opt_dontuse.h
MD_ROOT opt_md.h
MD_ROOT_SIZE opt_md.h
MUTEX_WAKE_ALL
NSWBUF_MIN opt_swap.h
PANIC_REBOOT_WAIT_TIME opt_panic.h
PPS_SYNC opt_ntp.h

@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include "opt_adaptive_mutexes.h"
#include "opt_ddb.h"
#include "opt_mutex_wake_all.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -469,6 +470,9 @@ _mtx_lock_sleep(struct mtx *m, int opts, const char *file, int line)
continue;
}
#ifdef MUTEX_WAKE_ALL
MPASS(v != MTX_CONTESTED);
#else
/*
* The mutex was marked contested on release. This means that
* there are other threads blocked on it. Grab ownership of
@ -481,6 +485,7 @@ _mtx_lock_sleep(struct mtx *m, int opts, const char *file, int line)
turnstile_claim(ts);
break;
}
#endif
/*
* If the mutex isn't already contested and a failure occurs
@ -643,6 +648,10 @@ _mtx_unlock_sleep(struct mtx *m, int opts, const char *file, int line)
#endif
/* XXX */
td1 = turnstile_head(ts);
#ifdef MUTEX_WAKE_ALL
turnstile_broadcast(ts);
_release_lock_quick(m);
#else
if (turnstile_signal(ts)) {
_release_lock_quick(m);
if (LOCK_LOG_TEST(&m->mtx_object, opts))
@ -653,6 +662,7 @@ _mtx_unlock_sleep(struct mtx *m, int opts, const char *file, int line)
CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p still contested",
m);
}
#endif
turnstile_unpend(ts);
/*