kern_timeout.c revision 141428
11541Srgrimes/*-
21541Srgrimes * Copyright (c) 1982, 1986, 1991, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes * (c) UNIX System Laboratories, Inc.
51541Srgrimes * All or some portions of this file are derived from material licensed
61541Srgrimes * to the University of California by American Telephone and Telegraph
71541Srgrimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with
81541Srgrimes * the permission of UNIX System Laboratories, Inc.
91541Srgrimes *
101541Srgrimes * Redistribution and use in source and binary forms, with or without
111541Srgrimes * modification, are permitted provided that the following conditions
121541Srgrimes * are met:
131541Srgrimes * 1. Redistributions of source code must retain the above copyright
141541Srgrimes *    notice, this list of conditions and the following disclaimer.
151541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
161541Srgrimes *    notice, this list of conditions and the following disclaimer in the
171541Srgrimes *    documentation and/or other materials provided with the distribution.
181541Srgrimes * 4. Neither the name of the University nor the names of its contributors
191541Srgrimes *    may be used to endorse or promote products derived from this software
201541Srgrimes *    without specific prior written permission.
211541Srgrimes *
221541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
231541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
241541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
251541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
261541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
271541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
281541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
291541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
301541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
311541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
321541Srgrimes * SUCH DAMAGE.
331541Srgrimes *
3444510Swollman *	From: @(#)kern_clock.c	8.5 (Berkeley) 1/21/94
351541Srgrimes */
361541Srgrimes
37116182Sobrien#include <sys/cdefs.h>
38116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_timeout.c 141428 2005-02-07 02:47:33Z iedowse $");
39116182Sobrien
401541Srgrimes#include <sys/param.h>
411541Srgrimes#include <sys/systm.h>
4233392Sphk#include <sys/callout.h>
43127969Scperciva#include <sys/condvar.h>
441541Srgrimes#include <sys/kernel.h>
45133229Srwatson#include <sys/ktr.h>
4674914Sjhb#include <sys/lock.h>
4768840Sjhb#include <sys/mutex.h>
48115810Sphk#include <sys/sysctl.h>
491541Srgrimes
50115810Sphkstatic int avg_depth;
51115810SphkSYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0,
52115810Sphk    "Average number of items examined per softclock call. Units = 1/1000");
53115810Sphkstatic int avg_gcalls;
54115810SphkSYSCTL_INT(_debug, OID_AUTO, to_avg_gcalls, CTLFLAG_RD, &avg_gcalls, 0,
55115810Sphk    "Average number of Giant callouts made per softclock call. Units = 1/1000");
56141428Siedowsestatic int avg_mtxcalls;
57141428SiedowseSYSCTL_INT(_debug, OID_AUTO, to_avg_mtxcalls, CTLFLAG_RD, &avg_mtxcalls, 0,
58141428Siedowse    "Average number of mtx callouts made per softclock call. Units = 1/1000");
59115810Sphkstatic int avg_mpcalls;
60115810SphkSYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0,
61115810Sphk    "Average number of MP callouts made per softclock call. Units = 1/1000");
6233392Sphk/*
6333392Sphk * TODO:
6433392Sphk *	allocate more timeout table slots when table overflows.
6533392Sphk */
6633392Sphk
6733392Sphk/* Exported to machdep.c and/or kern_clock.c.  */
6829680Sgibbsstruct callout *callout;
6929680Sgibbsstruct callout_list callfree;
7029680Sgibbsint callwheelsize, callwheelbits, callwheelmask;
7129680Sgibbsstruct callout_tailq *callwheel;
7233392Sphkint softticks;			/* Like ticks, but for softclock(). */
73116606Sphkstruct mtx callout_lock;
74122585Smckusick#ifdef DIAGNOSTIC
75122761Sphkstruct mtx dont_sleep_in_callout;
76122585Smckusick#endif
772112Swollman
7829680Sgibbsstatic struct callout *nextsoftcheck;	/* Next callout to be checked. */
79128024Scperciva
80139831Scperciva/**
81127969Scperciva * Locked by callout_lock:
82127969Scperciva *   curr_callout    - If a callout is in progress, it is curr_callout.
83127969Scperciva *                     If curr_callout is non-NULL, threads waiting on
84127969Scperciva *                     callout_wait will be woken up as soon as the
85127969Scperciva *                     relevant callout completes.
86141428Siedowse *   curr_cancelled  - Changing to 1 with both callout_lock and c_mtx held
87141428Siedowse *                     guarantees that the current callout will not run.
88141428Siedowse *                     The softclock() function sets this to 0 before it
89141428Siedowse *                     drops callout_lock to acquire c_mtx, and it calls
90141428Siedowse *                     the handler only if curr_cancelled still 0 when
91141428Siedowse *                     c_mtx is successfully acquired.
92128024Scperciva *   wakeup_ctr      - Incremented every time a thread wants to wait
93128024Scperciva *                     for a callout to complete.  Modified only when
94128024Scperciva *                     curr_callout is non-NULL.
95127969Scperciva *   wakeup_needed   - If a thread is waiting on callout_wait, then
96127969Scperciva *                     wakeup_needed is nonzero.  Increased only when
97127969Scperciva *                     cutt_callout is non-NULL.
98127969Scperciva */
99127969Scpercivastatic struct callout *curr_callout;
100141428Siedowsestatic int curr_cancelled;
101128024Scpercivastatic int wakeup_ctr;
102127969Scpercivastatic int wakeup_needed;
103128024Scperciva
104139831Scperciva/**
105127969Scperciva * Locked by callout_wait_lock:
106127969Scperciva *   callout_wait    - If wakeup_needed is set, callout_wait will be
107127969Scperciva *                     triggered after the current callout finishes.
108127969Scperciva *   wakeup_done_ctr - Set to the current value of wakeup_ctr after
109127969Scperciva *                     callout_wait is triggered.
110127969Scperciva */
111127969Scpercivastatic struct mtx callout_wait_lock;
112127969Scpercivastatic struct cv callout_wait;
113127969Scpercivastatic int wakeup_done_ctr;
1141541Srgrimes
1151541Srgrimes/*
11682127Sdillon * kern_timeout_callwheel_alloc() - kernel low level callwheel initialization
11782127Sdillon *
11882127Sdillon *	This code is called very early in the kernel initialization sequence,
11982127Sdillon *	and may be called more then once.
12082127Sdillon */
12182127Sdilloncaddr_t
12282127Sdillonkern_timeout_callwheel_alloc(caddr_t v)
12382127Sdillon{
12482127Sdillon	/*
12582127Sdillon	 * Calculate callout wheel size
12682127Sdillon	 */
12782127Sdillon	for (callwheelsize = 1, callwheelbits = 0;
12882127Sdillon	     callwheelsize < ncallout;
12982127Sdillon	     callwheelsize <<= 1, ++callwheelbits)
13082127Sdillon		;
13182127Sdillon	callwheelmask = callwheelsize - 1;
13282127Sdillon
13382127Sdillon	callout = (struct callout *)v;
13482127Sdillon	v = (caddr_t)(callout + ncallout);
13582127Sdillon	callwheel = (struct callout_tailq *)v;
13682127Sdillon	v = (caddr_t)(callwheel + callwheelsize);
13782127Sdillon	return(v);
13882127Sdillon}
13982127Sdillon
14082127Sdillon/*
14182127Sdillon * kern_timeout_callwheel_init() - initialize previously reserved callwheel
14282127Sdillon *				   space.
14382127Sdillon *
14482127Sdillon *	This code is called just once, after the space reserved for the
14582127Sdillon *	callout wheel has been finalized.
14682127Sdillon */
14782127Sdillonvoid
14882127Sdillonkern_timeout_callwheel_init(void)
14982127Sdillon{
15082127Sdillon	int i;
15182127Sdillon
15282127Sdillon	SLIST_INIT(&callfree);
15382127Sdillon	for (i = 0; i < ncallout; i++) {
15482127Sdillon		callout_init(&callout[i], 0);
15582127Sdillon		callout[i].c_flags = CALLOUT_LOCAL_ALLOC;
15682127Sdillon		SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle);
15782127Sdillon	}
15882127Sdillon	for (i = 0; i < callwheelsize; i++) {
15982127Sdillon		TAILQ_INIT(&callwheel[i]);
16082127Sdillon	}
16193818Sjhb	mtx_init(&callout_lock, "callout", NULL, MTX_SPIN | MTX_RECURSE);
162122585Smckusick#ifdef DIAGNOSTIC
163122761Sphk	mtx_init(&dont_sleep_in_callout, "dont_sleep_in_callout", NULL, MTX_DEF);
164122585Smckusick#endif
165127969Scperciva	mtx_init(&callout_wait_lock, "callout_wait_lock", NULL, MTX_DEF);
166127969Scperciva	cv_init(&callout_wait, "callout_wait");
16782127Sdillon}
16882127Sdillon
16982127Sdillon/*
17029680Sgibbs * The callout mechanism is based on the work of Adam M. Costello and
17129680Sgibbs * George Varghese, published in a technical report entitled "Redesigning
17229680Sgibbs * the BSD Callout and Timer Facilities" and modified slightly for inclusion
17329680Sgibbs * in FreeBSD by Justin T. Gibbs.  The original work on the data structures
174128630Shmp * used in this implementation was published by G. Varghese and T. Lauck in
17529680Sgibbs * the paper "Hashed and Hierarchical Timing Wheels: Data Structures for
17629680Sgibbs * the Efficient Implementation of a Timer Facility" in the Proceedings of
17729680Sgibbs * the 11th ACM Annual Symposium on Operating Systems Principles,
17829680Sgibbs * Austin, Texas Nov 1987.
17929680Sgibbs */
18032388Sphk
18129680Sgibbs/*
1821541Srgrimes * Software (low priority) clock interrupt.
1831541Srgrimes * Run periodic events from timeout queue.
1841541Srgrimes */
1851541Srgrimesvoid
18667551Sjhbsoftclock(void *dummy)
1871541Srgrimes{
188102936Sphk	struct callout *c;
189102936Sphk	struct callout_tailq *bucket;
190102936Sphk	int curticks;
191102936Sphk	int steps;	/* #steps since we last allowed interrupts */
192115810Sphk	int depth;
193115810Sphk	int mpcalls;
194141428Siedowse	int mtxcalls;
195115810Sphk	int gcalls;
196127969Scperciva	int wakeup_cookie;
197122585Smckusick#ifdef DIAGNOSTIC
198122585Smckusick	struct bintime bt1, bt2;
199122585Smckusick	struct timespec ts2;
200122585Smckusick	static uint64_t maxdt = 36893488147419102LL;	/* 2 msec */
201123254Sphk	static timeout_t *lastfunc;
202122585Smckusick#endif
2031541Srgrimes
20433392Sphk#ifndef MAX_SOFTCLOCK_STEPS
20533392Sphk#define MAX_SOFTCLOCK_STEPS 100 /* Maximum allowed value of steps. */
20633392Sphk#endif /* MAX_SOFTCLOCK_STEPS */
20729680Sgibbs
208115810Sphk	mpcalls = 0;
209141428Siedowse	mtxcalls = 0;
210115810Sphk	gcalls = 0;
211115810Sphk	depth = 0;
21229680Sgibbs	steps = 0;
21372200Sbmilekic	mtx_lock_spin(&callout_lock);
21429680Sgibbs	while (softticks != ticks) {
21529805Sgibbs		softticks++;
21629805Sgibbs		/*
21729805Sgibbs		 * softticks may be modified by hard clock, so cache
21829805Sgibbs		 * it while we work on a given bucket.
21929805Sgibbs		 */
22029805Sgibbs		curticks = softticks;
22129805Sgibbs		bucket = &callwheel[curticks & callwheelmask];
22229805Sgibbs		c = TAILQ_FIRST(bucket);
22329680Sgibbs		while (c) {
224115810Sphk			depth++;
22529805Sgibbs			if (c->c_time != curticks) {
22629680Sgibbs				c = TAILQ_NEXT(c, c_links.tqe);
22729680Sgibbs				++steps;
22829680Sgibbs				if (steps >= MAX_SOFTCLOCK_STEPS) {
22929680Sgibbs					nextsoftcheck = c;
23029805Sgibbs					/* Give interrupts a chance. */
23172200Sbmilekic					mtx_unlock_spin(&callout_lock);
23281370Sjhb					;	/* nothing */
23372200Sbmilekic					mtx_lock_spin(&callout_lock);
23429680Sgibbs					c = nextsoftcheck;
23529680Sgibbs					steps = 0;
23629680Sgibbs				}
23729680Sgibbs			} else {
23829680Sgibbs				void (*c_func)(void *);
23929680Sgibbs				void *c_arg;
240141428Siedowse				struct mtx *c_mtx;
24168889Sjake				int c_flags;
24229680Sgibbs
24329680Sgibbs				nextsoftcheck = TAILQ_NEXT(c, c_links.tqe);
24429805Sgibbs				TAILQ_REMOVE(bucket, c, c_links.tqe);
24529680Sgibbs				c_func = c->c_func;
24629680Sgibbs				c_arg = c->c_arg;
247141428Siedowse				c_mtx = c->c_mtx;
24868889Sjake				c_flags = c->c_flags;
24944510Swollman				if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
250140489Scperciva					c->c_func = NULL;
25144510Swollman					c->c_flags = CALLOUT_LOCAL_ALLOC;
25244510Swollman					SLIST_INSERT_HEAD(&callfree, c,
25344510Swollman							  c_links.sle);
25444510Swollman				} else {
25544510Swollman					c->c_flags =
25650673Sjlemon					    (c->c_flags & ~CALLOUT_PENDING);
25744510Swollman				}
258127969Scperciva				curr_callout = c;
259141428Siedowse				curr_cancelled = 0;
26072200Sbmilekic				mtx_unlock_spin(&callout_lock);
261141428Siedowse				if (c_mtx != NULL) {
262141428Siedowse					mtx_lock(c_mtx);
263141428Siedowse					/*
264141428Siedowse					 * The callout may have been cancelled
265141428Siedowse					 * while we switched locks.
266141428Siedowse					 */
267141428Siedowse					if (curr_cancelled) {
268141428Siedowse						mtx_unlock(c_mtx);
269141428Siedowse						mtx_lock_spin(&callout_lock);
270141428Siedowse						goto done_locked;
271141428Siedowse					}
272141428Siedowse					/* The callout cannot be stopped now. */
273141428Siedowse					curr_cancelled = 1;
274141428Siedowse
275141428Siedowse					if (c_mtx == &Giant) {
276141428Siedowse						gcalls++;
277141428Siedowse						CTR1(KTR_CALLOUT, "callout %p",
278141428Siedowse						    c_func);
279141428Siedowse					} else {
280141428Siedowse						mtxcalls++;
281141428Siedowse						CTR1(KTR_CALLOUT,
282141428Siedowse						    "callout mtx %p",
283141428Siedowse						    c_func);
284141428Siedowse					}
285115810Sphk				} else {
286115810Sphk					mpcalls++;
287133229Srwatson					CTR1(KTR_CALLOUT, "callout mpsafe %p",
288133229Srwatson					    c_func);
289115810Sphk				}
290122585Smckusick#ifdef DIAGNOSTIC
291122585Smckusick				binuptime(&bt1);
292122761Sphk				mtx_lock(&dont_sleep_in_callout);
293122585Smckusick#endif
29429680Sgibbs				c_func(c_arg);
295122585Smckusick#ifdef DIAGNOSTIC
296122761Sphk				mtx_unlock(&dont_sleep_in_callout);
297122585Smckusick				binuptime(&bt2);
298122585Smckusick				bintime_sub(&bt2, &bt1);
299122585Smckusick				if (bt2.frac > maxdt) {
300123254Sphk					if (lastfunc != c_func ||
301123254Sphk					    bt2.frac > maxdt * 2) {
302123254Sphk						bintime2timespec(&bt2, &ts2);
303123254Sphk						printf(
304123254Sphk			"Expensive timeout(9) function: %p(%p) %jd.%09ld s\n",
305123254Sphk						    c_func, c_arg,
306123254Sphk						    (intmax_t)ts2.tv_sec,
307123254Sphk						    ts2.tv_nsec);
308123254Sphk					}
309122585Smckusick					maxdt = bt2.frac;
310123254Sphk					lastfunc = c_func;
311122585Smckusick				}
312122585Smckusick#endif
313141428Siedowse				if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0)
314141428Siedowse					mtx_unlock(c_mtx);
31572200Sbmilekic				mtx_lock_spin(&callout_lock);
316141428Siedowsedone_locked:
317127969Scperciva				curr_callout = NULL;
318127969Scperciva				if (wakeup_needed) {
319127969Scperciva					/*
320127969Scperciva					 * There might be someone waiting
321127969Scperciva					 * for the callout to complete.
322127969Scperciva					 */
323127969Scperciva					wakeup_cookie = wakeup_ctr;
324127969Scperciva					mtx_unlock_spin(&callout_lock);
325127969Scperciva					mtx_lock(&callout_wait_lock);
326127969Scperciva					cv_broadcast(&callout_wait);
327127969Scperciva					wakeup_done_ctr = wakeup_cookie;
328127969Scperciva					mtx_unlock(&callout_wait_lock);
329127969Scperciva					mtx_lock_spin(&callout_lock);
330127969Scperciva					wakeup_needed = 0;
331128024Scperciva				}
33229680Sgibbs				steps = 0;
33329680Sgibbs				c = nextsoftcheck;
33429680Sgibbs			}
33529680Sgibbs		}
3361541Srgrimes	}
337115810Sphk	avg_depth += (depth * 1000 - avg_depth) >> 8;
338115810Sphk	avg_mpcalls += (mpcalls * 1000 - avg_mpcalls) >> 8;
339141428Siedowse	avg_mtxcalls += (mtxcalls * 1000 - avg_mtxcalls) >> 8;
340115810Sphk	avg_gcalls += (gcalls * 1000 - avg_gcalls) >> 8;
34129680Sgibbs	nextsoftcheck = NULL;
34272200Sbmilekic	mtx_unlock_spin(&callout_lock);
3431541Srgrimes}
3441541Srgrimes
3451541Srgrimes/*
3461541Srgrimes * timeout --
3471541Srgrimes *	Execute a function after a specified length of time.
3481541Srgrimes *
3491541Srgrimes * untimeout --
3501541Srgrimes *	Cancel previous timeout function call.
3511541Srgrimes *
35229680Sgibbs * callout_handle_init --
35329680Sgibbs *	Initialize a handle so that using it with untimeout is benign.
35429680Sgibbs *
3551541Srgrimes *	See AT&T BCI Driver Reference Manual for specification.  This
35629680Sgibbs *	implementation differs from that one in that although an
35729680Sgibbs *	identification value is returned from timeout, the original
35829680Sgibbs *	arguments to timeout as well as the identifier are used to
35929680Sgibbs *	identify entries for untimeout.
3601541Srgrimes */
36129680Sgibbsstruct callout_handle
36229680Sgibbstimeout(ftn, arg, to_ticks)
36333824Sbde	timeout_t *ftn;
3641541Srgrimes	void *arg;
36569147Sjlemon	int to_ticks;
3661541Srgrimes{
36729680Sgibbs	struct callout *new;
36829680Sgibbs	struct callout_handle handle;
3691541Srgrimes
37072200Sbmilekic	mtx_lock_spin(&callout_lock);
3711541Srgrimes
3721541Srgrimes	/* Fill in the next free callout structure. */
37329680Sgibbs	new = SLIST_FIRST(&callfree);
37429680Sgibbs	if (new == NULL)
37529680Sgibbs		/* XXX Attempt to malloc first */
3761541Srgrimes		panic("timeout table full");
37729680Sgibbs	SLIST_REMOVE_HEAD(&callfree, c_links.sle);
37844510Swollman
37944510Swollman	callout_reset(new, to_ticks, ftn, arg);
3801541Srgrimes
38144510Swollman	handle.callout = new;
38272200Sbmilekic	mtx_unlock_spin(&callout_lock);
38329680Sgibbs	return (handle);
3841541Srgrimes}
3851541Srgrimes
3861541Srgrimesvoid
38729680Sgibbsuntimeout(ftn, arg, handle)
38833824Sbde	timeout_t *ftn;
3891541Srgrimes	void *arg;
39029680Sgibbs	struct callout_handle handle;
3911541Srgrimes{
3921541Srgrimes
39329680Sgibbs	/*
39429680Sgibbs	 * Check for a handle that was initialized
39529680Sgibbs	 * by callout_handle_init, but never used
39629680Sgibbs	 * for a real timeout.
39729680Sgibbs	 */
39829680Sgibbs	if (handle.callout == NULL)
39929680Sgibbs		return;
40029680Sgibbs
40172200Sbmilekic	mtx_lock_spin(&callout_lock);
40244510Swollman	if (handle.callout->c_func == ftn && handle.callout->c_arg == arg)
40344510Swollman		callout_stop(handle.callout);
40472200Sbmilekic	mtx_unlock_spin(&callout_lock);
4051541Srgrimes}
4061541Srgrimes
40724101Sbdevoid
40829680Sgibbscallout_handle_init(struct callout_handle *handle)
40929680Sgibbs{
41029680Sgibbs	handle->callout = NULL;
41129680Sgibbs}
41229680Sgibbs
41344510Swollman/*
41444510Swollman * New interface; clients allocate their own callout structures.
41544510Swollman *
41644510Swollman * callout_reset() - establish or change a timeout
41744510Swollman * callout_stop() - disestablish a timeout
41844510Swollman * callout_init() - initialize a callout structure so that it can
41944510Swollman *	safely be passed to callout_reset() and callout_stop()
42044510Swollman *
42150673Sjlemon * <sys/callout.h> defines three convenience macros:
42244510Swollman *
423140487Scperciva * callout_active() - returns truth if callout has not been stopped,
424140487Scperciva *	drained, or deactivated since the last time the callout was
425140487Scperciva *	reset.
42650673Sjlemon * callout_pending() - returns truth if callout is still waiting for timeout
42750673Sjlemon * callout_deactivate() - marks the callout as having been serviced
42844510Swollman */
42944510Swollmanvoid
43069147Sjlemoncallout_reset(c, to_ticks, ftn, arg)
43144510Swollman	struct	callout *c;
43244510Swollman	int	to_ticks;
43392723Salfred	void	(*ftn)(void *);
43444510Swollman	void	*arg;
43544510Swollman{
43644510Swollman
437141428Siedowse#ifdef notyet /* Some callers of timeout() do not hold Giant. */
438141428Siedowse	if (c->c_mtx != NULL)
439141428Siedowse		mtx_assert(c->c_mtx, MA_OWNED);
440141428Siedowse#endif
441141428Siedowse
44272200Sbmilekic	mtx_lock_spin(&callout_lock);
443141428Siedowse	if (c == curr_callout) {
444127969Scperciva		/*
445127969Scperciva		 * We're being asked to reschedule a callout which is
446141428Siedowse		 * currently in progress.  If there is a mutex then we
447141428Siedowse		 * can cancel the callout if it has not really started.
448127969Scperciva		 */
449141428Siedowse		if (c->c_mtx != NULL && !curr_cancelled)
450141428Siedowse			curr_cancelled = 1;
451141428Siedowse		if (wakeup_needed) {
452141428Siedowse			/*
453141428Siedowse			 * Someone has called callout_drain to kill this
454141428Siedowse			 * callout.  Don't reschedule.
455141428Siedowse			 */
456141428Siedowse			mtx_unlock_spin(&callout_lock);
457141428Siedowse			return;
458141428Siedowse		}
459128024Scperciva	}
460133190Scperciva	if (c->c_flags & CALLOUT_PENDING) {
461133190Scperciva		if (nextsoftcheck == c) {
462133190Scperciva			nextsoftcheck = TAILQ_NEXT(c, c_links.tqe);
463133190Scperciva		}
464133190Scperciva		TAILQ_REMOVE(&callwheel[c->c_time & callwheelmask], c,
465133190Scperciva		    c_links.tqe);
46644510Swollman
467133190Scperciva		/*
468133190Scperciva		 * Part of the normal "stop a pending callout" process
469133190Scperciva		 * is to clear the CALLOUT_ACTIVE and CALLOUT_PENDING
470133190Scperciva		 * flags.  We're not going to bother doing that here,
471133190Scperciva		 * because we're going to be setting those flags ten lines
472133190Scperciva		 * after this point, and we're holding callout_lock
473133190Scperciva		 * between now and then.
474133190Scperciva		 */
475133190Scperciva	}
476133190Scperciva
47744510Swollman	/*
47881370Sjhb	 * We could unlock callout_lock here and lock it again before the
47981370Sjhb	 * TAILQ_INSERT_TAIL, but there's no point since doing this setup
48081370Sjhb	 * doesn't take much time.
48144510Swollman	 */
48244510Swollman	if (to_ticks <= 0)
48344510Swollman		to_ticks = 1;
48444510Swollman
48544510Swollman	c->c_arg = arg;
48669147Sjlemon	c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING);
48744510Swollman	c->c_func = ftn;
48844510Swollman	c->c_time = ticks + to_ticks;
48944510Swollman	TAILQ_INSERT_TAIL(&callwheel[c->c_time & callwheelmask],
49044510Swollman			  c, c_links.tqe);
49172200Sbmilekic	mtx_unlock_spin(&callout_lock);
49244510Swollman}
49344510Swollman
49481481Sjhbint
495127969Scperciva_callout_stop_safe(c, safe)
496127969Scperciva	struct	callout *c;
497127969Scperciva	int	safe;
498127969Scperciva{
499141428Siedowse	int use_mtx, wakeup_cookie;
500127969Scperciva
501141428Siedowse	if (!safe && c->c_mtx != NULL) {
502141428Siedowse#ifdef notyet /* Some callers do not hold Giant for Giant-locked callouts. */
503141428Siedowse		mtx_assert(c->c_mtx, MA_OWNED);
504141428Siedowse		use_mtx = 1;
505141428Siedowse#else
506141428Siedowse		use_mtx = mtx_owned(c->c_mtx);
507141428Siedowse#endif
508141428Siedowse	} else {
509141428Siedowse		use_mtx = 0;
510141428Siedowse	}
511141428Siedowse
51272200Sbmilekic	mtx_lock_spin(&callout_lock);
51344510Swollman	/*
51444510Swollman	 * Don't attempt to delete a callout that's not on the queue.
51544510Swollman	 */
51644510Swollman	if (!(c->c_flags & CALLOUT_PENDING)) {
51750673Sjlemon		c->c_flags &= ~CALLOUT_ACTIVE;
518141428Siedowse		if (c != curr_callout) {
519141428Siedowse			mtx_unlock_spin(&callout_lock);
520141428Siedowse			return (0);
521141428Siedowse		}
522141428Siedowse		if (safe) {
523128024Scperciva			/* We need to wait until the callout is finished. */
524127969Scperciva			wakeup_needed = 1;
525127969Scperciva			wakeup_cookie = wakeup_ctr++;
526127969Scperciva			mtx_unlock_spin(&callout_lock);
527127969Scperciva			mtx_lock(&callout_wait_lock);
528128024Scperciva
529127969Scperciva			/*
530127969Scperciva			 * Check to make sure that softclock() didn't
531127969Scperciva			 * do the wakeup in between our dropping
532127969Scperciva			 * callout_lock and picking up callout_wait_lock
533127969Scperciva			 */
534127969Scperciva			if (wakeup_cookie - wakeup_done_ctr > 0)
535127969Scperciva				cv_wait(&callout_wait, &callout_wait_lock);
536127969Scperciva
537127969Scperciva			mtx_unlock(&callout_wait_lock);
538141428Siedowse		} else if (use_mtx && !curr_cancelled) {
539141428Siedowse			/* We can stop the callout before it runs. */
540141428Siedowse			curr_cancelled = 1;
541141428Siedowse			mtx_unlock_spin(&callout_lock);
542141428Siedowse			return (1);
543127969Scperciva		} else
544127969Scperciva			mtx_unlock_spin(&callout_lock);
54581481Sjhb		return (0);
54644510Swollman	}
54750673Sjlemon	c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);
54844510Swollman
54944510Swollman	if (nextsoftcheck == c) {
55044510Swollman		nextsoftcheck = TAILQ_NEXT(c, c_links.tqe);
55144510Swollman	}
55244510Swollman	TAILQ_REMOVE(&callwheel[c->c_time & callwheelmask], c, c_links.tqe);
55344510Swollman
55444510Swollman	if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
555140492Scperciva		c->c_func = NULL;
55644510Swollman		SLIST_INSERT_HEAD(&callfree, c, c_links.sle);
55744510Swollman	}
55872200Sbmilekic	mtx_unlock_spin(&callout_lock);
55981481Sjhb	return (1);
56044510Swollman}
56144510Swollman
56244510Swollmanvoid
56369147Sjlemoncallout_init(c, mpsafe)
56444510Swollman	struct	callout *c;
56569147Sjlemon	int mpsafe;
56644510Swollman{
56744527Swollman	bzero(c, sizeof *c);
568141428Siedowse	if (mpsafe) {
569141428Siedowse		c->c_mtx = NULL;
570141428Siedowse		c->c_flags = CALLOUT_RETURNUNLOCKED;
571141428Siedowse	} else {
572141428Siedowse		c->c_mtx = &Giant;
573141428Siedowse		c->c_flags = 0;
574141428Siedowse	}
57544510Swollman}
57644510Swollman
577141428Siedowsevoid
578141428Siedowsecallout_init_mtx(c, mtx, flags)
579141428Siedowse	struct	callout *c;
580141428Siedowse	struct	mtx *mtx;
581141428Siedowse	int flags;
582141428Siedowse{
583141428Siedowse	bzero(c, sizeof *c);
584141428Siedowse	c->c_mtx = mtx;
585141428Siedowse	KASSERT((flags & ~CALLOUT_RETURNUNLOCKED) == 0,
586141428Siedowse	    ("callout_init_mtx: bad flags %d", flags));
587141428Siedowse	/* CALLOUT_RETURNUNLOCKED makes no sense without a mutex. */
588141428Siedowse	KASSERT(mtx != NULL || (flags & CALLOUT_RETURNUNLOCKED) == 0,
589141428Siedowse	    ("callout_init_mtx: CALLOUT_RETURNUNLOCKED with no mutex"));
590141428Siedowse	c->c_flags = flags & CALLOUT_RETURNUNLOCKED;
591141428Siedowse}
592141428Siedowse
59331950Snate#ifdef APM_FIXUP_CALLTODO
59431950Snate/*
59531950Snate * Adjust the kernel calltodo timeout list.  This routine is used after
59631950Snate * an APM resume to recalculate the calltodo timer list values with the
59731950Snate * number of hz's we have been sleeping.  The next hardclock() will detect
59831950Snate * that there are fired timers and run softclock() to execute them.
59931950Snate *
60031950Snate * Please note, I have not done an exhaustive analysis of what code this
60131950Snate * might break.  I am motivated to have my select()'s and alarm()'s that
60231950Snate * have expired during suspend firing upon resume so that the applications
60331950Snate * which set the timer can do the maintanence the timer was for as close
60431950Snate * as possible to the originally intended time.  Testing this code for a
60531950Snate * week showed that resuming from a suspend resulted in 22 to 25 timers
60631950Snate * firing, which seemed independant on whether the suspend was 2 hours or
60731950Snate * 2 days.  Your milage may vary.   - Ken Key <key@cs.utk.edu>
60831950Snate */
60931950Snatevoid
61031950Snateadjust_timeout_calltodo(time_change)
61131950Snate    struct timeval *time_change;
61231950Snate{
61331950Snate	register struct callout *p;
61431950Snate	unsigned long delta_ticks;
61531950Snate
61631950Snate	/*
61731950Snate	 * How many ticks were we asleep?
61836127Sbde	 * (stolen from tvtohz()).
61931950Snate	 */
62031950Snate
62131950Snate	/* Don't do anything */
62231950Snate	if (time_change->tv_sec < 0)
62331950Snate		return;
62431950Snate	else if (time_change->tv_sec <= LONG_MAX / 1000000)
62531950Snate		delta_ticks = (time_change->tv_sec * 1000000 +
62631950Snate			       time_change->tv_usec + (tick - 1)) / tick + 1;
62731950Snate	else if (time_change->tv_sec <= LONG_MAX / hz)
62831950Snate		delta_ticks = time_change->tv_sec * hz +
62931950Snate			      (time_change->tv_usec + (tick - 1)) / tick + 1;
63031950Snate	else
63131950Snate		delta_ticks = LONG_MAX;
63231950Snate
63331950Snate	if (delta_ticks > INT_MAX)
63431950Snate		delta_ticks = INT_MAX;
63531950Snate
63631950Snate	/*
63731950Snate	 * Now rip through the timer calltodo list looking for timers
63831950Snate	 * to expire.
63931950Snate	 */
64031950Snate
64131950Snate	/* don't collide with softclock() */
64272200Sbmilekic	mtx_lock_spin(&callout_lock);
64331950Snate	for (p = calltodo.c_next; p != NULL; p = p->c_next) {
64431950Snate		p->c_time -= delta_ticks;
64531950Snate
64631950Snate		/* Break if the timer had more time on it than delta_ticks */
64731950Snate		if (p->c_time > 0)
64831950Snate			break;
64931950Snate
65031950Snate		/* take back the ticks the timer didn't use (p->c_time <= 0) */
65131950Snate		delta_ticks = -p->c_time;
65231950Snate	}
65372200Sbmilekic	mtx_unlock_spin(&callout_lock);
65431950Snate
65531950Snate	return;
65631950Snate}
65731950Snate#endif /* APM_FIXUP_CALLTODO */
658