]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
c910b4d9 | 2 | * Copyright (c) 1993-1995, 1999-2008 Apple Inc. All rights reserved. |
1c79356b | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
2d21ac55 A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
1c79356b | 27 | */ |
316670eb A |
28 | |
29 | /*! | |
30 | @header thread_call.h | |
31 | @discussion Facilities for executing work asynchronously. | |
1c79356b A |
32 | */ |
33 | ||
34 | #ifndef _KERN_THREAD_CALL_H_ | |
35 | #define _KERN_THREAD_CALL_H_ | |
36 | ||
1c79356b A |
37 | #include <mach/mach_types.h> |
38 | ||
0b4e3aa0 A |
39 | #include <kern/clock.h> |
40 | ||
91447636 A |
41 | #include <sys/cdefs.h> |
42 | ||
316670eb A |
43 | struct thread_call; |
44 | typedef struct thread_call *thread_call_t; | |
45 | ||
46 | typedef void *thread_call_param_t; | |
47 | typedef void (*thread_call_func_t)( | |
48 | thread_call_param_t param0, | |
49 | thread_call_param_t param1); | |
50 | /*! | |
51 | @enum thread_call_priority_t | |
52 | @discussion Thread call priorities should not be assumed to have any specific | |
53 | numerical value; they should be interpreted as importances or roles for work | |
54 | items, priorities for which will be reasonably managed by the subsystem. | |
55 | @constant THREAD_CALL_PRIORITY_HIGH Importance above everything but realtime. | |
56 | Thread calls allocated with this priority execute at extremely high priority, | |
57 | above everything but realtime threads. They are generally executed in serial. | |
58 | Though they may execute concurrently under some circumstances, no fan-out is implied. | |
59 | These work items should do very small amounts of work or risk disrupting system | |
60 | responsiveness. | |
61 | @constant THREAD_CALL_PRIORITY_KERNEL Importance similar to that of normal kernel | |
62 | threads. | |
63 | @constant THREAD_CALL_PRIORITY_USER Importance similar to that of normal user threads. | |
64 | @constant THREAD_CALL_PRIORITY_LOW Very low importance. | |
65 | */ | |
66 | typedef enum { | |
67 | THREAD_CALL_PRIORITY_HIGH = 0, | |
68 | THREAD_CALL_PRIORITY_KERNEL = 1, | |
69 | THREAD_CALL_PRIORITY_USER = 2, | |
70 | THREAD_CALL_PRIORITY_LOW = 3 | |
71 | } thread_call_priority_t; | |
72 | ||
91447636 | 73 | __BEGIN_DECLS |
1c79356b | 74 | |
316670eb A |
75 | /*! |
76 | @function thread_call_enter | |
77 | @abstract Submit a thread call work item for immediate execution. | |
78 | @discussion If the work item is already scheduled for delayed execution, and it has | |
79 | not yet begun to run, that delayed invocation will be cancelled. Note that if a | |
80 | thread call is rescheduled from its own callback, then multiple invocations of the | |
81 | callback may be in flight at the same time. | |
82 | @result TRUE if the call was already pending for either delayed or immediate | |
83 | execution, FALSE otherwise. | |
84 | @param call The thread call to execute. | |
85 | */ | |
c910b4d9 A |
86 | extern boolean_t thread_call_enter( |
87 | thread_call_t call); | |
316670eb A |
88 | /*! |
89 | @function thread_call_enter1 | |
90 | @abstract Submit a thread call work item for immediate execution, with an extra parameter. | |
91 | @discussion This routine is identical to thread_call_enter(), except that | |
92 | the second parameter to the callback is specified. | |
93 | @result TRUE if the call was already pending for either delayed or immediate | |
94 | execution, FALSE otherwise. | |
95 | @param call The thread call to execute. | |
96 | @param param1 Parameter to pass callback. | |
97 | */ | |
c910b4d9 | 98 | extern boolean_t thread_call_enter1( |
316670eb A |
99 | thread_call_t call, |
100 | thread_call_param_t param1); | |
101 | ||
102 | /*! | |
103 | @function thread_call_enter_delayed | |
104 | @abstract Submit a thread call to be executed at some point in the future. | |
105 | @discussion If the work item is already scheduled for delayed or immediate execution, | |
106 | and it has not yet begun to run, that invocation will be cancelled in favor of execution | |
107 | at the newly specified time. Note that if a thread call is rescheduled from its own callback, | |
108 | then multiple invocations of the callback may be in flight at the same time. | |
109 | @result TRUE if the call was already pending for either delayed or immediate | |
110 | execution, FALSE otherwise. | |
111 | @param call The thread call to execute. | |
112 | @param deadline Time, in absolute time units, at which to execute callback. | |
113 | */ | |
c910b4d9 A |
114 | extern boolean_t thread_call_enter_delayed( |
115 | thread_call_t call, | |
316670eb A |
116 | uint64_t deadline); |
117 | /*! | |
118 | @function thread_call_enter1_delayed | |
119 | @abstract Submit a thread call to be executed at some point in the future, with an extra parameter. | |
120 | @discussion This routine is identical to thread_call_enter_delayed(), | |
121 | except that a second parameter to the callback is specified. | |
122 | @result TRUE if the call was already pending for either delayed or immediate | |
123 | execution, FALSE otherwise. | |
124 | @param call The thread call to execute. | |
125 | @param param1 Second parameter to callback. | |
126 | @param deadline Time, in absolute time units, at which to execute callback. | |
127 | */ | |
c910b4d9 | 128 | extern boolean_t thread_call_enter1_delayed( |
316670eb A |
129 | thread_call_t call, |
130 | thread_call_param_t param1, | |
131 | uint64_t deadline); | |
39236c6e A |
132 | #ifdef XNU_KERNEL_PRIVATE |
133 | ||
134 | /* | |
135 | * Flags to alter the default timer/timeout coalescing behavior | |
136 | * on a per-thread_call basis. | |
137 | * | |
138 | * The SYS urgency classes indicate that the thread_call is not | |
139 | * directly related to the current thread at the time the thread_call | |
140 | * is entered, so it is ignored in the calculation entirely (only | |
141 | * the subclass specified is used). | |
142 | * | |
143 | * The USER flags indicate that both the current thread scheduling and QoS | |
144 | * attributes, in addition to the per-thread_call urgency specification, | |
145 | * are used to establish coalescing behavior. | |
146 | */ | |
147 | #define THREAD_CALL_DELAY_SYS_NORMAL TIMEOUT_URGENCY_SYS_NORMAL | |
148 | #define THREAD_CALL_DELAY_SYS_CRITICAL TIMEOUT_URGENCY_SYS_CRITICAL | |
149 | #define THREAD_CALL_DELAY_SYS_BACKGROUND TIMEOUT_URGENCY_SYS_BACKGROUND | |
150 | ||
151 | #define THREAD_CALL_DELAY_USER_MASK TIMEOUT_URGENCY_USER_MASK | |
152 | #define THREAD_CALL_DELAY_USER_NORMAL TIMEOUT_URGENCY_USER_NORMAL | |
153 | #define THREAD_CALL_DELAY_USER_CRITICAL TIMEOUT_URGENCY_USER_CRITICAL | |
154 | #define THREAD_CALL_DELAY_USER_BACKGROUND TIMEOUT_URGENCY_USER_BACKGROUND | |
155 | ||
156 | #define THREAD_CALL_DELAY_URGENCY_MASK TIMEOUT_URGENCY_MASK | |
157 | ||
158 | /* | |
159 | * Indicate that a specific leeway value is being provided (otherwise | |
160 | * the leeway parameter is ignored). The supplied value can currently | |
161 | * only be used to extend the leeway calculated internally from the | |
162 | * urgency class provided. | |
163 | */ | |
164 | #define THREAD_CALL_DELAY_LEEWAY TIMEOUT_URGENCY_LEEWAY | |
165 | ||
166 | /*! | |
167 | @function thread_call_enter_delayed_with_leeway | |
168 | @abstract Submit a thread call to be executed at some point in the future. | |
169 | @discussion If the work item is already scheduled for delayed or immediate execution, | |
170 | and it has not yet begun to run, that invocation will be cancelled in favor of execution | |
171 | at the newly specified time. Note that if a thread call is rescheduled from its own callback, | |
172 | then multiple invocations of the callback may be in flight at the same time. | |
173 | @result TRUE if the call was already pending for either delayed or immediate | |
174 | execution, FALSE otherwise. | |
175 | @param call The thread call to execute. | |
176 | @param param1 Second parameter to callback. | |
177 | @param deadline Time, in absolute time units, at which to execute callback. | |
178 | @param leeway Time delta, in absolute time units, which sets range of time allowing kernel | |
179 | to decide appropriate time to run. | |
180 | @param flags configuration for timers in kernel. | |
181 | */ | |
182 | extern boolean_t thread_call_enter_delayed_with_leeway( | |
183 | thread_call_t call, | |
184 | thread_call_param_t param1, | |
185 | uint64_t deadline, | |
186 | uint64_t leeway, | |
187 | uint32_t flags); | |
188 | ||
189 | #endif /* XNU_KERNEL_PRIVATE */ | |
316670eb A |
190 | |
191 | /*! | |
192 | @function thread_call_cancel | |
193 | @abstract Attempt to cancel a pending invocation of a thread call. | |
194 | @discussion Attempt to cancel a thread call which has been scheduled | |
195 | for execution with a thread_call_enter* variant. If the call has not | |
196 | yet begun executing, the pending invocation will be cancelled and TRUE | |
197 | will be returned. If the work item has already begun executing, | |
198 | thread_call_cancel will return FALSE immediately; the callback may be | |
199 | about to run, currently running, or already done executing. | |
200 | @result TRUE if the call was successfully cancelled, FALSE otherwise. | |
201 | */ | |
c910b4d9 A |
202 | extern boolean_t thread_call_cancel( |
203 | thread_call_t call); | |
316670eb A |
204 | /*! |
205 | @function thread_call_cancel_wait | |
206 | @abstract Attempt to cancel a pending invocation of a thread call. | |
207 | If unable to cancel, wait for current invocation to finish. | |
208 | @discussion Attempt to cancel a thread call which has been scheduled | |
209 | for execution with a thread_call_enter* variant. If the call has not | |
210 | yet begun executing, the pending invocation will be cancelled and TRUE | |
211 | will be returned. If the work item has already begun executing, | |
212 | thread_call_cancel_wait waits for the most recent invocation to finish. When | |
213 | called on a work item which has already finished, it will return FALSE immediately. | |
214 | Note that this routine can only be used on thread calls set up with either | |
215 | thread_call_allocate or thread_call_allocate_with_priority, and that invocations | |
216 | of the thread call <i>after</i> the current invocation may be in flight when | |
217 | thread_call_cancel_wait returns. | |
218 | @result TRUE if the call was successfully cancelled, FALSE otherwise. | |
219 | */ | |
220 | extern boolean_t thread_call_cancel_wait( | |
221 | thread_call_t call); | |
c910b4d9 | 222 | |
316670eb A |
223 | /*! |
224 | @function thread_call_allocate | |
225 | @abstract Allocate a thread call to execute with default (high) priority. | |
226 | @discussion Allocates a thread call that will run with properties of | |
227 | THREAD_CALL_PRIORITY_HIGH, binding the first parameter to the callback. | |
228 | @param func Callback to invoke when thread call is scheduled. | |
229 | @param param0 First argument ot pass to callback. | |
230 | @result Thread call which can be passed to thread_call_enter variants. | |
231 | */ | |
c910b4d9 | 232 | extern thread_call_t thread_call_allocate( |
316670eb A |
233 | thread_call_func_t func, |
234 | thread_call_param_t param0); | |
235 | ||
236 | /*! | |
237 | @function thread_call_allocate_with_priority | |
238 | @abstract Allocate a thread call to execute with a specified priority. | |
239 | @discussion Identical to thread_call_allocate, except that priority | |
240 | is specified by caller. | |
241 | @param func Callback to invoke when thread call is scheduled. | |
242 | @param param0 First argument to pass to callback. | |
243 | @param pri Priority of item. | |
244 | @result Thread call which can be passed to thread_call_enter variants. | |
245 | */ | |
246 | extern thread_call_t thread_call_allocate_with_priority( | |
247 | thread_call_func_t func, | |
248 | thread_call_param_t param0, | |
249 | thread_call_priority_t pri); | |
250 | ||
251 | /*! | |
252 | @function thread_call_free | |
253 | @abstract Release a thread call. | |
254 | @discussion Should only be used on thread calls allocated with thread_call_allocate | |
255 | or thread_call_allocate_with_priority. Once thread_call_free has been called, | |
256 | no other operations may be performed on a thread call. If the thread call is | |
257 | currently pending, thread_call_free will return FALSE and will have no effect. | |
258 | Calling thread_call_free from a thread call's own callback is safe; the work | |
259 | item is not considering "pending" at that point. | |
260 | @result TRUE if the thread call has been successfully released, else FALSE. | |
261 | @param call The thread call to release. | |
262 | */ | |
263 | extern boolean_t thread_call_free( | |
264 | thread_call_t call); | |
1c79356b | 265 | |
316670eb A |
266 | /*! |
267 | @function thread_call_isactive | |
268 | @abstract Determine whether a thread call is pending or currently executing. | |
269 | @param call Thread call to examine. | |
270 | @result TRUE if the thread call is either scheduled for execution (immediately | |
271 | or at some point in the future) or is currently executing. | |
272 | */ | |
273 | boolean_t thread_call_isactive( | |
274 | thread_call_t call); | |
91447636 A |
275 | __END_DECLS |
276 | ||
277 | #ifdef MACH_KERNEL_PRIVATE | |
278 | ||
279 | #include <kern/call_entry.h> | |
280 | ||
316670eb A |
281 | struct thread_call { |
282 | struct call_entry tc_call; /* Must be first */ | |
283 | uint64_t tc_submit_count; | |
284 | uint64_t tc_finish_count; | |
39236c6e A |
285 | uint64_t ttd; /* Time to deadline at creation */ |
286 | uint64_t tc_soft_deadline; | |
287 | thread_call_priority_t tc_pri; | |
316670eb A |
288 | uint32_t tc_flags; |
289 | int32_t tc_refs; | |
290 | }; | |
291 | ||
292 | #define THREAD_CALL_ALLOC 0x01 | |
293 | #define THREAD_CALL_WAIT 0x02 | |
39236c6e | 294 | #define THREAD_CALL_DELAYED 0x04 |
fe8ab488 | 295 | #define THREAD_CALL_RATELIMITED TIMEOUT_URGENCY_RATELIMITED |
316670eb A |
296 | |
297 | typedef struct thread_call thread_call_data_t; | |
91447636 | 298 | |
c910b4d9 | 299 | extern void thread_call_initialize(void); |
91447636 | 300 | |
c910b4d9 A |
301 | extern void thread_call_setup( |
302 | thread_call_t call, | |
303 | thread_call_func_t func, | |
304 | thread_call_param_t param0); | |
91447636 | 305 | |
39236c6e | 306 | extern void thread_call_delayed_timer_rescan_all(void); |
91447636 A |
307 | #endif /* MACH_KERNEL_PRIVATE */ |
308 | ||
39236c6e | 309 | #ifdef XNU_KERNEL_PRIVATE |
9bccf70c | 310 | |
91447636 | 311 | __BEGIN_DECLS |
9bccf70c | 312 | |
1c79356b | 313 | /* |
39236c6e A |
314 | * These routines are equivalent to their thread_call_enter_XXX |
315 | * variants, only the thread_call_t is allocated out of a | |
316 | * fixed preallocated pool of memory, and will panic if the pool | |
317 | * is exhausted. | |
1c79356b | 318 | */ |
9bccf70c | 319 | |
c910b4d9 A |
320 | extern void thread_call_func_delayed( |
321 | thread_call_func_t func, | |
322 | thread_call_param_t param, | |
316670eb | 323 | uint64_t deadline); |
c910b4d9 | 324 | |
39236c6e A |
325 | extern void thread_call_func_delayed_with_leeway( |
326 | thread_call_func_t func, | |
327 | thread_call_param_t param, | |
328 | uint64_t deadline, | |
329 | uint64_t leeway, | |
330 | uint32_t flags); | |
b0d623f7 A |
331 | |
332 | extern boolean_t thread_call_func_cancel( | |
316670eb A |
333 | thread_call_func_t func, |
334 | thread_call_param_t param, | |
335 | boolean_t cancel_all); | |
91447636 A |
336 | __END_DECLS |
337 | ||
39236c6e | 338 | #endif /* XNU_KERNEL_PRIVATE */ |
0b4e3aa0 | 339 | |
91447636 | 340 | #endif /* _KERN_THREAD_CALL_H_ */ |