]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kern/thread_call.h
xnu-6153.141.1.tar.gz
[apple/xnu.git] / osfmk / kern / thread_call.h
1 /*
2 * Copyright (c) 1993-1995, 1999-2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
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
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 /*!
30 * @header thread_call.h
31 * @discussion Facilities for executing work asynchronously.
32 */
33
34 #ifndef _KERN_THREAD_CALL_H_
35 #define _KERN_THREAD_CALL_H_
36
37 #include <mach/mach_types.h>
38
39 #include <kern/clock.h>
40
41 #include <sys/cdefs.h>
42
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 * @constant THREAD_CALL_PRIORITY_KERNEL_HIGH Importance higher than most kernel
66 * threads.
67 */
68 typedef enum {
69 THREAD_CALL_PRIORITY_HIGH = 0,
70 THREAD_CALL_PRIORITY_KERNEL = 1,
71 THREAD_CALL_PRIORITY_USER = 2,
72 THREAD_CALL_PRIORITY_LOW = 3,
73 THREAD_CALL_PRIORITY_KERNEL_HIGH = 4
74 } thread_call_priority_t;
75
76 enum {
77 /* if call is re-submitted while the call is executing on a call thread, then delay the re-enqueue until it returns */
78 THREAD_CALL_OPTIONS_ONCE = 0x00000001,
79 #ifdef XNU_KERNEL_PRIVATE
80 /* execute call from the timer interrupt instead of from the thread call thread, private interface for IOTES workloop signaling */
81 THREAD_CALL_OPTIONS_SIGNAL = 0x00000002,
82 #endif /* XNU_KERNEL_PRIVATE */
83 };
84 typedef uint32_t thread_call_options_t;
85
86 __BEGIN_DECLS
87
88 /*!
89 * @function thread_call_enter
90 * @abstract Submit a thread call work item for immediate execution.
91 * @discussion If the work item is already scheduled for delayed execution, and it has
92 * not yet begun to run, that delayed invocation will be cancelled. Note that if a
93 * thread call is rescheduled from its own callback, then multiple invocations of the
94 * callback may be in flight at the same time.
95 * @result TRUE if the call was already pending for either delayed or immediate
96 * execution, FALSE otherwise.
97 * @param call The thread call to execute.
98 */
99 extern boolean_t thread_call_enter(
100 thread_call_t call);
101 /*!
102 * @function thread_call_enter1
103 * @abstract Submit a thread call work item for immediate execution, with an extra parameter.
104 * @discussion This routine is identical to thread_call_enter(), except that
105 * the second parameter to the callback is specified.
106 * @result TRUE if the call was already pending for either delayed or immediate
107 * execution, FALSE otherwise.
108 * @param call The thread call to execute.
109 * @param param1 Parameter to pass callback.
110 */
111 extern boolean_t thread_call_enter1(
112 thread_call_t call,
113 thread_call_param_t param1);
114
115 /*!
116 * @function thread_call_enter_delayed
117 * @abstract Submit a thread call to be executed at some point in the future.
118 * @discussion If the work item is already scheduled for delayed or immediate execution,
119 * and it has not yet begun to run, that invocation will be cancelled in favor of execution
120 * at the newly specified time. Note that if a thread call is rescheduled from its own callback,
121 * then multiple invocations of the callback may be in flight at the same time.
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 deadline Time, in absolute time units, at which to execute callback.
126 */
127 extern boolean_t thread_call_enter_delayed(
128 thread_call_t call,
129 uint64_t deadline);
130 /*!
131 * @function thread_call_enter1_delayed
132 * @abstract Submit a thread call to be executed at some point in the future, with an extra parameter.
133 * @discussion This routine is identical to thread_call_enter_delayed(),
134 * except that a second parameter to the callback is specified.
135 * @result TRUE if the call was already pending for either delayed or immediate
136 * execution, FALSE otherwise.
137 * @param call The thread call to execute.
138 * @param param1 Second parameter to callback.
139 * @param deadline Time, in absolute time units, at which to execute callback.
140 */
141 extern boolean_t thread_call_enter1_delayed(
142 thread_call_t call,
143 thread_call_param_t param1,
144 uint64_t deadline);
145 #ifdef XNU_KERNEL_PRIVATE
146
147 /*
148 * Flags to alter the default timer/timeout coalescing behavior
149 * on a per-thread_call basis.
150 *
151 * The SYS urgency classes indicate that the thread_call is not
152 * directly related to the current thread at the time the thread_call
153 * is entered, so it is ignored in the calculation entirely (only
154 * the subclass specified is used).
155 *
156 * The USER flags indicate that both the current thread scheduling and QoS
157 * attributes, in addition to the per-thread_call urgency specification,
158 * are used to establish coalescing behavior.
159 */
160 #define THREAD_CALL_DELAY_SYS_NORMAL TIMEOUT_URGENCY_SYS_NORMAL
161 #define THREAD_CALL_DELAY_SYS_CRITICAL TIMEOUT_URGENCY_SYS_CRITICAL
162 #define THREAD_CALL_DELAY_SYS_BACKGROUND TIMEOUT_URGENCY_SYS_BACKGROUND
163
164 #define THREAD_CALL_DELAY_USER_MASK TIMEOUT_URGENCY_USER_MASK
165 #define THREAD_CALL_DELAY_USER_NORMAL TIMEOUT_URGENCY_USER_NORMAL
166 #define THREAD_CALL_DELAY_USER_CRITICAL TIMEOUT_URGENCY_USER_CRITICAL
167 #define THREAD_CALL_DELAY_USER_BACKGROUND TIMEOUT_URGENCY_USER_BACKGROUND
168
169 #define THREAD_CALL_DELAY_URGENCY_MASK TIMEOUT_URGENCY_MASK
170
171 /*
172 * Indicate that a specific leeway value is being provided (otherwise
173 * the leeway parameter is ignored). The supplied value can currently
174 * only be used to extend the leeway calculated internally from the
175 * urgency class provided.
176 */
177 #define THREAD_CALL_DELAY_LEEWAY TIMEOUT_URGENCY_LEEWAY
178
179 /*
180 * Indicates that the time parameters should be interpreted as
181 * mach_continuous_time values, rather than mach_absolute_time and the timer
182 * be programmed to fire based on continuous time.
183 */
184 #define THREAD_CALL_CONTINUOUS 0x100
185
186 /*!
187 * @function thread_call_enter_delayed_with_leeway
188 * @abstract Submit a thread call to be executed at some point in the future.
189 * @discussion If the work item is already scheduled for delayed or immediate execution,
190 * and it has not yet begun to run, that invocation will be cancelled in favor of execution
191 * at the newly specified time. Note that if a thread call is rescheduled from its own callback,
192 * then multiple invocations of the callback may be in flight at the same time.
193 * @result TRUE if the call was already pending for either delayed or immediate
194 * execution, FALSE otherwise.
195 * @param call The thread call to execute.
196 * @param param1 Second parameter to callback.
197 * @param deadline Time, in absolute time units, at which to execute callback.
198 * @param leeway Time delta, in absolute time units, which sets range of time allowing kernel
199 * to decide appropriate time to run.
200 * @param flags configuration for timers in kernel.
201 */
202 extern boolean_t thread_call_enter_delayed_with_leeway(
203 thread_call_t call,
204 thread_call_param_t param1,
205 uint64_t deadline,
206 uint64_t leeway,
207 uint32_t flags);
208
209 #endif /* XNU_KERNEL_PRIVATE */
210
211 /*!
212 * @function thread_call_cancel
213 * @abstract Attempt to cancel a pending invocation of a thread call.
214 * @discussion Attempt to cancel a thread call which has been scheduled
215 * for execution with a thread_call_enter* variant. If the call has not
216 * yet begun executing, the pending invocation will be cancelled and TRUE
217 * will be returned. If the work item has already begun executing,
218 * thread_call_cancel will return FALSE immediately; the callback may be
219 * about to run, currently running, or already done executing.
220 * @result TRUE if the call was successfully cancelled, FALSE otherwise.
221 */
222 extern boolean_t thread_call_cancel(
223 thread_call_t call);
224 /*!
225 * @function thread_call_cancel_wait
226 * @abstract Attempt to cancel a pending invocation of a thread call.
227 * If unable to cancel, wait for current invocation to finish.
228 * @discussion Attempt to cancel a thread call which has been scheduled
229 * for execution with a thread_call_enter* variant. If the call has not
230 * yet begun executing, the pending invocation will be cancelled and TRUE
231 * will be returned. If the work item has already begun executing,
232 * thread_call_cancel_wait waits for the most recent invocation to finish. When
233 * called on a work item which has already finished, it will return FALSE immediately.
234 * Note that this routine can only be used on thread calls set up with either
235 * thread_call_allocate or thread_call_allocate_with_priority, and that invocations
236 * of the thread call <i>after</i> the current invocation may be in flight when
237 * thread_call_cancel_wait returns.
238 * @result TRUE if the call was successfully cancelled, FALSE otherwise.
239 */
240 extern boolean_t thread_call_cancel_wait(
241 thread_call_t call);
242
243 /*!
244 * @function thread_call_allocate
245 * @abstract Allocate a thread call to execute with default (high) priority.
246 * @discussion Allocates a thread call that will run with properties of
247 * THREAD_CALL_PRIORITY_HIGH, binding the first parameter to the callback.
248 * @param func Callback to invoke when thread call is scheduled.
249 * @param param0 First argument ot pass to callback.
250 * @result Thread call which can be passed to thread_call_enter variants.
251 */
252 extern thread_call_t thread_call_allocate(
253 thread_call_func_t func,
254 thread_call_param_t param0);
255
256 /*!
257 * @function thread_call_allocate_with_priority
258 * @abstract Allocate a thread call to execute with a specified priority.
259 * @discussion Identical to thread_call_allocate, except that priority
260 * is specified by caller.
261 * @param func Callback to invoke when thread call is scheduled.
262 * @param param0 First argument to pass to callback.
263 * @param pri Priority of item.
264 * @result Thread call which can be passed to thread_call_enter variants.
265 */
266 extern thread_call_t thread_call_allocate_with_priority(
267 thread_call_func_t func,
268 thread_call_param_t param0,
269 thread_call_priority_t pri);
270
271 /*!
272 * @function thread_call_allocate_with_options
273 * @abstract Allocate a thread call to execute with a specified priority.
274 * @discussion Identical to thread_call_allocate, except that priority
275 * and options are specified by caller.
276 * @param func Callback to invoke when thread call is scheduled.
277 * @param param0 First argument to pass to callback.
278 * @param pri Priority of item.
279 * @param options Options for item.
280 * @result Thread call which can be passed to thread_call_enter variants.
281 */
282 extern thread_call_t thread_call_allocate_with_options(
283 thread_call_func_t func,
284 thread_call_param_t param0,
285 thread_call_priority_t pri,
286 thread_call_options_t options);
287
288 #ifdef KERNEL_PRIVATE
289 /*!
290 * @function thread_call_allocate_with_qos
291 * @abstract Allocate a thread call to execute with a specified QoS.
292 * @discussion Identical to thread_call_allocate_with_options, except it uses the QoS namespace.
293 * Private interface for pthread kext.
294 * @param func Callback to invoke when thread call is scheduled.
295 * @param param0 First argument to pass to callback.
296 * @param qos_tier QoS tier to execute callback at (as in THREAD_QOS_POLICY)
297 * @param options flags from thread_call_options_t to influence the thread call behavior
298 * @result Thread call which can be passed to thread_call_enter variants.
299 */
300 extern thread_call_t
301 thread_call_allocate_with_qos(thread_call_func_t func,
302 thread_call_param_t param0,
303 int qos_tier,
304 thread_call_options_t options);
305
306 /*!
307 * @function thread_call_wait_once
308 * @abstract Wait for a THREAD_CALL_OPTIONS_ONCE call to finish executing if it is executing
309 * @discussion Only works on THREAD_CALL_OPTIONS_ONCE calls
310 * @param call The thread call to wait for
311 * @result True if it waited, false if it did not wait
312 */
313 extern boolean_t
314 thread_call_wait_once(thread_call_t call);
315 #endif /* KERNEL_PRIVATE */
316
317 /*!
318 * @function thread_call_free
319 * @abstract Release a thread call.
320 * @discussion Should only be used on thread calls allocated with thread_call_allocate
321 * or thread_call_allocate_with_priority. Once thread_call_free has been called,
322 * no other operations may be performed on a thread call. If the thread call is
323 * currently pending, thread_call_free will return FALSE and will have no effect.
324 * Calling thread_call_free from a thread call's own callback is safe; the work
325 * item is not considering "pending" at that point.
326 * @result TRUE if the thread call has been successfully released, else FALSE.
327 * @param call The thread call to release.
328 */
329 extern boolean_t thread_call_free(
330 thread_call_t call);
331
332 /*!
333 * @function thread_call_isactive
334 * @abstract Determine whether a thread call is pending or currently executing.
335 * @param call Thread call to examine.
336 * @result TRUE if the thread call is either scheduled for execution (immediately
337 * or at some point in the future) or is currently executing.
338 */
339 boolean_t thread_call_isactive(
340 thread_call_t call);
341 __END_DECLS
342
343 #ifdef MACH_KERNEL_PRIVATE
344
345 #include <kern/call_entry.h>
346
347 typedef enum {
348 THREAD_CALL_INDEX_HIGH = 0,
349 THREAD_CALL_INDEX_KERNEL = 1,
350 THREAD_CALL_INDEX_USER = 2,
351 THREAD_CALL_INDEX_LOW = 3,
352 THREAD_CALL_INDEX_KERNEL_HIGH = 4,
353 THREAD_CALL_INDEX_QOS_UI = 5,
354 THREAD_CALL_INDEX_QOS_IN = 6,
355 THREAD_CALL_INDEX_QOS_UT = 7,
356 THREAD_CALL_INDEX_MAX = 8, /* count of thread call indexes */
357 } thread_call_index_t;
358
359 struct thread_call {
360 struct call_entry tc_call; /* Must be first for queue macros */
361 uint64_t tc_submit_count;
362 uint64_t tc_finish_count;
363 uint64_t tc_ttd; /* Time to deadline at creation */
364 uint64_t tc_soft_deadline;
365 thread_call_index_t tc_index;
366 uint32_t tc_flags;
367 int32_t tc_refs;
368 };
369
370 #define THREAD_CALL_ALLOC 0x01 /* memory owned by thread_call.c */
371 #define THREAD_CALL_WAIT 0x02 /* thread waiting for call to finish running */
372 #define THREAD_CALL_DELAYED 0x04 /* deadline based */
373 #define THREAD_CALL_RUNNING 0x08 /* currently executing on a thread */
374 #define THREAD_CALL_SIGNAL 0x10 /* call from timer interrupt instead of thread */
375 #define THREAD_CALL_ONCE 0x20 /* pend the enqueue if re-armed while running */
376 #define THREAD_CALL_RESCHEDULE 0x40 /* enqueue is pending due to re-arm while running */
377 #define THREAD_CALL_RATELIMITED TIMEOUT_URGENCY_RATELIMITED /* 0x80 */
378 /* THREAD_CALL_CONTINUOUS 0x100 */
379
380 typedef struct thread_call thread_call_data_t;
381
382 extern void thread_call_initialize(void);
383
384 extern void thread_call_setup(
385 thread_call_t call,
386 thread_call_func_t func,
387 thread_call_param_t param0);
388
389 extern void thread_call_delayed_timer_rescan_all(void);
390 #endif /* MACH_KERNEL_PRIVATE */
391
392 #ifdef XNU_KERNEL_PRIVATE
393
394 __BEGIN_DECLS
395
396 /*
397 * These routines are equivalent to their thread_call_enter_XXX
398 * variants, only the thread_call_t is allocated out of a
399 * fixed preallocated pool of memory, and will panic if the pool
400 * is exhausted.
401 */
402
403 extern void thread_call_func_delayed(
404 thread_call_func_t func,
405 thread_call_param_t param,
406 uint64_t deadline);
407
408 extern void thread_call_func_delayed_with_leeway(
409 thread_call_func_t func,
410 thread_call_param_t param,
411 uint64_t deadline,
412 uint64_t leeway,
413 uint32_t flags);
414
415 /*
416 * This iterates all of the pending or delayed thread calls in the group,
417 * which is really inefficient.
418 *
419 * This is deprecated, switch to an allocated thread call instead.
420 */
421 extern boolean_t thread_call_func_cancel(
422 thread_call_func_t func,
423 thread_call_param_t param,
424 boolean_t cancel_all);
425
426 /*
427 * Called on the wake path to adjust the thread callouts running in mach_continuous_time
428 */
429 void adjust_cont_time_thread_calls(void);
430
431 __END_DECLS
432
433 #endif /* XNU_KERNEL_PRIVATE */
434
435 #endif /* _KERN_THREAD_CALL_H_ */