1.\" $OpenBSD: clockintr_bind.9,v 1.1 2024/02/24 16:21:32 cheloha Exp $ 2.\" 3.\" Copyright (c) 2023-2024 Scott Cheloha <cheloha@openbsd.org> 4.\" 5.\" Permission to use, copy, modify, and distribute this software for any 6.\" purpose with or without fee is hereby granted, provided that the above 7.\" copyright notice and this permission notice appear in all copies. 8.\" 9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16.\" 17.Dd $Mdocdate: February 24 2024 $ 18.Dt CLOCKINTR_BIND 9 19.Os 20.Sh NAME 21.Nm clockintr_bind , 22.Nm clockintr_schedule , 23.Nm clockintr_advance , 24.Nm clockintr_cancel , 25.Nm clockintr_unbind , 26.Nm clockintr_stagger , 27.Nm clockrequest_advance 28.Nd execute a function in a clock interrupt context 29.Sh SYNOPSIS 30.In sys/clockintr.h 31.Ft void 32.Fo clockintr_bind 33.Fa "struct clockintr *cl" 34.Fa "struct cpu_info *cpu" 35.Fa "void (*callback)(struct clockrequest *cr, void *cf, void *arg)" 36.Fa "void *arg" 37.Fc 38.Ft void 39.Fo clockintr_schedule 40.Fa "struct clockintr *cl" 41.Fa "uint64_t abs" 42.Fc 43.Ft uint64_t 44.Fo clockintr_advance 45.Fa "struct clockintr *cl" 46.Fa "uint64_t interval" 47.Fc 48.Ft void 49.Fo clockintr_cancel 50.Fa "struct clockintr *cl" 51.Fc 52.Ft void 53.Fo clockintr_unbind 54.Fa "struct clockintr *cl" 55.Fa "uint32_t flags" 56.Fc 57.Ft void 58.Fo clockintr_stagger 59.Fa "struct clockintr *cl" 60.Fa "uint64_t interval" 61.Fa "uint32_t numer" 62.Fa "uint32_t denom" 63.Fc 64.Ft uint64_t 65.Fo clockrequest_advance 66.Fa "struct clockrequest *cr" 67.Fa "uint64_t interval" 68.Fc 69.\" .Fn clockrequest_advance_random is intentionally undocumented. 70.\" It may be removed in the future. New code should not use it. 71.Sh DESCRIPTION 72The clock interrupt subsystem schedules functions for asynchronous execution 73from the clock interrupt context on a particular CPU. 74.Pp 75Clock interrupts are well-suited for timekeeping, 76scheduling, 77and statistical profiling. 78Applications with more relaxed latency requirements should use timeouts 79to schedule asynchronous execution; 80see 81.Xr timeout_add 9 82for details. 83.Pp 84The 85.Fn clockintr_bind 86function initializes the clock interrupt object 87.Fa cl . 88When 89.Fa cl 90expires, 91its 92.Fa callback 93function is executed from the 94.Dv IPL_CLOCK 95context on its host 96.Fa cpu 97without any locks or mutexes. 98The callback function must not block. 99Its parameters are as follows: 100.Bl -tag -width indent 101.It Fa cr 102A private 103.Vt clockrequest 104object. 105May be used to request rescheduling; 106see 107.Fn clockrequest_advance 108below. 109.It Fa cf 110The 111.Fa cpu Ns 's 112current machine-dependent clockframe. 113.It Fa arg 114The 115.Fa arg 116given to 117.Fn clockintr_bind . 118.El 119.Pp 120The memory pointed to by 121.Fa cl 122must be zeroed before it is first bound. 123It is an error to use 124.Fa cl 125as argument to any other function in the 126.Vt clockintr 127API before it is bound. 128It is an error to rebind 129.Fa cl 130without first unbinding it; 131see 132.Fn clockintr_unbind 133below. 134.Pp 135The 136.Fn clockintr_schedule 137function schedules 138.Fa cl 139to expire at the absolute time 140.Fa abs 141on the system uptime clock. 142The subsystem will never execute 143.Fa cl Ns 's 144callback function before this expiration time, 145though its execution may be delayed by other activity on the system. 146.Pp 147The 148.Fn clockintr_advance 149function schedules 150.Fa cl 151to expire at the next terminus of the given 152.Fa interval , 153a non-zero count of nanoseconds, 154relative to 155.Fa cl Ns 's 156current expiration time. 157Periodic clock interrupts should be scheduled with 158.Fn clockintr_advance 159to keep the execution period from drifting. 160.Pp 161The 162.Fn clockintr_cancel 163function cancels any pending expiration of 164.Fa cl . 165.Pp 166The 167.Fn clockintr_unbind 168function cancels any pending expiration of 169.Fa cl 170and severs the binding between 171.Fa cl 172and its host 173.Fa cpu . 174Upon return, 175.Fa cl 176may be rebound with 177.Fn clockintr_bind . 178The call may be configured with zero or more of the following 179.Fa flags : 180.Bl -tag -width CL_BARRIER 181.It Dv CL_BARRIER 182If 183.Fa cl Ns 's 184callback function is executing, 185block until it returns. 186By default, 187the caller does not block. 188Useful when 189.Fa arg 190is a shared reference. 191.El 192.Pp 193The 194.Fn clockintr_stagger 195function resets 196.Fa cl Ns 's 197expiration time to a fraction of the given 198.Fa interval , 199a count of nanoseconds. 200Specifically, 201.Fa cl Ns 's 202expiration time is reset to 203.Pq Fa interval Ms / Fa denom Ms * Fa numer . 204Periodic clock interrupts bound to multiple CPUs may be staggered 205to reduce the likelihood that their callback functions will execute 206simultaneously and compete for a shared resource. 207It is an error if 208.Fa numer 209is greater than or equal to 210.Fa denom . 211It is an error if 212.Fa cl 213is already scheduled to expire. 214.Pp 215The 216.Fn clockrequest_advance 217function is similar to 218.Fn clockintr_advance , 219except that 220(a) it may only be called during the execution of a 221.Fa callback 222function, 223(b) it accepts a 224.Vt clockrequest 225pointer as argument, 226and (c) scheduling requests submitted with the interface are not fulfilled 227until the callback function returns. 228When the callback function returns, 229scheduling requests are only committed to the underlying clock interrupt 230object if that object was not manipulated during the execution of the 231callback function. 232Otherwise, 233outstanding requests are discarded. 234.Sh CONTEXT 235The 236.Fn clockintr_bind 237function may only be called from process context. 238.Pp 239The 240.Fn clockintr_advance , 241.Fn clockintr_cancel , 242.Fn clockintr_schedule , 243and 244.Fn clockintr_stagger 245functions may be called from process context or from interrupt context. 246.Pp 247The 248.Fn clockintr_unbind 249function may normally be called from process context or from interrupt context. 250However, 251if the 252.Dv CL_BARRIER 253flag is set in 254.Fa flags , 255the function may only be called from process context. 256.Pp 257The 258.Fn clockrequest_advance 259function may only be called during execution of a 260.Fa callback 261function. 262.Sh RETURN VALUES 263The 264.Fn clockintr_advance 265and 266.Fn clockrequest_advance 267functions return the number of 268.Fa interval Ns s 269that have elapsed since 270.Fa cl 271was scheduled to expire, 272or zero if 273.Fa cl 274has not yet expired. 275.Sh CODE REFERENCES 276.Pa sys/kern/kern_clockintr.c 277.Sh SEE ALSO 278.Xr microtime 9 , 279.Xr spl 9 , 280.Xr timeout 9 281.Rs 282.%A Richard McDougall 283.%A Jim Mauro 284.%B Solaris Internals: Solaris 10 and OpenSolaris Kernel Architecture 285.%I Prentice Hall 286.%I Sun Microsystems Press 287.%D 2nd Edition, 2007 288.%P pp. 912\(en925 289.Re 290.Sh HISTORY 291The 292.Vt clockintr 293and 294.Vt clockrequest 295APIs first appeared in 296.Ox 7.5 . 297