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