]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/thread_call.h
xnu-7195.101.1.tar.gz
[apple/xnu.git] / osfmk / kern / thread_call.h
index 5b486cbbff9352a678e76341780a0b988935ba7f..1e0f2fb96303c0d0421d29125a9fdd116257b342 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1993-1995, 1999-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 /*!
- @header thread_call.h
- @discussion Facilities for executing work asynchronously.
*  @header thread_call.h
*  @discussion Facilities for executing work asynchronously.
  */
 
 #ifndef _KERN_THREAD_CALL_H_
@@ -45,90 +45,103 @@ 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);
+       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.
+ *  @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_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.
*  @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);
+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.
*  @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_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_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);
+extern boolean_t        thread_call_enter1_delayed(
+       thread_call_t           call,
+       thread_call_param_t     param1,
+       uint64_t                deadline);
 #ifdef XNU_KERNEL_PRIVATE
 
 /*
@@ -144,16 +157,16 @@ extern boolean_t  thread_call_enter1_delayed(
  * 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_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_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
+#define THREAD_CALL_DELAY_URGENCY_MASK          TIMEOUT_URGENCY_MASK
 
 /*
  * Indicate that a specific leeway value is being provided (otherwise
@@ -161,7 +174,7 @@ extern boolean_t    thread_call_enter1_delayed(
  * only be used to extend the leeway calculated internally from the
  * urgency class provided.
  */
-#define THREAD_CALL_DELAY_LEEWAY               TIMEOUT_URGENCY_LEEWAY
+#define THREAD_CALL_DELAY_LEEWAY                TIMEOUT_URGENCY_LEEWAY
 
 /*
  * Indicates that the time parameters should be interpreted as
@@ -170,150 +183,238 @@ extern boolean_t        thread_call_enter1_delayed(
  */
 #define THREAD_CALL_CONTINUOUS  0x100
 
-/*! 
- @function thread_call_enter_delayed_with_leeway
- @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 param1 Second parameter to callback.
- @param deadline Time, in absolute time units, at which to execute callback.
- @param leeway Time delta, in absolute time units, which sets range of time allowing kernel
-        to decide appropriate time to run.
- @param flags configuration for timers in kernel.
+/*!
*  @function thread_call_enter_delayed_with_leeway
*  @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 param1 Second parameter to callback.
*  @param deadline Time, in absolute time units, at which to execute callback.
*  @param leeway Time delta, in absolute time units, which sets range of time allowing kernel
*       to decide appropriate time to run.
*  @param flags configuration for timers in kernel.
  */
-extern boolean_t       thread_call_enter_delayed_with_leeway(
-                                               thread_call_t           call,
-                                               thread_call_param_t     param1,
-                                               uint64_t                deadline,
-                                               uint64_t                leeway,
-                                               uint32_t                flags);
+extern boolean_t        thread_call_enter_delayed_with_leeway(
+       thread_call_t           call,
+       thread_call_param_t     param1,
+       uint64_t                deadline,
+       uint64_t                leeway,
+       uint32_t                flags);
 
 #endif /* XNU_KERNEL_PRIVATE */
 
 /*!
- @function thread_call_cancel
- @abstract Attempt to cancel a pending invocation of a thread call.
- @discussion Attempt to cancel a thread call which has been scheduled
- for execution with a thread_call_enter* variant.  If the call has not 
- yet begun executing, the pending invocation will be cancelled and TRUE
- will be returned.  If the work item has already begun executing,
- thread_call_cancel will return FALSE immediately; the callback may be
- about to run, currently running, or already done executing.
- @result TRUE if the call was successfully cancelled, FALSE otherwise.
*  @function thread_call_cancel
*  @abstract Attempt to cancel a pending invocation of a thread call.
*  @discussion Attempt to cancel a thread call which has been scheduled
+ *  for execution with a thread_call_enter* variant.  If the call has not
*  yet begun executing, the pending invocation will be cancelled and TRUE
*  will be returned.  If the work item has already begun executing,
*  thread_call_cancel will return FALSE immediately; the callback may be
*  about to run, currently running, or already done executing.
*  @result TRUE if the call was successfully cancelled, FALSE otherwise.
  */
-extern boolean_t       thread_call_cancel(
-                                               thread_call_t           call);
+extern boolean_t        thread_call_cancel(
+       thread_call_t           call);
 /*!
- @function thread_call_cancel_wait
- @abstract Attempt to cancel a pending invocation of a thread call.  
- If unable to cancel, wait for current invocation to finish.
- @discussion Attempt to cancel a thread call which has been scheduled
- for execution with a thread_call_enter* variant.  If the call has not 
- yet begun executing, the pending invocation will be cancelled and TRUE
- will be returned.  If the work item has already begun executing,
- thread_call_cancel_wait waits for the most recent invocation to finish. When
- called on a work item which has already finished, it will return FALSE immediately.
- Note that this routine can only be used on thread calls set up with either
- thread_call_allocate or thread_call_allocate_with_priority, and that invocations
- of the thread call <i>after</i> the current invocation may be in flight when 
- thread_call_cancel_wait returns.
- @result TRUE if the call was successfully cancelled, FALSE otherwise.
*  @function thread_call_cancel_wait
+ *  @abstract Attempt to cancel a pending invocation of a thread call.
*  If unable to cancel, wait for current invocation to finish.
*  @discussion Attempt to cancel a thread call which has been scheduled
+ *  for execution with a thread_call_enter* variant.  If the call has not
*  yet begun executing, the pending invocation will be cancelled and TRUE
*  will be returned.  If the work item has already begun executing,
*  thread_call_cancel_wait waits for the most recent invocation to finish. When
*  called on a work item which has already finished, it will return FALSE immediately.
*  Note that this routine can only be used on thread calls set up with either
*  thread_call_allocate or thread_call_allocate_with_priority, and that invocations
+ *  of the thread call <i>after</i> the current invocation may be in flight when
*  thread_call_cancel_wait returns.
*  @result TRUE if the call was successfully cancelled, FALSE otherwise.
  */
-extern boolean_t       thread_call_cancel_wait(
-                                               thread_call_t           call);
-
- /*!
-  @function thread_call_allocate
-  @abstract Allocate a thread call to execute with default (high) priority.
-  @discussion  Allocates a thread call that will run with properties of 
-  THREAD_CALL_PRIORITY_HIGH, binding the first parameter to the callback.
-  @param func Callback to invoke when thread call is scheduled.
-  @param param0 First argument ot pass to callback.
-  @result Thread call which can be passed to thread_call_enter variants.
-  */
-extern thread_call_t   thread_call_allocate(
-                                               thread_call_func_t      func,
-                                               thread_call_param_t     param0);
-
- /*!
-  @function thread_call_allocate_with_priority
-  @abstract Allocate a thread call to execute with a specified priority.
-  @discussion Identical to thread_call_allocate, except that priority 
-  is specified by caller.
-  @param func Callback to invoke when thread call is scheduled.
-  @param param0 First argument to pass to callback.
-  @param pri Priority of item.
-  @result Thread call which can be passed to thread_call_enter variants.
-  */
-extern thread_call_t   thread_call_allocate_with_priority(
-                                               thread_call_func_t      func,
-                                               thread_call_param_t     param0,
-                                               thread_call_priority_t  pri);
+extern boolean_t        thread_call_cancel_wait(
+       thread_call_t           call);
 
 /*!
- @function thread_call_free
- @abstract Release a thread call.
- @discussion Should only be used on thread calls allocated with thread_call_allocate
- or thread_call_allocate_with_priority.  Once thread_call_free has been called,
- no other operations may be performed on a thread call.  If the thread call is
- currently pending, thread_call_free will return FALSE and will have no effect.
- Calling thread_call_free from a thread call's own callback is safe; the work
- item is not considering "pending" at that point.
- @result TRUE if the thread call has been successfully released, else FALSE.
- @param call The thread call to release.
+ *  @function thread_call_allocate
+ *  @abstract Allocate a thread call to execute with default (high) priority.
+ *  @discussion  Allocates a thread call that will run with properties of
+ *  THREAD_CALL_PRIORITY_HIGH, binding the first parameter to the callback.
+ *  @param func Callback to invoke when thread call is scheduled.
+ *  @param param0 First argument ot pass to callback.
+ *  @result Thread call which can be passed to thread_call_enter variants.
  */
-extern boolean_t       thread_call_free(
-                                               thread_call_t           call);
+extern thread_call_t    thread_call_allocate(
+       thread_call_func_t      func,
+       thread_call_param_t     param0);
 
 /*!
- @function thread_call_isactive
- @abstract Determine whether a thread call is pending or currently executing.
- @param call Thread call to examine.
- @result TRUE if the thread call is either scheduled for execution (immediately
- or at some point in the future) or is currently executing.
+ *  @function thread_call_allocate_with_priority
+ *  @abstract Allocate a thread call to execute with a specified priority.
+ *  @discussion Identical to thread_call_allocate, except that priority
+ *  is specified by caller.
+ *  @param func Callback to invoke when thread call is scheduled.
+ *  @param param0 First argument to pass to callback.
+ *  @param pri Priority of item.
+ *  @result Thread call which can be passed to thread_call_enter variants.
  */
-boolean_t              thread_call_isactive(
-                                               thread_call_t call);
-__END_DECLS
+extern thread_call_t    thread_call_allocate_with_priority(
+       thread_call_func_t      func,
+       thread_call_param_t     param0,
+       thread_call_priority_t  pri);
 
-#ifdef MACH_KERNEL_PRIVATE
+/*!
+ *  @function thread_call_allocate_with_options
+ *  @abstract Allocate a thread call to execute with a specified priority.
+ *  @discussion Identical to thread_call_allocate, except that priority
+ *  and options are specified by caller.
+ *  @param func Callback to invoke when thread call is scheduled.
+ *  @param param0 First argument to pass to callback.
+ *  @param pri Priority of item.
+ *  @param options Options for item.
+ *  @result Thread call which can be passed to thread_call_enter variants.
+ */
+extern thread_call_t    thread_call_allocate_with_options(
+       thread_call_func_t      func,
+       thread_call_param_t     param0,
+       thread_call_priority_t  pri,
+       thread_call_options_t   options);
 
-#include <kern/call_entry.h>
+#ifdef KERNEL_PRIVATE
+/*!
+ *  @function thread_call_allocate_with_qos
+ *  @abstract Allocate a thread call to execute with a specified QoS.
+ *  @discussion Identical to thread_call_allocate_with_options, except it uses the QoS namespace.
+ *      Private interface for pthread kext.
+ *  @param func Callback to invoke when thread call is scheduled.
+ *  @param param0 First argument to pass to callback.
+ *  @param qos_tier QoS tier to execute callback at (as in THREAD_QOS_POLICY)
+ *  @param options flags from thread_call_options_t to influence the thread call behavior
+ *  @result Thread call which can be passed to thread_call_enter variants.
+ */
+extern thread_call_t
+thread_call_allocate_with_qos(thread_call_func_t        func,
+    thread_call_param_t       param0,
+    int                       qos_tier,
+    thread_call_options_t     options);
+
+/*!
+ *  @function thread_call_wait_once
+ *  @abstract Wait for a THREAD_CALL_OPTIONS_ONCE call to finish executing if it is executing
+ *  @discussion Only works on THREAD_CALL_OPTIONS_ONCE calls
+ *  @param call The thread call to wait for
+ *  @result True if it waited, false if it did not wait
+ */
+extern boolean_t
+thread_call_wait_once(thread_call_t call);
+#endif /* KERNEL_PRIVATE */
+
+/*!
+ *  @function thread_call_free
+ *  @abstract Release a thread call.
+ *  @discussion Should only be used on thread calls allocated with thread_call_allocate
+ *  or thread_call_allocate_with_priority.  Once thread_call_free has been called,
+ *  no other operations may be performed on a thread call.  If the thread call is
+ *  currently pending, thread_call_free will return FALSE and will have no effect.
+ *  Calling thread_call_free from a thread call's own callback is safe; the work
+ *  item is not considering "pending" at that point.
+ *  @result TRUE if the thread call has been successfully released, else FALSE.
+ *  @param call The thread call to release.
+ */
+extern boolean_t        thread_call_free(
+       thread_call_t           call);
+
+/*!
+ *  @function thread_call_isactive
+ *  @abstract Determine whether a thread call is pending or currently executing.
+ *  @param call Thread call to examine.
+ *  @result TRUE if the thread call is either scheduled for execution (immediately
+ *  or at some point in the future) or is currently executing.
+ */
+boolean_t               thread_call_isactive(
+       thread_call_t call);
+__END_DECLS
+
+#ifdef  MACH_KERNEL_PRIVATE
+
+#include <kern/queue.h>
+#include <kern/priority_queue.h>
+
+__enum_closed_decl(thread_call_index_t, uint16_t, {
+       THREAD_CALL_INDEX_HIGH          = 0,
+       THREAD_CALL_INDEX_KERNEL        = 1,
+       THREAD_CALL_INDEX_USER          = 2,
+       THREAD_CALL_INDEX_LOW           = 3,
+       THREAD_CALL_INDEX_KERNEL_HIGH   = 4,
+       THREAD_CALL_INDEX_QOS_UI        = 5,
+       THREAD_CALL_INDEX_QOS_IN        = 6,
+       THREAD_CALL_INDEX_QOS_UT        = 7,
+       THREAD_CALL_INDEX_MAX           = 8,    /* count of thread call indexes */
+});
+
+__options_closed_decl(thread_call_flags_t, uint16_t, {
+       THREAD_CALL_ALLOC               = 0x0001,       /* memory owned by thread_call.c */
+       THREAD_CALL_WAIT                = 0x0002,       /* thread waiting for call to finish running */
+       THREAD_CALL_DELAYED             = 0x0004,       /* deadline based */
+       THREAD_CALL_RUNNING             = 0x0008,       /* currently executing on a thread */
+       THREAD_CALL_SIGNAL              = 0x0010,       /* call from timer interrupt instead of thread */
+       THREAD_CALL_ONCE                = 0x0020,       /* pend the enqueue if re-armed while running */
+       THREAD_CALL_RESCHEDULE          = 0x0040,       /* enqueue is pending due to re-arm while running */
+       THREAD_CALL_RATELIMITED         = 0x0080,       /* timer doesn't fire until slop+deadline */
+       THREAD_CALL_FLAG_CONTINUOUS     = 0x0100,       /* deadline is in continuous time */
+});
 
 struct thread_call {
-       struct call_entry       tc_call;        /* Must be first */
-       uint64_t                        tc_submit_count;
-       uint64_t                        tc_finish_count;
-       uint64_t                        ttd; /* Time to deadline at creation */
-       uint64_t                        tc_soft_deadline;
-       thread_call_priority_t          tc_pri;
-       uint32_t                        tc_flags;
-       int32_t                         tc_refs;
+       /* Originally requested deadline */
+       uint64_t                                tc_soft_deadline;
+       /* Deadline presented to hardware (post-leeway) stored in tc_pqlink.deadline */
+       struct priority_queue_entry_deadline    tc_pqlink;
+       /* Which queue head is this call enqueued on */
+       queue_head_t                            *tc_queue;
+       queue_chain_t                           tc_qlink;
+       thread_call_index_t                     tc_index;
+       thread_call_flags_t                     tc_flags;
+       int32_t                                 tc_refs;
+       /* Time to deadline at creation */
+       uint64_t                                tc_ttd;
+       /* Timestamp of enqueue on pending queue */
+       uint64_t                                tc_pending_timestamp;
+       thread_call_func_t                      tc_func;
+       thread_call_param_t                     tc_param0;
+       thread_call_param_t                     tc_param1;
+       uint64_t                                tc_submit_count;
+       uint64_t                                tc_finish_count;
 };
 
-#define THREAD_CALL_ALLOC       0x01
-#define THREAD_CALL_WAIT        0x02
-#define THREAD_CALL_DELAYED     0x04
-#define THREAD_CALL_RATELIMITED TIMEOUT_URGENCY_RATELIMITED
-
 typedef struct thread_call thread_call_data_t;
 
-extern void            thread_call_initialize(void);
+extern void             thread_call_initialize(void);
+
+extern void             thread_call_setup(
+       thread_call_t                   call,
+       thread_call_func_t              func,
+       thread_call_param_t             param0);
+
+extern void             thread_call_setup_with_options(
+       thread_call_t                   call,
+       thread_call_func_t              func,
+       thread_call_param_t             param0,
+       thread_call_priority_t          pri,
+       thread_call_options_t           options);
 
-extern void            thread_call_setup(
-                                       thread_call_t                   call,
-                                       thread_call_func_t              func,
-                                       thread_call_param_t             param0);
+extern void             thread_call_delayed_timer_rescan_all(void);
+extern uint64_t         thread_call_get_armed_deadline(thread_call_t call);
 
-extern void            thread_call_delayed_timer_rescan_all(void);
-#endif /* MACH_KERNEL_PRIVATE */
+struct thread_call_thread_state;
 
-#ifdef XNU_KERNEL_PRIVATE
+#endif  /* MACH_KERNEL_PRIVATE */
+
+#ifdef  XNU_KERNEL_PRIVATE
 
 __BEGIN_DECLS
 
@@ -324,30 +425,39 @@ __BEGIN_DECLS
  * is exhausted.
  */
 
-extern void            thread_call_func_delayed(
-                                       thread_call_func_t              func,
-                                       thread_call_param_t             param,
-                                       uint64_t                        deadline);
+extern void             thread_call_func_delayed(
+       thread_call_func_t              func,
+       thread_call_param_t             param,
+       uint64_t                        deadline);
 
-extern void            thread_call_func_delayed_with_leeway(
-                                               thread_call_func_t              func,
-                                               thread_call_param_t             param,
-                                               uint64_t                deadline,
-                                               uint64_t                leeway,
-                                               uint32_t                flags);
+extern void             thread_call_func_delayed_with_leeway(
+       thread_call_func_t              func,
+       thread_call_param_t             param,
+       uint64_t                deadline,
+       uint64_t                leeway,
+       uint32_t                flags);
 
-extern boolean_t       thread_call_func_cancel(
-                                               thread_call_func_t      func,
-                                               thread_call_param_t     param,
-                                               boolean_t               cancel_all);
+/*
+ * This iterates all of the pending or delayed thread calls in the group,
+ * which is really inefficient.
+ *
+ * This is deprecated, switch to an allocated thread call instead.
+ */
+extern boolean_t        thread_call_func_cancel(
+       thread_call_func_t      func,
+       thread_call_param_t     param,
+       boolean_t               cancel_all);
 
-/* 
+/*
  * Called on the wake path to adjust the thread callouts running in mach_continuous_time
  */
-void                           adjust_cont_time_thread_calls(void);
+extern void adjust_cont_time_thread_calls(void);
+
+/* called by IOTimerEventSource to track when the workloop lock has been taken */
+extern void thread_call_start_iotes_invocation(thread_call_t call);
 
 __END_DECLS
 
-#endif /* XNU_KERNEL_PRIVATE */
+#endif  /* XNU_KERNEL_PRIVATE */
 
-#endif /* _KERN_THREAD_CALL_H_ */
+#endif  /* _KERN_THREAD_CALL_H_ */