1.\" $NetBSD: timeout.9,v 1.2 1996/06/23 22:32:34 pk Exp $ 2.\" 3.\" Copyright (c) 1996 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Paul Kranenburg. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 22.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28.\" POSSIBILITY OF SUCH DAMAGE. 29.\" 30.Dd January 22, 2024 31.Dt CALLOUT 9 32.Os 33.Sh NAME 34.Nm callout_active , 35.Nm callout_deactivate , 36.Nm callout_drain , 37.Nm callout_init , 38.Nm callout_init_mtx , 39.Nm callout_init_rm , 40.Nm callout_init_rw , 41.Nm callout_pending , 42.Nm callout_reset , 43.Nm callout_reset_curcpu , 44.Nm callout_reset_on , 45.Nm callout_reset_sbt , 46.Nm callout_reset_sbt_curcpu , 47.Nm callout_reset_sbt_on , 48.Nm callout_schedule , 49.Nm callout_schedule_curcpu , 50.Nm callout_schedule_on , 51.Nm callout_schedule_sbt , 52.Nm callout_schedule_sbt_curcpu , 53.Nm callout_schedule_sbt_on , 54.Nm callout_stop , 55.Nm callout_when 56.Nd execute a function after a specified length of time 57.Sh SYNOPSIS 58.In sys/types.h 59.In sys/callout.h 60.Bd -literal 61typedef void callout_func_t (void *); 62.Ed 63.Ft int 64.Fn callout_active "struct callout *c" 65.Ft void 66.Fn callout_deactivate "struct callout *c" 67.Ft int 68.Fn callout_drain "struct callout *c" 69.Ft void 70.Fn callout_init "struct callout *c" "int mpsafe" 71.Ft void 72.Fn callout_init_mtx "struct callout *c" "struct mtx *mtx" "int flags" 73.Ft void 74.Fn callout_init_rm "struct callout *c" "struct rmlock *rm" "int flags" 75.Ft void 76.Fn callout_init_rw "struct callout *c" "struct rwlock *rw" "int flags" 77.Ft int 78.Fn callout_pending "struct callout *c" 79.Ft int 80.Fo callout_reset 81.Fa "struct callout *c" 82.Fa "int ticks" 83.Fa "callout_func_t *func" 84.Fa "void *arg" 85.Fc 86.Ft int 87.Fo callout_reset_curcpu 88.Fa "struct callout *c" 89.Fa "int ticks" 90.Fa "callout_func_t *func" 91.Fa "void *arg" 92.Fc 93.Ft int 94.Fo callout_reset_on 95.Fa "struct callout *c" 96.Fa "int ticks" 97.Fa "callout_func_t *func" 98.Fa "void *arg" 99.Fa "int cpu" 100.Fc 101.Ft int 102.Fo callout_reset_sbt 103.Fa "struct callout *c" 104.Fa "sbintime_t sbt" 105.Fa "sbintime_t pr" 106.Fa "callout_func_t *func" 107.Fa "void *arg" 108.Fa "int flags" 109.Fc 110.Ft int 111.Fo callout_reset_sbt_curcpu 112.Fa "struct callout *c" 113.Fa "sbintime_t sbt" 114.Fa "sbintime_t pr" 115.Fa "callout_func_t *func" 116.Fa "void *arg" 117.Fa "int flags" 118.Fc 119.Ft int 120.Fo callout_reset_sbt_on 121.Fa "struct callout *c" 122.Fa "sbintime_t sbt" 123.Fa "sbintime_t pr" 124.Fa "callout_func_t *func" 125.Fa "void *arg" 126.Fa "int cpu" 127.Fa "int flags" 128.Fc 129.Ft int 130.Fn callout_schedule "struct callout *c" "int ticks" 131.Ft int 132.Fn callout_schedule_curcpu "struct callout *c" "int ticks" 133.Ft int 134.Fn callout_schedule_on "struct callout *c" "int ticks" "int cpu" 135.Ft int 136.Fo callout_schedule_sbt 137.Fa "struct callout *c" 138.Fa "sbintime_t sbt" 139.Fa "sbintime_t pr" 140.Fa "int flags" 141.Fc 142.Ft int 143.Fo callout_schedule_sbt_curcpu 144.Fa "struct callout *c" 145.Fa "sbintime_t sbt" 146.Fa "sbintime_t pr" 147.Fa "int flags" 148.Fc 149.Ft int 150.Fo callout_schedule_sbt_on 151.Fa "struct callout *c" 152.Fa "sbintime_t sbt" 153.Fa "sbintime_t pr" 154.Fa "int cpu" 155.Fa "int flags" 156.Fc 157.Ft int 158.Fn callout_stop "struct callout *c" 159.Ft sbintime_t 160.Fo callout_when 161.Fa "sbintime_t sbt" 162.Fa "sbintime_t precision" 163.Fa "int flags" 164.Fa "sbintime_t *sbt_res" 165.Fa "sbintime_t *precision_res" 166.Fc 167.Sh DESCRIPTION 168The 169.Nm callout 170API is used to schedule a call to an arbitrary function at a specific 171time in the future. 172Consumers of this API are required to allocate a callout structure 173.Pq struct callout 174for each pending function invocation. 175This structure stores state about the pending function invocation including 176the function to be called and the time at which the function should be invoked. 177Pending function calls can be cancelled or rescheduled to a different time. 178In addition, 179a callout structure may be reused to schedule a new function call after a 180scheduled call is completed. 181.Pp 182Callouts only provide a single-shot mode. 183If a consumer requires a periodic timer, 184it must explicitly reschedule each function call. 185This is normally done by rescheduling the subsequent call within the called 186function. 187.Pp 188Callout functions must not sleep. 189They may not acquire sleepable locks, 190wait on condition variables, 191perform blocking allocation requests, 192or invoke any other action that might sleep. 193.Pp 194Each callout structure must be initialized by 195.Fn callout_init , 196.Fn callout_init_mtx , 197.Fn callout_init_rm , 198or 199.Fn callout_init_rw 200before it is passed to any of the other callout functions. 201The 202.Fn callout_init 203function initializes a callout structure in 204.Fa c 205that is not associated with a specific lock. 206If the 207.Fa mpsafe 208argument is zero, 209the callout structure is not considered to be 210.Dq multi-processor safe ; 211and the Giant lock will be acquired before calling the callout function 212and released when the callout function returns. 213.Pp 214The 215.Fn callout_init_mtx , 216.Fn callout_init_rm , 217and 218.Fn callout_init_rw 219functions initialize a callout structure in 220.Fa c 221that is associated with a specific lock. 222The lock is specified by the 223.Fa mtx , 224.Fa rm , 225or 226.Fa rw 227parameter. 228The associated lock must be held while stopping or rescheduling the 229callout. 230The callout subsystem acquires the associated lock before calling the 231callout function and releases it after the function returns. 232If the callout was cancelled while the callout subsystem waited for the 233associated lock, 234the callout function is not called, 235and the associated lock is released. 236This ensures that stopping or rescheduling the callout will abort any 237previously scheduled invocation. 238.Pp 239A sleepable read-mostly lock 240.Po 241one initialized with the 242.Dv RM_SLEEPABLE 243flag 244.Pc 245may not be used with 246.Fn callout_init_rm . 247Similarly, other sleepable lock types such as 248.Xr sx 9 249and 250.Xr lockmgr 9 251cannot be used with callouts because sleeping is not permitted in 252the callout subsystem. 253.Pp 254These 255.Fa flags 256may be specified for 257.Fn callout_init_mtx , 258.Fn callout_init_rm , 259or 260.Fn callout_init_rw : 261.Bl -tag -width ".Dv CALLOUT_RETURNUNLOCKED" 262.It Dv CALLOUT_RETURNUNLOCKED 263The callout function will release the associated lock itself, 264so the callout subsystem should not attempt to unlock it 265after the callout function returns. 266.It Dv CALLOUT_SHAREDLOCK 267The lock is only acquired in read mode when running the callout handler. 268This flag is ignored by 269.Fn callout_init_mtx . 270.El 271.Pp 272The function 273.Fn callout_stop 274cancels a callout 275.Fa c 276if it is currently pending. 277If the callout is pending and successfully stopped, then 278.Fn callout_stop 279returns a value of one. 280If the callout is not set, or 281has already been serviced, then 282negative one is returned. 283If the callout is currently being serviced and cannot be stopped, 284then zero will be returned. 285If the callout is currently being serviced and cannot be stopped, and at the 286same time a next invocation of the same callout is also scheduled, then 287.Fn callout_stop 288unschedules the next run and returns zero. 289If the callout has an associated lock, 290then that lock must be held when this function is called. 291.Pp 292The function 293.Fn callout_drain 294is identical to 295.Fn callout_stop 296except that it will wait for the callout 297.Fa c 298to complete if it is already in progress. 299This function MUST NOT be called while holding any 300locks on which the callout might block, or deadlock will result. 301Note that if the callout subsystem has already begun processing this 302callout, then the callout function may be invoked before 303.Fn callout_drain 304returns. 305However, the callout subsystem does guarantee that the callout will be 306fully stopped before 307.Fn callout_drain 308returns. 309.Pp 310The 311.Fn callout_reset 312and 313.Fn callout_schedule 314function families schedule a future function invocation for callout 315.Fa c . 316If 317.Fa c 318already has a pending callout, 319it is cancelled before the new invocation is scheduled. 320These functions return a value of one if a pending callout was cancelled 321and zero if there was no pending callout. 322If the callout has an associated lock, 323then that lock must be held when any of these functions are called. 324.Pp 325The time at which the callout function will be invoked is determined by 326either the 327.Fa ticks 328argument or the 329.Fa sbt , 330.Fa pr , 331and 332.Fa flags 333arguments. 334When 335.Fa ticks 336is used, 337the callout is scheduled to execute after 338.Fa ticks Ns No /hz 339seconds. 340Non-positive values of 341.Fa ticks 342are silently converted to the value 343.Sq 1 . 344.Pp 345The 346.Fa sbt , 347.Fa pr , 348and 349.Fa flags 350arguments provide more control over the scheduled time including 351support for higher resolution times, 352specifying the precision of the scheduled time, 353and setting an absolute deadline instead of a relative timeout. 354The callout is scheduled to execute in a time window which begins at 355the time specified in 356.Fa sbt 357and extends for the amount of time specified in 358.Fa pr . 359If 360.Fa sbt 361specifies a time in the past, 362the window is adjusted to start at the current time. 363A non-zero value for 364.Fa pr 365allows the callout subsystem to coalesce callouts scheduled close to each 366other into fewer timer interrupts, 367reducing processing overhead and power consumption. 368These 369.Fa flags 370may be specified to adjust the interpretation of 371.Fa sbt 372and 373.Fa pr : 374.Bl -tag -width ".Dv C_DIRECT_EXEC" 375.It Dv C_ABSOLUTE 376Handle the 377.Fa sbt 378argument as an absolute time since boot. 379By default, 380.Fa sbt 381is treated as a relative amount of time, 382similar to 383.Fa ticks . 384.It Dv C_DIRECT_EXEC 385Run the handler directly from hardware interrupt context instead of from the 386softclock thread. 387This reduces latency and overhead, but puts more constraints on the callout 388function. 389Callout functions run in this context may use only spin mutexes for locking 390and should be as small as possible because they run with absolute priority. 391.It Fn C_PREL 392Specifies relative event time precision as binary logarithm of time interval 393divided by acceptable time deviation: 1 -- 1/2, 2 -- 1/4, etc. 394Note that the larger of 395.Fa pr 396or this value is used as the length of the time window. 397Smaller values 398.Pq which result in larger time intervals 399allow the callout subsystem to aggregate more events in one timer interrupt. 400.It Dv C_PRECALC 401The 402.Fa sbt 403argument specifies the absolute time at which the callout should be run, 404and the 405.Fa pr 406argument specifies the requested precision, which will not be 407adjusted during the scheduling process. 408The 409.Fa sbt 410and 411.Fa pr 412values should be calculated by an earlier call to 413.Fn callout_when 414which uses the user-supplied 415.Fa sbt , 416.Fa pr , 417and 418.Fa flags 419values. 420.It Dv C_HARDCLOCK 421Align the timeouts to 422.Fn hardclock 423calls if possible. 424.El 425.Pp 426The 427.Fn callout_reset 428functions accept a 429.Fa func 430argument which identifies the function to be called when the time expires. 431It must be a pointer to a function that takes a single 432.Fa void * 433argument. 434Upon invocation, 435.Fa func 436will receive 437.Fa arg 438as its only argument. 439The 440.Fn callout_schedule 441functions reuse the 442.Fa func 443and 444.Fa arg 445arguments from the previous callout. 446Note that one of the 447.Fn callout_reset 448functions must always be called to initialize 449.Fa func 450and 451.Fa arg 452before one of the 453.Fn callout_schedule 454functions can be used. 455.Pp 456The callout subsystem provides a softclock thread for each CPU in the system. 457Callouts are assigned to a single CPU and are executed by the softclock thread 458for that CPU. 459Initially, 460callouts are assigned to CPU 0. 461The 462.Fn callout_reset_on , 463.Fn callout_reset_sbt_on , 464.Fn callout_schedule_on 465and 466.Fn callout_schedule_sbt_on 467functions assign the callout to CPU 468.Fa cpu . 469The 470.Fn callout_reset_curcpu , 471.Fn callout_reset_sbt_curpu , 472.Fn callout_schedule_curcpu 473and 474.Fn callout_schedule_sbt_curcpu 475functions assign the callout to the current CPU. 476The 477.Fn callout_reset , 478.Fn callout_reset_sbt , 479.Fn callout_schedule 480and 481.Fn callout_schedule_sbt 482functions schedule the callout to execute in the softclock thread of the CPU 483to which it is currently assigned. 484.Pp 485Softclock threads are not pinned to their respective CPUs by default. 486The softclock thread for CPU 0 can be pinned to CPU 0 by setting the 487.Va kern.pin_default_swi 488loader tunable to a non-zero value. 489Softclock threads for CPUs other than zero can be pinned to their 490respective CPUs by setting the 491.Va kern.pin_pcpu_swi 492loader tunable to a non-zero value. 493.Pp 494The macros 495.Fn callout_pending , 496.Fn callout_active 497and 498.Fn callout_deactivate 499provide access to the current state of the callout. 500The 501.Fn callout_pending 502macro checks whether a callout is 503.Em pending ; 504a callout is considered 505.Em pending 506when a timeout has been set but the time has not yet arrived. 507Note that once the timeout time arrives and the callout subsystem 508starts to process this callout, 509.Fn callout_pending 510will return 511.Dv FALSE 512even though the callout function may not have finished 513.Pq or even begun 514executing. 515The 516.Fn callout_active 517macro checks whether a callout is marked as 518.Em active , 519and the 520.Fn callout_deactivate 521macro clears the callout's 522.Em active 523flag. 524The callout subsystem marks a callout as 525.Em active 526when a timeout is set and it clears the 527.Em active 528flag in 529.Fn callout_stop 530and 531.Fn callout_drain , 532but it 533.Em does not 534clear it when a callout expires normally via the execution of the 535callout function. 536.Pp 537The 538.Fn callout_when 539function may be used to pre-calculate the absolute time at which the 540timeout should be run and the precision of the scheduled run time 541according to the required time 542.Fa sbt , 543precision 544.Fa precision , 545and additional adjustments requested by the 546.Fa flags 547argument. 548Flags accepted by the 549.Fn callout_when 550function are the same as flags for the 551.Fn callout_reset 552function. 553The resulting time is assigned to the variable pointed to by the 554.Fa sbt_res 555argument, and the resulting precision is assigned to 556.Fa *precision_res . 557When passing the results to 558.Fa callout_reset , 559add the 560.Va C_PRECALC 561flag to 562.Fa flags , 563to avoid incorrect re-adjustment. 564The function is intended for situations where precise time of the callout 565run should be known in advance, since 566trying to read this time from the callout structure itself after a 567.Fn callout_reset 568call is racy. 569.Ss "Avoiding Race Conditions" 570The callout subsystem invokes callout functions from its own thread 571context. 572Without some kind of synchronization, 573it is possible that a callout 574function will be invoked concurrently with an attempt to stop or reset 575the callout by another thread. 576In particular, since callout functions typically acquire a lock as 577their first action, the callout function may have already been invoked, 578but is blocked waiting for that lock at the time that another thread 579tries to reset or stop the callout. 580.Pp 581There are three main techniques for addressing these 582synchronization concerns. 583The first approach is preferred as it is the simplest: 584.Bl -enum -offset indent 585.It 586Callouts can be associated with a specific lock when they are initialized 587by 588.Fn callout_init_mtx , 589.Fn callout_init_rm , 590or 591.Fn callout_init_rw . 592When a callout is associated with a lock, 593the callout subsystem acquires the lock before the callout function is 594invoked. 595This allows the callout subsystem to transparently handle races between 596callout cancellation, 597scheduling, 598and execution. 599Note that the associated lock must be acquired before calling 600.Fn callout_stop 601or one of the 602.Fn callout_reset 603or 604.Fn callout_schedule 605functions to provide this safety. 606.Pp 607A callout initialized via 608.Fn callout_init 609with 610.Fa mpsafe 611set to zero is implicitly associated with the 612.Va Giant 613mutex. 614If 615.Va Giant 616is held when cancelling or rescheduling the callout, 617then its use will prevent races with the callout function. 618.It 619The return value from 620.Fn callout_stop 621.Po 622or the 623.Fn callout_reset 624and 625.Fn callout_schedule 626function families 627.Pc 628indicates whether or not the callout was removed. 629If it is known that the callout was set and the callout function has 630not yet executed, then a return value of 631.Dv FALSE 632indicates that the callout function is about to be called. 633For example: 634.Bd -literal -offset indent 635if (sc->sc_flags & SCFLG_CALLOUT_RUNNING) { 636 if (callout_stop(&sc->sc_callout)) { 637 sc->sc_flags &= ~SCFLG_CALLOUT_RUNNING; 638 /* successfully stopped */ 639 } else { 640 /* 641 * callout has expired and callout 642 * function is about to be executed 643 */ 644 } 645} 646.Ed 647.It 648The 649.Fn callout_pending , 650.Fn callout_active 651and 652.Fn callout_deactivate 653macros can be used together to work around the race conditions. 654When a callout's timeout is set, the callout subsystem marks the 655callout as both 656.Em active 657and 658.Em pending . 659When the timeout time arrives, the callout subsystem begins processing 660the callout by first clearing the 661.Em pending 662flag. 663It then invokes the callout function without changing the 664.Em active 665flag, and does not clear the 666.Em active 667flag even after the callout function returns. 668The mechanism described here requires the callout function itself to 669clear the 670.Em active 671flag using the 672.Fn callout_deactivate 673macro. 674The 675.Fn callout_stop 676and 677.Fn callout_drain 678functions always clear both the 679.Em active 680and 681.Em pending 682flags before returning. 683.Pp 684The callout function should first check the 685.Em pending 686flag and return without action if 687.Fn callout_pending 688returns 689.Dv TRUE . 690This indicates that the callout was rescheduled using 691.Fn callout_reset 692just before the callout function was invoked. 693If 694.Fn callout_active 695returns 696.Dv FALSE 697then the callout function should also return without action. 698This indicates that the callout has been stopped. 699Finally, the callout function should call 700.Fn callout_deactivate 701to clear the 702.Em active 703flag. 704For example: 705.Bd -literal -offset indent 706mtx_lock(&sc->sc_mtx); 707if (callout_pending(&sc->sc_callout)) { 708 /* callout was reset */ 709 mtx_unlock(&sc->sc_mtx); 710 return; 711} 712if (!callout_active(&sc->sc_callout)) { 713 /* callout was stopped */ 714 mtx_unlock(&sc->sc_mtx); 715 return; 716} 717callout_deactivate(&sc->sc_callout); 718/* rest of callout function */ 719.Ed 720.Pp 721Together with appropriate synchronization, such as the mutex used above, 722this approach permits the 723.Fn callout_stop 724and 725.Fn callout_reset 726functions to be used at any time without races. 727For example: 728.Bd -literal -offset indent 729mtx_lock(&sc->sc_mtx); 730callout_stop(&sc->sc_callout); 731/* The callout is effectively stopped now. */ 732.Ed 733.Pp 734If the callout is still pending then these functions operate normally, 735but if processing of the callout has already begun then the tests in 736the callout function cause it to return without further action. 737Synchronization between the callout function and other code ensures that 738stopping or resetting the callout will never be attempted while the 739callout function is past the 740.Fn callout_deactivate 741call. 742.Pp 743The above technique additionally ensures that the 744.Em active 745flag always reflects whether the callout is effectively enabled or 746disabled. 747If 748.Fn callout_active 749returns false, then the callout is effectively disabled, since even if 750the callout subsystem is actually just about to invoke the callout 751function, the callout function will return without action. 752.El 753.Pp 754There is one final race condition that must be considered when a 755callout is being stopped for the last time. 756In this case it may not be safe to let the callout function itself 757detect that the callout was stopped, since it may need to access 758data objects that have already been destroyed or recycled. 759To ensure that the callout is completely finished, a call to 760.Fn callout_drain 761should be used. 762In particular, 763a callout should always be drained prior to destroying its associated lock 764or releasing the storage for the callout structure. 765.Sh RETURN VALUES 766The 767.Fn callout_active 768macro returns the state of a callout's 769.Em active 770flag. 771.Pp 772The 773.Fn callout_pending 774macro returns the state of a callout's 775.Em pending 776flag. 777.Pp 778The 779.Fn callout_reset 780and 781.Fn callout_schedule 782function families return a value of one if the callout was pending before the new 783function invocation was scheduled. 784.Pp 785The 786.Fn callout_stop 787and 788.Fn callout_drain 789functions return a value of one if the callout was still pending when it was 790called, a zero if the callout could not be stopped and a negative one is it 791was either not running or has already completed. 792.Sh HISTORY 793.Fx 794initially used the long standing 795.Bx 796linked list 797callout mechanism which offered O(n) insertion and removal running time 798but did not generate or require handles for untimeout operations. 799.Pp 800.Fx 3.0 801introduced a new set of timeout and untimeout routines from 802.Nx 803based on the work of 804.An Adam M. Costello 805and 806.An George Varghese , 807published in a technical report entitled 808.%T "Redesigning the BSD Callout and Timer Facilities" 809and modified for inclusion in 810.Fx 811by 812.An Justin T. Gibbs . 813The original work on the data structures used in that implementation 814was published by 815.An G. Varghese 816and 817.An A. Lauck 818in the paper 819.%T "Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility" 820in the 821.%B "Proceedings of the 11th ACM Annual Symposium on Operating Systems Principles" . 822.Pp 823.Fx 3.3 824introduced the first implementations of 825.Fn callout_init , 826.Fn callout_reset , 827and 828.Fn callout_stop 829which permitted callers to allocate dedicated storage for callouts. 830This ensured that a callout would always fire unlike 831.Fn timeout 832which would silently fail if it was unable to allocate a callout. 833.Pp 834.Fx 5.0 835permitted callout handlers to be tagged as MPSAFE via 836.Fn callout_init . 837.Pp 838.Fx 5.3 839introduced 840.Fn callout_drain . 841.Pp 842.Fx 6.0 843introduced 844.Fn callout_init_mtx . 845.Pp 846.Fx 8.0 847introduced per-CPU callout wheels, 848.Fn callout_init_rw , 849and 850.Fn callout_schedule . 851.Pp 852.Fx 9.0 853changed the underlying timer interrupts used to drive callouts to prefer 854one-shot event timers instead of a periodic timer interrupt. 855.Pp 856.Fx 10.0 857switched the callout wheel to support tickless operation. 858These changes introduced 859.Vt sbintime_t 860and the 861.Fn callout_reset_sbt* 862family of functions. 863.Fx 10.0 also added 864.Dv C_DIRECT_EXEC 865and 866.Fn callout_init_rm . 867.Pp 868.Fx 10.2 869introduced the 870.Fn callout_schedule_sbt* 871family of functions. 872.Pp 873.Fx 11.0 874introduced 875.Fn callout_async_drain . 876.Fx 11.1 877introduced 878.Fn callout_when . 879.Fx 13.0 880removed 881.Vt timeout_t , 882.Fn timeout , 883and 884.Fn untimeout . 885