+#include <sys/cdefs.h>
+
+struct thread_call;
+typedef struct thread_call *thread_call_t;
+
+typedef void *thread_call_param_t;
+typedef void (*thread_call_func_t)(
+ thread_call_param_t param0,
+ thread_call_param_t param1);
+/*!
+ * @enum thread_call_priority_t
+ * @discussion Thread call priorities should not be assumed to have any specific
+ * numerical value; they should be interpreted as importances or roles for work
+ * items, priorities for which will be reasonably managed by the subsystem.
+ * @constant THREAD_CALL_PRIORITY_HIGH Importance above everything but realtime.
+ * Thread calls allocated with this priority execute at extremely high priority,
+ * above everything but realtime threads. They are generally executed in serial.
+ * Though they may execute concurrently under some circumstances, no fan-out is implied.
+ * These work items should do very small amounts of work or risk disrupting system
+ * responsiveness.
+ * @constant THREAD_CALL_PRIORITY_KERNEL Importance similar to that of normal kernel
+ * threads.
+ * @constant THREAD_CALL_PRIORITY_USER Importance similar to that of normal user threads.
+ * @constant THREAD_CALL_PRIORITY_LOW Very low importance.
+ * @constant THREAD_CALL_PRIORITY_KERNEL_HIGH Importance higher than most kernel
+ * threads.
+ */
+typedef enum {
+ THREAD_CALL_PRIORITY_HIGH = 0,
+ THREAD_CALL_PRIORITY_KERNEL = 1,
+ THREAD_CALL_PRIORITY_USER = 2,
+ THREAD_CALL_PRIORITY_LOW = 3,
+ THREAD_CALL_PRIORITY_KERNEL_HIGH = 4
+} thread_call_priority_t;
+
+enum {
+ /* if call is re-submitted while the call is executing on a call thread, then delay the re-enqueue until it returns */
+ THREAD_CALL_OPTIONS_ONCE = 0x00000001,
+#ifdef XNU_KERNEL_PRIVATE
+ /* execute call from the timer interrupt instead of from the thread call thread, private interface for IOTES workloop signaling */
+ THREAD_CALL_OPTIONS_SIGNAL = 0x00000002,
+#endif /* XNU_KERNEL_PRIVATE */
+};
+typedef uint32_t thread_call_options_t;
+
+__BEGIN_DECLS
+
+/*!
+ * @function thread_call_enter
+ * @abstract Submit a thread call work item for immediate execution.
+ * @discussion If the work item is already scheduled for delayed execution, and it has
+ * not yet begun to run, that delayed invocation will be cancelled. Note that if a
+ * thread call is rescheduled from its own callback, then multiple invocations of the
+ * callback may be in flight at the same time.
+ * @result TRUE if the call was already pending for either delayed or immediate
+ * execution, FALSE otherwise.
+ * @param call The thread call to execute.
+ */
+extern boolean_t thread_call_enter(
+ thread_call_t call);
+/*!
+ * @function thread_call_enter1
+ * @abstract Submit a thread call work item for immediate execution, with an extra parameter.
+ * @discussion This routine is identical to thread_call_enter(), except that
+ * the second parameter to the callback is specified.
+ * @result TRUE if the call was already pending for either delayed or immediate
+ * execution, FALSE otherwise.
+ * @param call The thread call to execute.
+ * @param param1 Parameter to pass callback.
+ */
+extern boolean_t thread_call_enter1(
+ thread_call_t call,
+ thread_call_param_t param1);
+
+/*!
+ * @function thread_call_enter_delayed
+ * @abstract Submit a thread call to be executed at some point in the future.
+ * @discussion If the work item is already scheduled for delayed or immediate execution,
+ * and it has not yet begun to run, that invocation will be cancelled in favor of execution
+ * at the newly specified time. Note that if a thread call is rescheduled from its own callback,
+ * then multiple invocations of the callback may be in flight at the same time.
+ * @result TRUE if the call was already pending for either delayed or immediate
+ * execution, FALSE otherwise.
+ * @param call The thread call to execute.
+ * @param deadline Time, in absolute time units, at which to execute callback.
+ */
+extern boolean_t thread_call_enter_delayed(
+ thread_call_t call,
+ uint64_t deadline);
+/*!
+ * @function thread_call_enter1_delayed
+ * @abstract Submit a thread call to be executed at some point in the future, with an extra parameter.
+ * @discussion This routine is identical to thread_call_enter_delayed(),
+ * except that a second parameter to the callback is specified.
+ * @result TRUE if the call was already pending for either delayed or immediate
+ * execution, FALSE otherwise.
+ * @param call The thread call to execute.
+ * @param param1 Second parameter to callback.
+ * @param deadline Time, in absolute time units, at which to execute callback.
+ */
+extern boolean_t thread_call_enter1_delayed(
+ thread_call_t call,
+ thread_call_param_t param1,
+ uint64_t deadline);
+#ifdef XNU_KERNEL_PRIVATE
+
+/*
+ * Flags to alter the default timer/timeout coalescing behavior
+ * on a per-thread_call basis.
+ *
+ * The SYS urgency classes indicate that the thread_call is not
+ * directly related to the current thread at the time the thread_call
+ * is entered, so it is ignored in the calculation entirely (only
+ * the subclass specified is used).
+ *
+ * The USER flags indicate that both the current thread scheduling and QoS
+ * attributes, in addition to the per-thread_call urgency specification,
+ * are used to establish coalescing behavior.
+ */
+#define THREAD_CALL_DELAY_SYS_NORMAL TIMEOUT_URGENCY_SYS_NORMAL
+#define THREAD_CALL_DELAY_SYS_CRITICAL TIMEOUT_URGENCY_SYS_CRITICAL
+#define THREAD_CALL_DELAY_SYS_BACKGROUND TIMEOUT_URGENCY_SYS_BACKGROUND
+
+#define THREAD_CALL_DELAY_USER_MASK TIMEOUT_URGENCY_USER_MASK
+#define THREAD_CALL_DELAY_USER_NORMAL TIMEOUT_URGENCY_USER_NORMAL
+#define THREAD_CALL_DELAY_USER_CRITICAL TIMEOUT_URGENCY_USER_CRITICAL
+#define THREAD_CALL_DELAY_USER_BACKGROUND TIMEOUT_URGENCY_USER_BACKGROUND
+
+#define THREAD_CALL_DELAY_URGENCY_MASK TIMEOUT_URGENCY_MASK
+
+/*
+ * Indicate that a specific leeway value is being provided (otherwise
+ * the leeway parameter is ignored). The supplied value can currently
+ * only be used to extend the leeway calculated internally from the
+ * urgency class provided.
+ */
+#define THREAD_CALL_DELAY_LEEWAY TIMEOUT_URGENCY_LEEWAY