kern_timeout.c revision 163246
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 163246 2006-10-11 14:57:03Z glebius $"); 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> 48150188Sjhb#include <sys/proc.h> 49115810Sphk#include <sys/sysctl.h> 501541Srgrimes 51115810Sphkstatic int avg_depth; 52115810SphkSYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0, 53115810Sphk "Average number of items examined per softclock call. Units = 1/1000"); 54115810Sphkstatic int avg_gcalls; 55115810SphkSYSCTL_INT(_debug, OID_AUTO, to_avg_gcalls, CTLFLAG_RD, &avg_gcalls, 0, 56115810Sphk "Average number of Giant callouts made per softclock call. Units = 1/1000"); 57141428Siedowsestatic int avg_mtxcalls; 58141428SiedowseSYSCTL_INT(_debug, OID_AUTO, to_avg_mtxcalls, CTLFLAG_RD, &avg_mtxcalls, 0, 59141428Siedowse "Average number of mtx callouts made per softclock call. Units = 1/1000"); 60115810Sphkstatic int avg_mpcalls; 61115810SphkSYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0, 62115810Sphk "Average number of MP callouts made per softclock call. Units = 1/1000"); 6333392Sphk/* 6433392Sphk * TODO: 6533392Sphk * allocate more timeout table slots when table overflows. 6633392Sphk */ 6733392Sphk 6833392Sphk/* Exported to machdep.c and/or kern_clock.c. */ 6929680Sgibbsstruct callout *callout; 7029680Sgibbsstruct callout_list callfree; 7129680Sgibbsint callwheelsize, callwheelbits, callwheelmask; 7229680Sgibbsstruct callout_tailq *callwheel; 7333392Sphkint softticks; /* Like ticks, but for softclock(). */ 74116606Sphkstruct mtx callout_lock; 752112Swollman 7629680Sgibbsstatic struct callout *nextsoftcheck; /* Next callout to be checked. */ 77128024Scperciva 78139831Scperciva/** 79127969Scperciva * Locked by callout_lock: 80127969Scperciva * curr_callout - If a callout is in progress, it is curr_callout. 81155957Sjhb * If curr_callout is non-NULL, threads waiting in 82155957Sjhb * callout_drain() will be woken up as soon as the 83127969Scperciva * relevant callout completes. 84141428Siedowse * curr_cancelled - Changing to 1 with both callout_lock and c_mtx held 85141428Siedowse * guarantees that the current callout will not run. 86141428Siedowse * The softclock() function sets this to 0 before it 87141428Siedowse * drops callout_lock to acquire c_mtx, and it calls 88155957Sjhb * the handler only if curr_cancelled is still 0 after 89141428Siedowse * c_mtx is successfully acquired. 90155957Sjhb * callout_wait - If a thread is waiting in callout_drain(), then 91155957Sjhb * callout_wait is nonzero. Set only when 92128024Scperciva * curr_callout is non-NULL. 93127969Scperciva */ 94127969Scpercivastatic struct callout *curr_callout; 95141428Siedowsestatic int curr_cancelled; 96155957Sjhbstatic int callout_wait; 97128024Scperciva 981541Srgrimes/* 9982127Sdillon * kern_timeout_callwheel_alloc() - kernel low level callwheel initialization 10082127Sdillon * 10182127Sdillon * This code is called very early in the kernel initialization sequence, 10282127Sdillon * and may be called more then once. 10382127Sdillon */ 10482127Sdilloncaddr_t 10582127Sdillonkern_timeout_callwheel_alloc(caddr_t v) 10682127Sdillon{ 10782127Sdillon /* 10882127Sdillon * Calculate callout wheel size 10982127Sdillon */ 11082127Sdillon for (callwheelsize = 1, callwheelbits = 0; 11182127Sdillon callwheelsize < ncallout; 11282127Sdillon callwheelsize <<= 1, ++callwheelbits) 11382127Sdillon ; 11482127Sdillon callwheelmask = callwheelsize - 1; 11582127Sdillon 11682127Sdillon callout = (struct callout *)v; 11782127Sdillon v = (caddr_t)(callout + ncallout); 11882127Sdillon callwheel = (struct callout_tailq *)v; 11982127Sdillon v = (caddr_t)(callwheel + callwheelsize); 12082127Sdillon return(v); 12182127Sdillon} 12282127Sdillon 12382127Sdillon/* 12482127Sdillon * kern_timeout_callwheel_init() - initialize previously reserved callwheel 12582127Sdillon * space. 12682127Sdillon * 12782127Sdillon * This code is called just once, after the space reserved for the 12882127Sdillon * callout wheel has been finalized. 12982127Sdillon */ 13082127Sdillonvoid 13182127Sdillonkern_timeout_callwheel_init(void) 13282127Sdillon{ 13382127Sdillon int i; 13482127Sdillon 13582127Sdillon SLIST_INIT(&callfree); 13682127Sdillon for (i = 0; i < ncallout; i++) { 13782127Sdillon callout_init(&callout[i], 0); 13882127Sdillon callout[i].c_flags = CALLOUT_LOCAL_ALLOC; 13982127Sdillon SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle); 14082127Sdillon } 14182127Sdillon for (i = 0; i < callwheelsize; i++) { 14282127Sdillon TAILQ_INIT(&callwheel[i]); 14382127Sdillon } 14493818Sjhb mtx_init(&callout_lock, "callout", NULL, MTX_SPIN | MTX_RECURSE); 14582127Sdillon} 14682127Sdillon 14782127Sdillon/* 14829680Sgibbs * The callout mechanism is based on the work of Adam M. Costello and 14929680Sgibbs * George Varghese, published in a technical report entitled "Redesigning 15029680Sgibbs * the BSD Callout and Timer Facilities" and modified slightly for inclusion 15129680Sgibbs * in FreeBSD by Justin T. Gibbs. The original work on the data structures 152128630Shmp * used in this implementation was published by G. Varghese and T. Lauck in 15329680Sgibbs * the paper "Hashed and Hierarchical Timing Wheels: Data Structures for 15429680Sgibbs * the Efficient Implementation of a Timer Facility" in the Proceedings of 15529680Sgibbs * the 11th ACM Annual Symposium on Operating Systems Principles, 15629680Sgibbs * Austin, Texas Nov 1987. 15729680Sgibbs */ 15832388Sphk 15929680Sgibbs/* 1601541Srgrimes * Software (low priority) clock interrupt. 1611541Srgrimes * Run periodic events from timeout queue. 1621541Srgrimes */ 1631541Srgrimesvoid 16467551Sjhbsoftclock(void *dummy) 1651541Srgrimes{ 166102936Sphk struct callout *c; 167102936Sphk struct callout_tailq *bucket; 168102936Sphk int curticks; 169102936Sphk int steps; /* #steps since we last allowed interrupts */ 170115810Sphk int depth; 171115810Sphk int mpcalls; 172141428Siedowse int mtxcalls; 173115810Sphk int gcalls; 174122585Smckusick#ifdef DIAGNOSTIC 175122585Smckusick struct bintime bt1, bt2; 176122585Smckusick struct timespec ts2; 177122585Smckusick static uint64_t maxdt = 36893488147419102LL; /* 2 msec */ 178123254Sphk static timeout_t *lastfunc; 179122585Smckusick#endif 1801541Srgrimes 18133392Sphk#ifndef MAX_SOFTCLOCK_STEPS 18233392Sphk#define MAX_SOFTCLOCK_STEPS 100 /* Maximum allowed value of steps. */ 18333392Sphk#endif /* MAX_SOFTCLOCK_STEPS */ 18429680Sgibbs 185115810Sphk mpcalls = 0; 186141428Siedowse mtxcalls = 0; 187115810Sphk gcalls = 0; 188115810Sphk depth = 0; 18929680Sgibbs steps = 0; 19072200Sbmilekic mtx_lock_spin(&callout_lock); 19129680Sgibbs while (softticks != ticks) { 19229805Sgibbs softticks++; 19329805Sgibbs /* 19429805Sgibbs * softticks may be modified by hard clock, so cache 19529805Sgibbs * it while we work on a given bucket. 19629805Sgibbs */ 19729805Sgibbs curticks = softticks; 19829805Sgibbs bucket = &callwheel[curticks & callwheelmask]; 19929805Sgibbs c = TAILQ_FIRST(bucket); 20029680Sgibbs while (c) { 201115810Sphk depth++; 20229805Sgibbs if (c->c_time != curticks) { 20329680Sgibbs c = TAILQ_NEXT(c, c_links.tqe); 20429680Sgibbs ++steps; 20529680Sgibbs if (steps >= MAX_SOFTCLOCK_STEPS) { 20629680Sgibbs nextsoftcheck = c; 20729805Sgibbs /* Give interrupts a chance. */ 20872200Sbmilekic mtx_unlock_spin(&callout_lock); 20981370Sjhb ; /* nothing */ 21072200Sbmilekic mtx_lock_spin(&callout_lock); 21129680Sgibbs c = nextsoftcheck; 21229680Sgibbs steps = 0; 21329680Sgibbs } 21429680Sgibbs } else { 21529680Sgibbs void (*c_func)(void *); 21629680Sgibbs void *c_arg; 217141428Siedowse struct mtx *c_mtx; 21868889Sjake int c_flags; 21929680Sgibbs 22029680Sgibbs nextsoftcheck = TAILQ_NEXT(c, c_links.tqe); 22129805Sgibbs TAILQ_REMOVE(bucket, c, c_links.tqe); 22229680Sgibbs c_func = c->c_func; 22329680Sgibbs c_arg = c->c_arg; 224141428Siedowse c_mtx = c->c_mtx; 22568889Sjake c_flags = c->c_flags; 22644510Swollman if (c->c_flags & CALLOUT_LOCAL_ALLOC) { 227140489Scperciva c->c_func = NULL; 22844510Swollman c->c_flags = CALLOUT_LOCAL_ALLOC; 22944510Swollman SLIST_INSERT_HEAD(&callfree, c, 23044510Swollman c_links.sle); 231141674Siedowse curr_callout = NULL; 23244510Swollman } else { 23344510Swollman c->c_flags = 23450673Sjlemon (c->c_flags & ~CALLOUT_PENDING); 235141674Siedowse curr_callout = c; 23644510Swollman } 237141428Siedowse curr_cancelled = 0; 23872200Sbmilekic mtx_unlock_spin(&callout_lock); 239141428Siedowse if (c_mtx != NULL) { 240141428Siedowse mtx_lock(c_mtx); 241141428Siedowse /* 242141428Siedowse * The callout may have been cancelled 243141428Siedowse * while we switched locks. 244141428Siedowse */ 245141428Siedowse if (curr_cancelled) { 246141428Siedowse mtx_unlock(c_mtx); 247155957Sjhb goto skip; 248141428Siedowse } 249141428Siedowse /* The callout cannot be stopped now. */ 250141428Siedowse curr_cancelled = 1; 251141428Siedowse 252141428Siedowse if (c_mtx == &Giant) { 253141428Siedowse gcalls++; 254163246Sglebius CTR3(KTR_CALLOUT, 255163246Sglebius "callout %p func %p arg %p", 256163246Sglebius c, c_func, c_arg); 257141428Siedowse } else { 258141428Siedowse mtxcalls++; 259163246Sglebius CTR3(KTR_CALLOUT, "callout mtx" 260163246Sglebius " %p func %p arg %p", 261163246Sglebius c, c_func, c_arg); 262141428Siedowse } 263115810Sphk } else { 264115810Sphk mpcalls++; 265163246Sglebius CTR3(KTR_CALLOUT, 266163246Sglebius "callout mpsafe %p func %p arg %p", 267163246Sglebius c, c_func, c_arg); 268115810Sphk } 269122585Smckusick#ifdef DIAGNOSTIC 270122585Smckusick binuptime(&bt1); 271122585Smckusick#endif 272150187Sjhb THREAD_NO_SLEEPING(); 27329680Sgibbs c_func(c_arg); 274150187Sjhb THREAD_SLEEPING_OK(); 275122585Smckusick#ifdef DIAGNOSTIC 276122585Smckusick binuptime(&bt2); 277122585Smckusick bintime_sub(&bt2, &bt1); 278122585Smckusick if (bt2.frac > maxdt) { 279123254Sphk if (lastfunc != c_func || 280123254Sphk bt2.frac > maxdt * 2) { 281123254Sphk bintime2timespec(&bt2, &ts2); 282123254Sphk printf( 283123254Sphk "Expensive timeout(9) function: %p(%p) %jd.%09ld s\n", 284123254Sphk c_func, c_arg, 285123254Sphk (intmax_t)ts2.tv_sec, 286123254Sphk ts2.tv_nsec); 287123254Sphk } 288122585Smckusick maxdt = bt2.frac; 289123254Sphk lastfunc = c_func; 290122585Smckusick } 291122585Smckusick#endif 292141428Siedowse if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0) 293141428Siedowse mtx_unlock(c_mtx); 294155957Sjhb skip: 29572200Sbmilekic mtx_lock_spin(&callout_lock); 296127969Scperciva curr_callout = NULL; 297155957Sjhb if (callout_wait) { 298127969Scperciva /* 299155957Sjhb * There is someone waiting 300127969Scperciva * for the callout to complete. 301127969Scperciva */ 302155957Sjhb wakeup(&callout_wait); 303155957Sjhb callout_wait = 0; 304128024Scperciva } 30529680Sgibbs steps = 0; 30629680Sgibbs c = nextsoftcheck; 30729680Sgibbs } 30829680Sgibbs } 3091541Srgrimes } 310115810Sphk avg_depth += (depth * 1000 - avg_depth) >> 8; 311115810Sphk avg_mpcalls += (mpcalls * 1000 - avg_mpcalls) >> 8; 312141428Siedowse avg_mtxcalls += (mtxcalls * 1000 - avg_mtxcalls) >> 8; 313115810Sphk avg_gcalls += (gcalls * 1000 - avg_gcalls) >> 8; 31429680Sgibbs nextsoftcheck = NULL; 31572200Sbmilekic mtx_unlock_spin(&callout_lock); 3161541Srgrimes} 3171541Srgrimes 3181541Srgrimes/* 3191541Srgrimes * timeout -- 3201541Srgrimes * Execute a function after a specified length of time. 3211541Srgrimes * 3221541Srgrimes * untimeout -- 3231541Srgrimes * Cancel previous timeout function call. 3241541Srgrimes * 32529680Sgibbs * callout_handle_init -- 32629680Sgibbs * Initialize a handle so that using it with untimeout is benign. 32729680Sgibbs * 3281541Srgrimes * See AT&T BCI Driver Reference Manual for specification. This 32929680Sgibbs * implementation differs from that one in that although an 33029680Sgibbs * identification value is returned from timeout, the original 33129680Sgibbs * arguments to timeout as well as the identifier are used to 33229680Sgibbs * identify entries for untimeout. 3331541Srgrimes */ 33429680Sgibbsstruct callout_handle 33529680Sgibbstimeout(ftn, arg, to_ticks) 33633824Sbde timeout_t *ftn; 3371541Srgrimes void *arg; 33869147Sjlemon int to_ticks; 3391541Srgrimes{ 34029680Sgibbs struct callout *new; 34129680Sgibbs struct callout_handle handle; 3421541Srgrimes 34372200Sbmilekic mtx_lock_spin(&callout_lock); 3441541Srgrimes 3451541Srgrimes /* Fill in the next free callout structure. */ 34629680Sgibbs new = SLIST_FIRST(&callfree); 34729680Sgibbs if (new == NULL) 34829680Sgibbs /* XXX Attempt to malloc first */ 3491541Srgrimes panic("timeout table full"); 35029680Sgibbs SLIST_REMOVE_HEAD(&callfree, c_links.sle); 35144510Swollman 35244510Swollman callout_reset(new, to_ticks, ftn, arg); 3531541Srgrimes 35444510Swollman handle.callout = new; 35572200Sbmilekic mtx_unlock_spin(&callout_lock); 35629680Sgibbs return (handle); 3571541Srgrimes} 3581541Srgrimes 3591541Srgrimesvoid 36029680Sgibbsuntimeout(ftn, arg, handle) 36133824Sbde timeout_t *ftn; 3621541Srgrimes void *arg; 36329680Sgibbs struct callout_handle handle; 3641541Srgrimes{ 3651541Srgrimes 36629680Sgibbs /* 36729680Sgibbs * Check for a handle that was initialized 36829680Sgibbs * by callout_handle_init, but never used 36929680Sgibbs * for a real timeout. 37029680Sgibbs */ 37129680Sgibbs if (handle.callout == NULL) 37229680Sgibbs return; 37329680Sgibbs 37472200Sbmilekic mtx_lock_spin(&callout_lock); 37544510Swollman if (handle.callout->c_func == ftn && handle.callout->c_arg == arg) 37644510Swollman callout_stop(handle.callout); 37772200Sbmilekic mtx_unlock_spin(&callout_lock); 3781541Srgrimes} 3791541Srgrimes 38024101Sbdevoid 38129680Sgibbscallout_handle_init(struct callout_handle *handle) 38229680Sgibbs{ 38329680Sgibbs handle->callout = NULL; 38429680Sgibbs} 38529680Sgibbs 38644510Swollman/* 38744510Swollman * New interface; clients allocate their own callout structures. 38844510Swollman * 38944510Swollman * callout_reset() - establish or change a timeout 39044510Swollman * callout_stop() - disestablish a timeout 39144510Swollman * callout_init() - initialize a callout structure so that it can 39244510Swollman * safely be passed to callout_reset() and callout_stop() 39344510Swollman * 39450673Sjlemon * <sys/callout.h> defines three convenience macros: 39544510Swollman * 396140487Scperciva * callout_active() - returns truth if callout has not been stopped, 397140487Scperciva * drained, or deactivated since the last time the callout was 398140487Scperciva * reset. 39950673Sjlemon * callout_pending() - returns truth if callout is still waiting for timeout 40050673Sjlemon * callout_deactivate() - marks the callout as having been serviced 40144510Swollman */ 402149879Sglebiusint 40369147Sjlemoncallout_reset(c, to_ticks, ftn, arg) 40444510Swollman struct callout *c; 40544510Swollman int to_ticks; 40692723Salfred void (*ftn)(void *); 40744510Swollman void *arg; 40844510Swollman{ 409149879Sglebius int cancelled = 0; 41044510Swollman 411141428Siedowse#ifdef notyet /* Some callers of timeout() do not hold Giant. */ 412141428Siedowse if (c->c_mtx != NULL) 413141428Siedowse mtx_assert(c->c_mtx, MA_OWNED); 414141428Siedowse#endif 415141428Siedowse 41672200Sbmilekic mtx_lock_spin(&callout_lock); 417141428Siedowse if (c == curr_callout) { 418127969Scperciva /* 419127969Scperciva * We're being asked to reschedule a callout which is 420141428Siedowse * currently in progress. If there is a mutex then we 421141428Siedowse * can cancel the callout if it has not really started. 422127969Scperciva */ 423141428Siedowse if (c->c_mtx != NULL && !curr_cancelled) 424149879Sglebius cancelled = curr_cancelled = 1; 425155957Sjhb if (callout_wait) { 426141428Siedowse /* 427141428Siedowse * Someone has called callout_drain to kill this 428141428Siedowse * callout. Don't reschedule. 429141428Siedowse */ 430163246Sglebius CTR4(KTR_CALLOUT, "%s %p func %p arg %p", 431163246Sglebius cancelled ? "cancelled" : "failed to cancel", 432163246Sglebius c, c->c_func, c->c_arg); 433141428Siedowse mtx_unlock_spin(&callout_lock); 434149879Sglebius return (cancelled); 435141428Siedowse } 436128024Scperciva } 437133190Scperciva if (c->c_flags & CALLOUT_PENDING) { 438133190Scperciva if (nextsoftcheck == c) { 439133190Scperciva nextsoftcheck = TAILQ_NEXT(c, c_links.tqe); 440133190Scperciva } 441133190Scperciva TAILQ_REMOVE(&callwheel[c->c_time & callwheelmask], c, 442133190Scperciva c_links.tqe); 44344510Swollman 444149879Sglebius cancelled = 1; 445149879Sglebius 446133190Scperciva /* 447133190Scperciva * Part of the normal "stop a pending callout" process 448133190Scperciva * is to clear the CALLOUT_ACTIVE and CALLOUT_PENDING 449133190Scperciva * flags. We're not going to bother doing that here, 450133190Scperciva * because we're going to be setting those flags ten lines 451133190Scperciva * after this point, and we're holding callout_lock 452133190Scperciva * between now and then. 453133190Scperciva */ 454133190Scperciva } 455133190Scperciva 45644510Swollman /* 45781370Sjhb * We could unlock callout_lock here and lock it again before the 45881370Sjhb * TAILQ_INSERT_TAIL, but there's no point since doing this setup 45981370Sjhb * doesn't take much time. 46044510Swollman */ 46144510Swollman if (to_ticks <= 0) 46244510Swollman to_ticks = 1; 46344510Swollman 46444510Swollman c->c_arg = arg; 46569147Sjlemon c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING); 46644510Swollman c->c_func = ftn; 46744510Swollman c->c_time = ticks + to_ticks; 46844510Swollman TAILQ_INSERT_TAIL(&callwheel[c->c_time & callwheelmask], 46944510Swollman c, c_links.tqe); 470163246Sglebius CTR5(KTR_CALLOUT, "%sscheduled %p func %p arg %p in %d", 471163246Sglebius cancelled ? "re" : "", c, c->c_func, c->c_arg, to_ticks); 47272200Sbmilekic mtx_unlock_spin(&callout_lock); 473149879Sglebius 474149879Sglebius return (cancelled); 47544510Swollman} 47644510Swollman 47781481Sjhbint 478127969Scperciva_callout_stop_safe(c, safe) 479127969Scperciva struct callout *c; 480127969Scperciva int safe; 481127969Scperciva{ 482155957Sjhb int use_mtx; 483127969Scperciva 484141428Siedowse if (!safe && c->c_mtx != NULL) { 485141428Siedowse#ifdef notyet /* Some callers do not hold Giant for Giant-locked callouts. */ 486141428Siedowse mtx_assert(c->c_mtx, MA_OWNED); 487141428Siedowse use_mtx = 1; 488141428Siedowse#else 489141428Siedowse use_mtx = mtx_owned(c->c_mtx); 490141428Siedowse#endif 491141428Siedowse } else { 492141428Siedowse use_mtx = 0; 493141428Siedowse } 494141428Siedowse 49572200Sbmilekic mtx_lock_spin(&callout_lock); 49644510Swollman /* 497155957Sjhb * If the callout isn't pending, it's not on the queue, so 498155957Sjhb * don't attempt to remove it from the queue. We can try to 499155957Sjhb * stop it by other means however. 50044510Swollman */ 50144510Swollman if (!(c->c_flags & CALLOUT_PENDING)) { 50250673Sjlemon c->c_flags &= ~CALLOUT_ACTIVE; 503155957Sjhb 504155957Sjhb /* 505155957Sjhb * If it wasn't on the queue and it isn't the current 506155957Sjhb * callout, then we can't stop it, so just bail. 507155957Sjhb */ 508141428Siedowse if (c != curr_callout) { 509163246Sglebius CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p", 510163246Sglebius c, c->c_func, c->c_arg); 511141428Siedowse mtx_unlock_spin(&callout_lock); 512141428Siedowse return (0); 513141428Siedowse } 514155957Sjhb 515141428Siedowse if (safe) { 516127969Scperciva /* 517155957Sjhb * The current callout is running (or just 518155957Sjhb * about to run) and blocking is allowed, so 519155957Sjhb * just wait for the current invocation to 520155957Sjhb * finish. 521127969Scperciva */ 522155957Sjhb while (c == curr_callout) { 523155957Sjhb callout_wait = 1; 524155957Sjhb msleep_spin(&callout_wait, &callout_lock, 525155957Sjhb "codrain", 0); 526155957Sjhb } 527141428Siedowse } else if (use_mtx && !curr_cancelled) { 528155957Sjhb /* 529155957Sjhb * The current callout is waiting for it's 530155957Sjhb * mutex which we hold. Cancel the callout 531155957Sjhb * and return. After our caller drops the 532155957Sjhb * mutex, the callout will be skipped in 533155957Sjhb * softclock(). 534155957Sjhb */ 535141428Siedowse curr_cancelled = 1; 536163246Sglebius CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p", 537163246Sglebius c, c->c_func, c->c_arg); 538141428Siedowse mtx_unlock_spin(&callout_lock); 539141428Siedowse return (1); 540155957Sjhb } 541163246Sglebius CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p", 542163246Sglebius c, c->c_func, c->c_arg); 543155957Sjhb mtx_unlock_spin(&callout_lock); 54481481Sjhb return (0); 54544510Swollman } 54650673Sjlemon c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING); 54744510Swollman 54844510Swollman if (nextsoftcheck == c) { 54944510Swollman nextsoftcheck = TAILQ_NEXT(c, c_links.tqe); 55044510Swollman } 55144510Swollman TAILQ_REMOVE(&callwheel[c->c_time & callwheelmask], c, c_links.tqe); 55244510Swollman 553163246Sglebius CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p", 554163246Sglebius c, c->c_func, c->c_arg); 555163246Sglebius 55644510Swollman if (c->c_flags & CALLOUT_LOCAL_ALLOC) { 557140492Scperciva c->c_func = NULL; 55844510Swollman SLIST_INSERT_HEAD(&callfree, c, c_links.sle); 55944510Swollman } 56072200Sbmilekic mtx_unlock_spin(&callout_lock); 56181481Sjhb return (1); 56244510Swollman} 56344510Swollman 56444510Swollmanvoid 56569147Sjlemoncallout_init(c, mpsafe) 56644510Swollman struct callout *c; 56769147Sjlemon int mpsafe; 56844510Swollman{ 56944527Swollman bzero(c, sizeof *c); 570141428Siedowse if (mpsafe) { 571141428Siedowse c->c_mtx = NULL; 572141428Siedowse c->c_flags = CALLOUT_RETURNUNLOCKED; 573141428Siedowse } else { 574141428Siedowse c->c_mtx = &Giant; 575141428Siedowse c->c_flags = 0; 576141428Siedowse } 57744510Swollman} 57844510Swollman 579141428Siedowsevoid 580141428Siedowsecallout_init_mtx(c, mtx, flags) 581141428Siedowse struct callout *c; 582141428Siedowse struct mtx *mtx; 583141428Siedowse int flags; 584141428Siedowse{ 585141428Siedowse bzero(c, sizeof *c); 586141428Siedowse c->c_mtx = mtx; 587141428Siedowse KASSERT((flags & ~CALLOUT_RETURNUNLOCKED) == 0, 588141428Siedowse ("callout_init_mtx: bad flags %d", flags)); 589141428Siedowse /* CALLOUT_RETURNUNLOCKED makes no sense without a mutex. */ 590141428Siedowse KASSERT(mtx != NULL || (flags & CALLOUT_RETURNUNLOCKED) == 0, 591141428Siedowse ("callout_init_mtx: CALLOUT_RETURNUNLOCKED with no mutex")); 592141428Siedowse c->c_flags = flags & CALLOUT_RETURNUNLOCKED; 593141428Siedowse} 594141428Siedowse 59531950Snate#ifdef APM_FIXUP_CALLTODO 59631950Snate/* 59731950Snate * Adjust the kernel calltodo timeout list. This routine is used after 59831950Snate * an APM resume to recalculate the calltodo timer list values with the 59931950Snate * number of hz's we have been sleeping. The next hardclock() will detect 60031950Snate * that there are fired timers and run softclock() to execute them. 60131950Snate * 60231950Snate * Please note, I have not done an exhaustive analysis of what code this 60331950Snate * might break. I am motivated to have my select()'s and alarm()'s that 60431950Snate * have expired during suspend firing upon resume so that the applications 60531950Snate * which set the timer can do the maintanence the timer was for as close 60631950Snate * as possible to the originally intended time. Testing this code for a 60731950Snate * week showed that resuming from a suspend resulted in 22 to 25 timers 60831950Snate * firing, which seemed independant on whether the suspend was 2 hours or 60931950Snate * 2 days. Your milage may vary. - Ken Key <key@cs.utk.edu> 61031950Snate */ 61131950Snatevoid 61231950Snateadjust_timeout_calltodo(time_change) 61331950Snate struct timeval *time_change; 61431950Snate{ 61531950Snate register struct callout *p; 61631950Snate unsigned long delta_ticks; 61731950Snate 61831950Snate /* 61931950Snate * How many ticks were we asleep? 62036127Sbde * (stolen from tvtohz()). 62131950Snate */ 62231950Snate 62331950Snate /* Don't do anything */ 62431950Snate if (time_change->tv_sec < 0) 62531950Snate return; 62631950Snate else if (time_change->tv_sec <= LONG_MAX / 1000000) 62731950Snate delta_ticks = (time_change->tv_sec * 1000000 + 62831950Snate time_change->tv_usec + (tick - 1)) / tick + 1; 62931950Snate else if (time_change->tv_sec <= LONG_MAX / hz) 63031950Snate delta_ticks = time_change->tv_sec * hz + 63131950Snate (time_change->tv_usec + (tick - 1)) / tick + 1; 63231950Snate else 63331950Snate delta_ticks = LONG_MAX; 63431950Snate 63531950Snate if (delta_ticks > INT_MAX) 63631950Snate delta_ticks = INT_MAX; 63731950Snate 63831950Snate /* 63931950Snate * Now rip through the timer calltodo list looking for timers 64031950Snate * to expire. 64131950Snate */ 64231950Snate 64331950Snate /* don't collide with softclock() */ 64472200Sbmilekic mtx_lock_spin(&callout_lock); 64531950Snate for (p = calltodo.c_next; p != NULL; p = p->c_next) { 64631950Snate p->c_time -= delta_ticks; 64731950Snate 64831950Snate /* Break if the timer had more time on it than delta_ticks */ 64931950Snate if (p->c_time > 0) 65031950Snate break; 65131950Snate 65231950Snate /* take back the ticks the timer didn't use (p->c_time <= 0) */ 65331950Snate delta_ticks = -p->c_time; 65431950Snate } 65572200Sbmilekic mtx_unlock_spin(&callout_lock); 65631950Snate 65731950Snate return; 65831950Snate} 65931950Snate#endif /* APM_FIXUP_CALLTODO */ 660