diff options
author | jeff <jeff@FreeBSD.org> | 2008-02-06 01:02:13 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2008-02-06 01:02:13 +0000 |
commit | 77ea5a24c756bd86d2880b544e3ae2c4fc85de96 (patch) | |
tree | 5bef34d7805971aa4bece9b058097a604c9778de /sys/kern/subr_turnstile.c | |
parent | 2656e4d699d3e85d13d9ce6ed95c7a71f1f72563 (diff) | |
download | FreeBSD-src-77ea5a24c756bd86d2880b544e3ae2c4fc85de96.zip FreeBSD-src-77ea5a24c756bd86d2880b544e3ae2c4fc85de96.tar.gz |
Adaptive spinning in write path with readers and writer starvation avoidance.
- Move recursion checking into rwlock inlines to free a bit for use with
adaptive spinners.
- Clear the RW_LOCK_WRITE_SPINNERS flag whenever the lock state changes
causing write spinners to restart their loop.
- Write spinners are limited by a count while readers hold the lock as
there is no way to know for certain whether readers are running still.
- In the read path block if there are write waiters or spinners to avoid
starving writers. Use a new per-thread count, td_rw_rlocks, to skip
starvation avoidance if it might cause a deadlock.
- Remove or change invalid assertions in turnstiles.
Reviewed by: attilio (developed parts of the patch as well)
Sponsored by: Nokia
Diffstat (limited to 'sys/kern/subr_turnstile.c')
-rw-r--r-- | sys/kern/subr_turnstile.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/sys/kern/subr_turnstile.c b/sys/kern/subr_turnstile.c index 269faca..aa674ca 100644 --- a/sys/kern/subr_turnstile.c +++ b/sys/kern/subr_turnstile.c @@ -674,8 +674,6 @@ turnstile_wait(struct turnstile *ts, struct thread *owner, int queue) td = curthread; mtx_assert(&ts->ts_lock, MA_OWNED); - if (queue == TS_SHARED_QUEUE) - MPASS(owner != NULL); if (owner) MPASS(owner->td_proc->p_magic == P_MAGIC); MPASS(queue == TS_SHARED_QUEUE || queue == TS_EXCLUSIVE_QUEUE); @@ -766,8 +764,7 @@ turnstile_signal(struct turnstile *ts, int queue) MPASS(ts != NULL); mtx_assert(&ts->ts_lock, MA_OWNED); MPASS(curthread->td_proc->p_magic == P_MAGIC); - MPASS(ts->ts_owner == curthread || - (queue == TS_EXCLUSIVE_QUEUE && ts->ts_owner == NULL)); + MPASS(ts->ts_owner == curthread || ts->ts_owner == NULL); MPASS(queue == TS_SHARED_QUEUE || queue == TS_EXCLUSIVE_QUEUE); /* @@ -818,8 +815,7 @@ turnstile_broadcast(struct turnstile *ts, int queue) MPASS(ts != NULL); mtx_assert(&ts->ts_lock, MA_OWNED); MPASS(curthread->td_proc->p_magic == P_MAGIC); - MPASS(ts->ts_owner == curthread || - (queue == TS_EXCLUSIVE_QUEUE && ts->ts_owner == NULL)); + MPASS(ts->ts_owner == curthread || ts->ts_owner == NULL); /* * We must have the chain locked so that we can remove the empty * turnstile from the hash queue. @@ -869,8 +865,7 @@ turnstile_unpend(struct turnstile *ts, int owner_type) MPASS(ts != NULL); mtx_assert(&ts->ts_lock, MA_OWNED); - MPASS(ts->ts_owner == curthread || - (owner_type == TS_SHARED_LOCK && ts->ts_owner == NULL)); + MPASS(ts->ts_owner == curthread || ts->ts_owner == NULL); MPASS(!TAILQ_EMPTY(&ts->ts_pending)); /* |