Date: Wed, 22 Feb 2006 21:18:15 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 92231 for review Message-ID: <200602222118.k1MLIFJW086687@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=92231 Change 92231 by jhb@jhb_slimer on 2006/02/22 21:17:47 Minor nits, axe an extra int we didn't need, and expand some comments. Affected files ... .. //depot/projects/smpng/sys/kern/kern_timeout.c#28 edit Differences ... ==== //depot/projects/smpng/sys/kern/kern_timeout.c#28 (text+ko) ==== @@ -78,8 +78,8 @@ /** * Locked by callout_lock: * curr_callout - If a callout is in progress, it is curr_callout. - * If curr_callout is non-NULL, threads waiting on - * callout_wait will be woken up as soon as the + * If curr_callout is non-NULL, threads waiting in + * callout_drain() will be woken up as soon as the * relevant callout completes. * curr_cancelled - Changing to 1 with both callout_lock and c_mtx held * guarantees that the current callout will not run. @@ -87,14 +87,12 @@ * drops callout_lock to acquire c_mtx, and it calls * the handler only if curr_cancelled is still 0 after * c_mtx is successfully acquired. - * wakeup_needed - If a thread is waiting on callout_wait, then - * wakeup_needed is nonzero. Set only when + * callout_wait - If a thread is waiting in callout_drain(), then + * callout_wait is nonzero. Set only when * curr_callout is non-NULL. - * callout_wait - Placeholder for a wait channel. */ static struct callout *curr_callout; static int curr_cancelled; -static int wakeup_needed; static int callout_wait; /* @@ -246,8 +244,7 @@ */ if (curr_cancelled) { mtx_unlock(c_mtx); - mtx_lock_spin(&callout_lock); - goto done_locked; + goto skip; } /* The callout cannot be stopped now. */ curr_cancelled = 1; @@ -292,16 +289,16 @@ #endif if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0) mtx_unlock(c_mtx); + skip: mtx_lock_spin(&callout_lock); -done_locked: curr_callout = NULL; - if (wakeup_needed) { + if (callout_wait) { /* - * There might be someone waiting + * There is someone waiting * for the callout to complete. */ wakeup(&callout_wait); - wakeup_needed = 0; + callout_wait = 0; } steps = 0; c = nextsoftcheck; @@ -423,7 +420,7 @@ */ if (c->c_mtx != NULL && !curr_cancelled) cancelled = curr_cancelled = 1; - if (wakeup_needed) { + if (callout_wait) { /* * Someone has called callout_drain to kill this * callout. Don't reschedule. @@ -490,24 +487,38 @@ mtx_lock_spin(&callout_lock); /* - * Don't attempt to delete a callout that's not on the queue. + * If the callout isn't pending, it's not on the queue, so + * don't attempt to remove it from the queue. We can try + * to stop it by other means however. */ if (!(c->c_flags & CALLOUT_PENDING)) { c->c_flags &= ~CALLOUT_ACTIVE; - if (c != curr_callout) { - mtx_unlock_spin(&callout_lock); - return (0); - } - rval = 0; - if (safe) { - /* We need to wait until the callout is finished. */ + + /* + * If it wasn't on the queue and it isn't the current + * callout, then we can't stop it, so just bail. + */ + if (c != curr_callout) + rval = 0; + else if (safe) { + /* + * The current callout is running (or just about to + * run) and blocking is allowed, so just wait for + * the current invocation to finish. + */ while (c == curr_callout) { - wakeup_needed = 1; + callout_wait = 1; msleep_spin(&callout_wait, &callout_lock, - "costop", 0); + "codrain", 0); } + rval = 0; } else if (use_mtx && !curr_cancelled) { - /* We can stop the callout before it runs. */ + /* + * The current callout is waiting for it's mutex + * which we hold. Cancel the callout and return. + * After our caller drops the mutex, the callout + * will be skipped in softclock(). + */ curr_cancelled = 1; rval = 1; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200602222118.k1MLIFJW086687>