PERFORCE change 92144 for review
John Baldwin
jhb at FreeBSD.org
Tue Feb 21 13:51:27 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=92144
Change 92144 by jhb at jhb_slimer on 2006/02/21 21:51:15
Axe the callout_wait mutex and instead just use msleep_spin with
the callout_lock spin lock directly.
Affected files ...
.. //depot/projects/smpng/sys/kern/kern_timeout.c#27 edit
Differences ...
==== //depot/projects/smpng/sys/kern/kern_timeout.c#27 (text+ko) ====
@@ -85,31 +85,18 @@
* guarantees that the current callout will not run.
* The softclock() function sets this to 0 before it
* drops callout_lock to acquire c_mtx, and it calls
- * the handler only if curr_cancelled still 0 when
+ * the handler only if curr_cancelled is still 0 after
* c_mtx is successfully acquired.
- * wakeup_ctr - Incremented every time a thread wants to wait
- * for a callout to complete. Modified only when
+ * wakeup_needed - If a thread is waiting on callout_wait, then
+ * wakeup_needed is nonzero. Set only when
* curr_callout is non-NULL.
- * wakeup_needed - If a thread is waiting on callout_wait, then
- * wakeup_needed is nonzero. Increased only when
- * cutt_callout is non-NULL.
+ * callout_wait - Placeholder for a wait channel.
*/
static struct callout *curr_callout;
static int curr_cancelled;
-static int wakeup_ctr;
static int wakeup_needed;
+static int callout_wait;
-/**
- * Locked by callout_wait_lock:
- * callout_wait - If wakeup_needed is set, callout_wait will be
- * triggered after the current callout finishes.
- * wakeup_done_ctr - Set to the current value of wakeup_ctr after
- * callout_wait is triggered.
- */
-static struct mtx callout_wait_lock;
-static struct cv callout_wait;
-static int wakeup_done_ctr;
-
/*
* kern_timeout_callwheel_alloc() - kernel low level callwheel initialization
*
@@ -157,8 +144,6 @@
TAILQ_INIT(&callwheel[i]);
}
mtx_init(&callout_lock, "callout", NULL, MTX_SPIN | MTX_RECURSE);
- mtx_init(&callout_wait_lock, "callout_wait_lock", NULL, MTX_DEF);
- cv_init(&callout_wait, "callout_wait");
}
/*
@@ -188,7 +173,6 @@
int mpcalls;
int mtxcalls;
int gcalls;
- int wakeup_cookie;
#ifdef DIAGNOSTIC
struct bintime bt1, bt2;
struct timespec ts2;
@@ -316,13 +300,7 @@
* There might be someone waiting
* for the callout to complete.
*/
- wakeup_cookie = wakeup_ctr;
- mtx_unlock_spin(&callout_lock);
- mtx_lock(&callout_wait_lock);
- cv_broadcast(&callout_wait);
- wakeup_done_ctr = wakeup_cookie;
- mtx_unlock(&callout_wait_lock);
- mtx_lock_spin(&callout_lock);
+ wakeup(&callout_wait);
wakeup_needed = 0;
}
steps = 0;
@@ -497,7 +475,7 @@
struct callout *c;
int safe;
{
- int use_mtx, wakeup_cookie;
+ int rval, use_mtx;
if (!safe && c->c_mtx != NULL) {
#ifdef notyet /* Some callers do not hold Giant for Giant-locked callouts. */
@@ -520,30 +498,21 @@
mtx_unlock_spin(&callout_lock);
return (0);
}
+ rval = 0;
if (safe) {
/* We need to wait until the callout is finished. */
- wakeup_needed = 1;
- wakeup_cookie = wakeup_ctr++;
- mtx_unlock_spin(&callout_lock);
- mtx_lock(&callout_wait_lock);
-
- /*
- * Check to make sure that softclock() didn't
- * do the wakeup in between our dropping
- * callout_lock and picking up callout_wait_lock
- */
- if (wakeup_cookie - wakeup_done_ctr > 0)
- cv_wait(&callout_wait, &callout_wait_lock);
-
- mtx_unlock(&callout_wait_lock);
+ while (c == curr_callout) {
+ wakeup_needed = 1;
+ msleep_spin(&callout_wait, &callout_lock,
+ "costop", 0);
+ }
} else if (use_mtx && !curr_cancelled) {
/* We can stop the callout before it runs. */
curr_cancelled = 1;
- mtx_unlock_spin(&callout_lock);
- return (1);
- } else
- mtx_unlock_spin(&callout_lock);
- return (0);
+ rval = 1;
+ }
+ mtx_unlock_spin(&callout_lock);
+ return (rval);
}
c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);
More information about the p4-projects
mailing list