From 6e24e61797e51837f86c76c47cd4d439e09b18a3 Mon Sep 17 00:00:00 2001 From: David Xu Date: Fri, 30 May 2008 02:18:54 +0000 Subject: [PATCH] Use a seperated hash table for mutex and rwlock, avoid wasting some time on walking through idle threads sleeping on condition variables. --- sys/kern/kern_umtx.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 85c5b55aac0a..8e5fcab3b867 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -58,12 +58,12 @@ __FBSDID("$FreeBSD$"); #include #endif -#define TYPE_SIMPLE_LOCK 0 -#define TYPE_SIMPLE_WAIT 1 -#define TYPE_NORMAL_UMUTEX 2 -#define TYPE_PI_UMUTEX 3 -#define TYPE_PP_UMUTEX 4 -#define TYPE_CV 5 +#define TYPE_SIMPLE_WAIT 0 +#define TYPE_CV 1 +#define TYPE_SIMPLE_LOCK 2 +#define TYPE_NORMAL_UMUTEX 3 +#define TYPE_PI_UMUTEX 4 +#define TYPE_PP_UMUTEX 5 #define TYPE_RWLOCK 6 /* Key to represent a unique userland synchronous object */ @@ -191,7 +191,7 @@ struct umtxq_chain { #define BUSY_SPINS 200 static uma_zone_t umtx_pi_zone; -static struct umtxq_chain umtxq_chains[UMTX_CHAINS]; +static struct umtxq_chain umtxq_chains[2][UMTX_CHAINS]; static MALLOC_DEFINE(M_UMTX, "umtx", "UMTX queue memory"); static int umtx_pi_allocated; @@ -232,18 +232,20 @@ static struct mtx umtx_lock; static void umtxq_sysinit(void *arg __unused) { - int i; + int i, j; umtx_pi_zone = uma_zcreate("umtx pi", sizeof(struct umtx_pi), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); - for (i = 0; i < UMTX_CHAINS; ++i) { - mtx_init(&umtxq_chains[i].uc_lock, "umtxql", NULL, - MTX_DEF | MTX_DUPOK); - TAILQ_INIT(&umtxq_chains[i].uc_queue[0]); - TAILQ_INIT(&umtxq_chains[i].uc_queue[1]); - TAILQ_INIT(&umtxq_chains[i].uc_pi_list); - umtxq_chains[i].uc_busy = 0; - umtxq_chains[i].uc_waiters = 0; + for (i = 0; i < 2; ++i) { + for (j = 0; j < UMTX_CHAINS; ++j) { + mtx_init(&umtxq_chains[i][j].uc_lock, "umtxql", NULL, + MTX_DEF | MTX_DUPOK); + TAILQ_INIT(&umtxq_chains[i][j].uc_queue[0]); + TAILQ_INIT(&umtxq_chains[i][j].uc_queue[1]); + TAILQ_INIT(&umtxq_chains[i][j].uc_pi_list); + umtxq_chains[i][j].uc_busy = 0; + umtxq_chains[i][j].uc_waiters = 0; + } } mtx_init(&umtx_lock, "umtx lock", NULL, MTX_SPIN); EVENTHANDLER_REGISTER(process_exec, umtx_exec_hook, NULL, @@ -285,7 +287,9 @@ umtx_key_match(const struct umtx_key *k1, const struct umtx_key *k2) static inline struct umtxq_chain * umtxq_getchain(struct umtx_key *key) { - return (&umtxq_chains[key->hash]); + if (key->type <= TYPE_CV) + return (&umtxq_chains[1][key->hash]); + return (&umtxq_chains[0][key->hash]); } /*