1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

Use wakeup_one to avoid thundering herd.

Tested by: kris
This commit is contained in:
David Xu 2006-05-09 13:00:46 +00:00
parent 0d0b9ff2a4
commit 005efcdb0e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158377

View File

@ -82,8 +82,8 @@ struct umtxq_chain {
struct mtx uc_lock; /* Lock for this chain. */ struct mtx uc_lock; /* Lock for this chain. */
struct umtx_head uc_queue; /* List of sleep queues. */ struct umtx_head uc_queue; /* List of sleep queues. */
#define UCF_BUSY 0x01 #define UCF_BUSY 0x01
#define UCF_WANT 0x02
int uc_flags; int uc_flags;
int uc_waiters;
}; };
#define GOLDEN_RATIO_PRIME 2654404609U #define GOLDEN_RATIO_PRIME 2654404609U
@ -135,6 +135,7 @@ umtxq_init_chains(void *arg __unused)
MTX_DEF | MTX_DUPOK); MTX_DEF | MTX_DUPOK);
LIST_INIT(&umtxq_chains[i].uc_queue); LIST_INIT(&umtxq_chains[i].uc_queue);
umtxq_chains[i].uc_flags = 0; umtxq_chains[i].uc_flags = 0;
umtxq_chains[i].uc_waiters = 0;
} }
} }
@ -166,9 +167,10 @@ umtxq_busy(struct umtx_key *key)
mtx_assert(umtxq_mtx(chain), MA_OWNED); mtx_assert(umtxq_mtx(chain), MA_OWNED);
while (umtxq_chains[chain].uc_flags & UCF_BUSY) { while (umtxq_chains[chain].uc_flags & UCF_BUSY) {
umtxq_chains[chain].uc_flags |= UCF_WANT; umtxq_chains[chain].uc_waiters++;
msleep(&umtxq_chains[chain], umtxq_mtx(chain), msleep(&umtxq_chains[chain], umtxq_mtx(chain),
0, "umtxq_busy", 0); 0, "umtxq_busy", 0);
umtxq_chains[chain].uc_waiters--;
} }
umtxq_chains[chain].uc_flags |= UCF_BUSY; umtxq_chains[chain].uc_flags |= UCF_BUSY;
} }
@ -181,10 +183,8 @@ umtxq_unbusy(struct umtx_key *key)
mtx_assert(umtxq_mtx(chain), MA_OWNED); mtx_assert(umtxq_mtx(chain), MA_OWNED);
KASSERT(umtxq_chains[chain].uc_flags & UCF_BUSY, ("not busy")); KASSERT(umtxq_chains[chain].uc_flags & UCF_BUSY, ("not busy"));
umtxq_chains[chain].uc_flags &= ~UCF_BUSY; umtxq_chains[chain].uc_flags &= ~UCF_BUSY;
if (umtxq_chains[chain].uc_flags & UCF_WANT) { if (umtxq_chains[chain].uc_waiters)
umtxq_chains[chain].uc_flags &= ~UCF_WANT; wakeup_one(&umtxq_chains[chain]);
wakeup(&umtxq_chains[chain]);
}
} }
static inline void static inline void