summaryrefslogtreecommitdiff
path: root/sys/kern/subr_turnstile.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/subr_turnstile.c')
-rw-r--r--sys/kern/subr_turnstile.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/sys/kern/subr_turnstile.c b/sys/kern/subr_turnstile.c
index 980a5177f1e4..3bb6e949e0e2 100644
--- a/sys/kern/subr_turnstile.c
+++ b/sys/kern/subr_turnstile.c
@@ -397,9 +397,21 @@ turnstile_free(struct turnstile *ts)
}
/*
+ * Lock the turnstile chain associated with the specified lock.
+ */
+void
+turnstile_lock(struct lock_object *lock)
+{
+ struct turnstile_chain *tc;
+
+ tc = TC_LOOKUP(lock);
+ mtx_lock_spin(&tc->tc_lock);
+}
+
+/*
* Look up the turnstile for a lock in the hash table locking the associated
- * turnstile chain along the way. Return with the turnstile chain locked.
- * If no turnstile is found in the hash table, NULL is returned.
+ * turnstile chain along the way. If no turnstile is found in the hash
+ * table, NULL is returned.
*/
struct turnstile *
turnstile_lookup(struct lock_object *lock)
@@ -408,7 +420,7 @@ turnstile_lookup(struct lock_object *lock)
struct turnstile *ts;
tc = TC_LOOKUP(lock);
- mtx_lock_spin(&tc->tc_lock);
+ mtx_assert(&tc->tc_lock, MA_OWNED);
LIST_FOREACH(ts, &tc->tc_turnstiles, ts_hash)
if (ts->ts_lockobj == lock)
return (ts);
@@ -432,13 +444,16 @@ turnstile_release(struct lock_object *lock)
* owner appropriately.
*/
void
-turnstile_claim(struct turnstile *ts)
+turnstile_claim(struct lock_object *lock)
{
struct turnstile_chain *tc;
+ struct turnstile *ts;
struct thread *td, *owner;
- tc = TC_LOOKUP(ts->ts_lockobj);
+ tc = TC_LOOKUP(lock);
mtx_assert(&tc->tc_lock, MA_OWNED);
+ ts = turnstile_lookup(lock);
+ MPASS(ts != NULL);
owner = curthread;
mtx_lock_spin(&td_contested_lock);
@@ -460,16 +475,16 @@ turnstile_claim(struct turnstile *ts)
}
/*
- * Block the current thread on the turnstile ts. This function will context
- * switch and not return until this thread has been woken back up. This
- * function must be called with the appropriate turnstile chain locked and
- * will return with it unlocked.
+ * Block the current thread on the turnstile assicated with 'lock'. This
+ * function will context switch and not return until this thread has been
+ * woken back up. This function must be called with the appropriate
+ * turnstile chain locked and will return with it unlocked.
*/
void
-turnstile_wait(struct turnstile *ts, struct lock_object *lock,
- struct thread *owner)
+turnstile_wait(struct lock_object *lock, struct thread *owner)
{
struct turnstile_chain *tc;
+ struct turnstile *ts;
struct thread *td, *td1;
td = curthread;
@@ -479,7 +494,14 @@ turnstile_wait(struct turnstile *ts, struct lock_object *lock,
MPASS(owner != NULL);
MPASS(owner->td_proc->p_magic == P_MAGIC);
- /* If the passed in turnstile is NULL, use this thread's turnstile. */
+ /* Look up the turnstile associated with the lock 'lock'. */
+ ts = turnstile_lookup(lock);
+
+ /*
+ * If the lock does not already have a turnstile, use this thread's
+ * turnstile. Otherwise insert the current thread into the
+ * turnstile already in use by this lock.
+ */
if (ts == NULL) {
#ifdef TURNSTILE_PROFILING
tc->tc_depth++;