Date: Tue, 21 Feb 2006 21:51:18 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 92144 for review Message-ID: <200602212151.k1LLpHPr078269@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=92144 Change 92144 by jhb@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200602212151.k1LLpHPr078269>