]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/thread.h
xnu-6153.41.3.tar.gz
[apple/xnu.git] / osfmk / kern / thread.h
index 39b9c4fcfb8d4454ec647a4f517090b8a3327e20..7242faac767d8dcf2c26cf449b635c63b0668034 100644 (file)
 #include <kern/debug.h>
 #include <kern/block_hint.h>
 #include <kern/turnstile.h>
+#include <kern/mpsc_queue.h>
 
 #include <kern/waitq.h>
 #include <san/kasan.h>
 
 #include <ipc/ipc_kmsg.h>
 
+#include <machine/atomic.h>
 #include <machine/cpu_data.h>
 #include <machine/thread.h>
 
@@ -172,26 +174,38 @@ struct thread {
        union {
                queue_chain_t                   runq_links;             /* run queue links */
                queue_chain_t                   wait_links;             /* wait queue links */
+               struct mpsc_queue_chain         mpsc_links;             /* thread daemon mpsc links */
                struct priority_queue_entry     wait_prioq_links;       /* priority ordered waitq links */
        };
 
-       processor_t             runq;           /* run queue assignment */
-
        event64_t               wait_event;     /* wait queue event */
+       processor_t             runq;           /* run queue assignment */
        struct waitq           *waitq;          /* wait queue this thread is enqueued on */
        struct turnstile       *turnstile;      /* thread's turnstile, protected by primitives interlock */
        void                   *inheritor;      /* inheritor of the primitive the thread will block on */
-       struct priority_queue  inheritor_queue; /* Inheritor queue */
+       struct priority_queue  sched_inheritor_queue; /* Inheritor queue for kernel promotion */
+       struct priority_queue  base_inheritor_queue; /* Inheritor queue for user promotion */
+
+#if CONFIG_SCHED_CLUTCH
+       /*
+        * In the clutch scheduler, the threads are maintained in runqs at the clutch_bucket
+        * level (clutch_bucket defines a unique thread group and scheduling bucket pair). In
+        * order to determine the priority of the clutch bucket as a whole, it is necessary to
+        * find the highest thread in it. The thread could be present in the clutch bucket due
+        * to its base_pri or its promoted pri. This link is used to maintain that queue.
+        */
+       struct priority_queue_entry sched_clutchpri_link;
+
+#endif /* CONFIG_SCHED_CLUTCH */
 
        /* Data updated during assert_wait/thread_wakeup */
 #if __SMP__
-       decl_simple_lock_data(, sched_lock)      /* scheduling lock (thread_lock()) */
-       decl_simple_lock_data(, wake_lock)       /* for thread stop / wait (wake_lock()) */
+       decl_simple_lock_data(, sched_lock);     /* scheduling lock (thread_lock()) */
+       decl_simple_lock_data(, wake_lock);      /* for thread stop / wait (wake_lock()) */
 #endif
-       integer_t               options;                        /* options set by thread itself */
+       uint16_t                options;                        /* options set by thread itself */
 #define TH_OPT_INTMASK          0x0003          /* interrupt / abort level */
 #define TH_OPT_VMPRIV           0x0004          /* may allocate reserved memory */
-#define TH_OPT_DTRACE           0x0008          /* executing under dtrace_probe */
 #define TH_OPT_SYSTEM_CRITICAL  0x0010          /* Thread must always be allowed to run - even under heavy load */
 #define TH_OPT_PROC_CPULIMIT    0x0020          /* Thread has a task-wide CPU limit applied to it */
 #define TH_OPT_PRVT_CPULIMIT    0x0040          /* Thread has a thread-private CPU limit applied to it */
@@ -202,8 +216,8 @@ struct thread {
 #define TH_OPT_SEND_IMPORTANCE  0x0800          /* Thread will allow importance donation from kernel rpc */
 #define TH_OPT_ZONE_GC          0x1000          /* zone_gc() called on this thread */
 
-       boolean_t                       wake_active;    /* wake event on stop */
-       int                                     at_safe_point;  /* thread_abort_safely allowed */
+       bool                            wake_active;    /* wake event on stop */
+       bool                            at_safe_point;  /* thread_abort_safely allowed */
        ast_t                           reason;                 /* why we blocked */
        uint32_t                        quantum_remaining;
        wait_result_t                   wait_result;    /* outcome of wait -
@@ -220,6 +234,10 @@ struct thread {
        struct kasan_thread_data kasan_data;
 #endif
 
+#if CONFIG_KSANCOV
+       void *ksancov_data;
+#endif
+
        /* Thread state: */
        int                                     state;
 /*
@@ -262,7 +280,7 @@ struct thread {
 /* unused TH_SFLAG_PRI_UPDATE           0x0100 */
 #define TH_SFLAG_EAGERPREEMPT           0x0200          /* Any preemption of this thread should be treated as if AST_URGENT applied */
 #define TH_SFLAG_RW_PROMOTED            0x0400          /* promote reason: blocking with RW lock held */
-/* unused TH_SFLAG_THROTTLE_DEMOTED     0x0800 */
+#define TH_SFLAG_BASE_PRI_FROZEN        0x0800          /* (effective) base_pri is frozen */
 #define TH_SFLAG_WAITQ_PROMOTED         0x1000          /* promote reason: waitq wakeup (generally for IPC receive) */
 
 
@@ -274,7 +292,8 @@ struct thread {
 #define TH_SFLAG_RW_PROMOTED_BIT        (10)    /* 0x400 */
 
        int16_t                         sched_pri;              /* scheduled (current) priority */
-       int16_t                         base_pri;               /* base priority */
+       int16_t                         base_pri;               /* effective base priority (equal to req_base_pri unless TH_SFLAG_BASE_PRI_FROZEN) */
+       int16_t                         req_base_pri;           /* requested base priority */
        int16_t                         max_priority;           /* copy of max base priority */
        int16_t                         task_priority;          /* copy of task base priority */
        int16_t                         promotion_priority;     /* priority thread is currently promoted to */
@@ -285,16 +304,14 @@ struct thread {
 #endif
 #endif
 
-       int16_t                         promotions;                     /* level of promotion */
        int                             iotier_override; /* atomic operations to set, cleared on ret to user */
-       struct os_refcnt                ref_count;              /* number of references to me */
+       os_refcnt_t                     ref_count;              /* number of references to me */
 
        lck_mtx_t*                      waiting_for_mutex;      /* points to mutex we're waiting for until we acquire it */
 
        uint32_t                        rwlock_count;   /* Number of lck_rw_t locks held by thread */
 
        integer_t                       importance;                     /* task-relative importance */
-       uint32_t                        was_promoted_on_wakeup;         /* thread promoted on wakeup to acquire mutex */
 
        /* Priority depression expiration */
        integer_t                       depress_timer_active;
@@ -331,9 +348,8 @@ struct thread {
        uint64_t                        safe_release;   /* when to release fail-safe */
 
        /* Call out from scheduler */
-       void                            (*sched_call)(
-               int                     type,
-               thread_t        thread);
+       void                            (*sched_call)(int type, thread_t thread);
+
 #if defined(CONFIG_SCHED_PROTO)
        uint32_t                        runqueue_generation;    /* last time runqueue was drained */
 #endif
@@ -370,18 +386,16 @@ struct thread {
        uint64_t                wait_sfi_begin_time;    /* start time for thread waiting in SFI */
 #endif
 
-       /* Timed wait expiration */
-       timer_call_data_t       wait_timer;
-       integer_t                       wait_timer_active;
-       boolean_t                       wait_timer_is_set;
-
-
        /*
         * Processor/cache affinity
         * - affinity_threads links task threads with the same affinity set
         */
-       affinity_set_t                  affinity_set;
        queue_chain_t                   affinity_threads;
+       affinity_set_t                  affinity_set;
+
+#if CONFIG_EMBEDDED
+       task_watch_t *  taskwatch;              /* task watch */
+#endif /* CONFIG_EMBEDDED */
 
        /* Various bits of state to stash across a continuation, exclusive to the current thread block point */
        union {
@@ -389,7 +403,7 @@ struct thread {
                        mach_msg_return_t       state;          /* receive state */
                        mach_port_seqno_t       seqno;          /* seqno of recvd message */
                        ipc_object_t            object;         /* object received on */
-                       mach_vm_address_t       msg_addr;       /* receive buffer pointer */
+                       vm_address_t            msg_addr;       /* receive buffer pointer */
                        mach_msg_size_t         rsize;          /* max size for recvd msg */
                        mach_msg_size_t         msize;          /* actual size for recvd msg */
                        mach_msg_option_t       option;         /* options for receive */
@@ -412,6 +426,10 @@ struct thread {
                        kern_return_t           result;                         /* primary result */
                        mach_msg_continue_t continuation;
                } sema;
+               struct {
+#define THREAD_SAVE_IOKIT_TLS_COUNT     8
+                       void                    *tls[THREAD_SAVE_IOKIT_TLS_COUNT];
+               } iokit;
        } saved;
 
        /* Only user threads can cause guard exceptions, only kernel threads can be thread call threads */
@@ -441,26 +459,28 @@ struct thread {
        struct ipc_kmsg_queue ith_messages;             /* messages to reap */
        mach_port_t ith_rpc_reply;                      /* reply port for kernel RPCs */
 
+       /* Pending thread ast(s) */
+       ast_t                                   ast;
+
        /* Ast/Halt data structures */
-       vm_offset_t                                     recover;                /* page fault recover(copyin/out) */
+       vm_offset_t                             recover;                /* page fault recover(copyin/out) */
 
        queue_chain_t                           threads;                /* global list of all threads */
 
        /* Activation */
-       queue_chain_t                   task_threads;
+       queue_chain_t                           task_threads;
 
        /* Task membership */
        struct task                             *task;
        vm_map_t                                map;
 #if DEVELOPMENT || DEBUG
-       boolean_t pmap_footprint_suspended;
+       bool      pmap_footprint_suspended;
 #endif /* DEVELOPMENT || DEBUG */
 
-       decl_lck_mtx_data(, mutex)
-
-
-       /* Pending thread ast(s) */
-       ast_t                                   ast;
+       /* Timed wait expiration */
+       timer_call_data_t       wait_timer;
+       uint16_t                wait_timer_active;
+       bool                    wait_timer_is_set;
 
        /* Miscellaneous bits guarded by mutex */
        uint32_t
@@ -473,6 +493,8 @@ struct thread {
            corpse_dup:1,                               /* TRUE when thread is an inactive duplicate in a corpse */
        :0;
 
+       decl_lck_mtx_data(, mutex);
+
        /* Ports associated with this thread */
        struct ipc_port                 *ith_self;                      /* not a right, doesn't hold ref */
        struct ipc_port                 *ith_sself;                     /* a send right */
@@ -484,8 +506,9 @@ struct thread {
 #endif
 
 #if CONFIG_DTRACE
-       uint32_t t_dtrace_flags;                /* DTrace thread states */
+       uint16_t t_dtrace_flags;                /* DTrace thread states */
 #define TH_DTRACE_EXECSUCCESS   0x01
+       uint16_t t_dtrace_inprobe;          /* Executing under dtrace_probe */
        uint32_t t_dtrace_predcache;        /* DTrace per thread predicate value hint */
        int64_t t_dtrace_tracing;               /* Thread time under dtrace_probe() */
        int64_t t_dtrace_vtime;
@@ -498,21 +521,28 @@ struct thread {
        uint64_t    t_page_creation_throttled_hard;
        uint64_t    t_page_creation_throttled_soft;
 #endif /* DEVELOPMENT || DEBUG */
+       int         t_pagein_error;            /* for vm_fault(), holds error from vnop_pagein() */
 
 #ifdef KPERF
-/* The high 7 bits are the number of frames to sample of a user callstack. */
-#define T_KPERF_CALLSTACK_DEPTH_OFFSET     (25)
+/* The high 8 bits are the number of frames to sample of a user callstack. */
+#define T_KPERF_CALLSTACK_DEPTH_OFFSET     (24)
 #define T_KPERF_SET_CALLSTACK_DEPTH(DEPTH) (((uint32_t)(DEPTH)) << T_KPERF_CALLSTACK_DEPTH_OFFSET)
 #define T_KPERF_GET_CALLSTACK_DEPTH(FLAGS) ((FLAGS) >> T_KPERF_CALLSTACK_DEPTH_OFFSET)
+#define T_KPERF_ACTIONID_OFFSET            (18)
+#define T_KPERF_SET_ACTIONID(AID)          (((uint32_t)(AID)) << T_KPERF_ACTIONID_OFFSET)
+#define T_KPERF_GET_ACTIONID(FLAGS)        ((FLAGS) >> T_KPERF_ACTIONID_OFFSET)
 #endif
 
-#define T_KPERF_AST_CALLSTACK (1U << 0) /* dump a callstack on thread's next AST */
-#define T_KPERF_AST_DISPATCH  (1U << 1) /* dump a name on thread's next AST */
-#define T_KPC_ALLOC           (1U << 2) /* thread needs a kpc_buf allocated */
-/* only go up to T_KPERF_CALLSTACK_DEPTH_OFFSET - 1 */
+#define T_KPERF_AST_CALLSTACK 0x1 /* dump a callstack on thread's next AST */
+#define T_KPERF_AST_DISPATCH  0x2 /* dump a name on thread's next AST */
+#define T_KPC_ALLOC           0x4 /* thread needs a kpc_buf allocated */
+
+#define T_KPERF_AST_ALL \
+    (T_KPERF_AST_CALLSTACK | T_KPERF_AST_DISPATCH | T_KPC_ALLOC)
+/* only go up to T_KPERF_ACTIONID_OFFSET - 1 */
 
 #ifdef KPERF
-       uint32_t kperf_flags;
+       uint32_t kperf_ast;
        uint32_t kperf_pet_gen;  /* last generation of PET that sampled this thread*/
        uint32_t kperf_c_switch; /* last dispatch detection */
        uint32_t kperf_pet_cnt;  /* how many times a thread has been sampled by PET */
@@ -528,8 +558,6 @@ struct thread {
        void *hv_thread_target;
 #endif /* HYPERVISOR */
 
-       uint64_t thread_id;             /*system wide unique thread-id*/
-
        /* Statistics accumulated per-thread and aggregated per-task */
        uint32_t                syscalls_unix;
        uint32_t                syscalls_mach;
@@ -539,6 +567,8 @@ struct thread {
        uint64_t                t_deduct_bank_ledger_time;   /* cpu time to be deducted from bank ledger */
        uint64_t                t_deduct_bank_ledger_energy; /* energy to be deducted from bank ledger */
 
+       uint64_t thread_id;             /*system wide unique thread-id*/
+
 #if MONOTONIC
        struct mt_thread t_monotonic;
 #endif /* MONOTONIC */
@@ -559,27 +589,28 @@ struct thread {
                user_addr_t     override_resource;
        } *overrides;
 
-       uint32_t        ipc_overrides;
-       _Atomic uint32_t kqwl_owning_count;
-       uint32_t        sync_ipc_overrides;
-       uint16_t        user_promotion_basepri;
+       uint32_t        kevent_overrides;
+       uint8_t         user_promotion_basepri;
+       uint8_t         kern_promotion_schedpri;
        _Atomic uint16_t kevent_ast_bits;
 
        io_stat_info_t                  thread_io_stats; /* per-thread I/O statistics */
 
-#if CONFIG_EMBEDDED
-       task_watch_t *  taskwatch;              /* task watch */
-#endif /* CONFIG_EMBEDDED */
-
        uint32_t                        thread_callout_interrupt_wakeups;
        uint32_t                        thread_callout_platform_idle_wakeups;
        uint32_t                        thread_timer_wakeups_bin_1;
        uint32_t                        thread_timer_wakeups_bin_2;
        uint16_t                        thread_tag;
+       /*
+        * callout_* fields are only set for thread call threads whereas guard_exc_fatal is set
+        * by user threads on themselves while taking a guard exception. So it's okay for them to
+        * share this bitfield.
+        */
        uint16_t                        callout_woken_from_icontext:1,
            callout_woken_from_platform_idle:1,
            callout_woke_thread:1,
-           thread_bitfield_unused:13;
+           guard_exc_fatal:1,
+           thread_bitfield_unused:12;
 
        mach_port_name_t                ith_voucher_name;
        ipc_voucher_t                   ith_voucher;
@@ -596,6 +627,7 @@ struct thread {
        turnstile_update_flags_t inheritor_flags; /* inheritor flags for inheritor field */
        block_hint_t    pending_block_hint;
        block_hint_t    block_hint;      /* What type of primitive last caused us to block. */
+       integer_t       decompressions;  /* Per-thread decompressions counter to be added to per-task decompressions counter */
 };
 
 #define ith_state           saved.receive.state
@@ -657,9 +689,6 @@ MACRO_END
 extern void                     thread_deallocate(
        thread_t                thread);
 
-extern void                     thread_deallocate_safe(
-       thread_t                thread);
-
 extern void                     thread_inspect_deallocate(
        thread_inspect_t        thread);
 
@@ -690,9 +719,6 @@ extern void                     thread_copy_resource_info(
 
 extern void                     thread_terminate_crashed_threads(void);
 
-extern void                     turnstile_deallocate_enqueue(
-       struct turnstile *turnstile);
-
 extern void                     thread_stack_enqueue(
        thread_t                thread);
 
@@ -702,7 +728,7 @@ extern void                     thread_hold(
 extern void                     thread_release(
        thread_t        thread);
 
-extern void                     thread_corpse_continue(void);
+extern void                     thread_corpse_continue(void) __dead2;
 
 extern boolean_t                thread_is_active(thread_t thread);
 
@@ -789,7 +815,6 @@ extern thread_t                 machine_switch_context(
 extern void                             machine_load_context(
        thread_t                thread) __attribute__((noreturn));
 
-
 extern kern_return_t    machine_thread_state_initialize(
        thread_t                                thread);
 
@@ -799,6 +824,16 @@ extern kern_return_t    machine_thread_set_state(
        thread_state_t                  state,
        mach_msg_type_number_t  count);
 
+extern mach_vm_address_t machine_thread_pc(
+       thread_t                thread);
+
+extern void machine_thread_reset_pc(
+       thread_t                thread,
+       mach_vm_address_t       pc);
+
+extern boolean_t        machine_thread_on_core(
+       thread_t                thread);
+
 extern kern_return_t    machine_thread_get_state(
        thread_t                                thread,
        thread_flavor_t                 flavor,
@@ -866,7 +901,7 @@ vm_offset_t                     max_valid_stack_address(void);
 static inline uint16_t
 thread_set_tag_internal(thread_t        thread, uint16_t tag)
 {
-       return __sync_fetch_and_or(&thread->thread_tag, tag);
+       return os_atomic_or_orig(&thread->thread_tag, tag, relaxed);
 }
 
 static inline uint16_t
@@ -889,7 +924,7 @@ extern void thread_mtx_lock(thread_t thread);
 
 extern void thread_mtx_unlock(thread_t thread);
 
-extern thread_t         current_thread(void);
+extern thread_t         current_thread(void) __attribute__((const));
 
 extern void                     thread_reference(
        thread_t        thread);
@@ -897,6 +932,19 @@ extern void                     thread_reference(
 extern void                     thread_deallocate(
        thread_t        thread);
 
+#if BSD_KERNEL_PRIVATE
+/* Duplicated from osfmk/kern/ipc_tt.h */
+__options_decl(port_to_thread_options_t, uint32_t, {
+       PORT_TO_THREAD_NONE               = 0x0000,
+       PORT_TO_THREAD_IN_CURRENT_TASK    = 0x0001,
+       PORT_TO_THREAD_NOT_CURRENT_THREAD = 0x0002,
+});
+
+extern thread_t port_name_to_thread(
+       mach_port_name_t            port_name,
+       port_to_thread_options_t    options);
+#endif /* BSD_KERNEL_PRIVATE */
+
 __END_DECLS
 
 #endif  /* MACH_KERNEL_PRIVATE */
@@ -905,22 +953,21 @@ __END_DECLS
 
 __BEGIN_DECLS
 
-extern void                     thread_starts_owning_workloop(
-       thread_t                thread);
-
-extern void                     thread_ends_owning_workloop(
-       thread_t                thread);
-
-extern uint32_t         thread_owned_workloops_count(
+extern void                     thread_deallocate_safe(
        thread_t                thread);
 
-
 extern uint64_t                 thread_dispatchqaddr(
        thread_t thread);
 
 extern uint64_t                 thread_rettokern_addr(
        thread_t thread);
 
+extern integer_t        thread_kern_get_pri(thread_t thr) __attribute__((const));
+
+extern void             thread_kern_set_pri(thread_t thr, integer_t pri);
+
+extern integer_t        thread_kern_get_kernel_maxpri(void) __attribute__((const));
+
 __END_DECLS
 
 #endif  /* KERNEL_PRIVATE */
@@ -1114,6 +1161,7 @@ extern int              thread_task_has_ldt(thread_t);
 #endif
 extern void             *get_bsdthread_info(thread_t);
 extern void             set_bsdthread_info(thread_t, void *);
+extern void             set_thread_pagein_error(thread_t, int);
 extern void             *uthread_alloc(task_t, thread_t, int);
 extern event_t  workq_thread_init_and_wq_lock(task_t, thread_t); // bsd/pthread/
 extern void             uthread_cleanup_name(void *uthread);
@@ -1143,13 +1191,13 @@ extern void act_set_io_telemetry_ast(thread_t);
 extern uint32_t dtrace_get_thread_predcache(thread_t);
 extern int64_t dtrace_get_thread_vtime(thread_t);
 extern int64_t dtrace_get_thread_tracing(thread_t);
-extern boolean_t dtrace_get_thread_reentering(thread_t);
+extern uint16_t dtrace_get_thread_inprobe(thread_t);
 extern int dtrace_get_thread_last_cpu_id(thread_t);
 extern vm_offset_t dtrace_get_kernel_stack(thread_t);
 extern void dtrace_set_thread_predcache(thread_t, uint32_t);
 extern void dtrace_set_thread_vtime(thread_t, int64_t);
 extern void dtrace_set_thread_tracing(thread_t, int64_t);
-extern void dtrace_set_thread_reentering(thread_t, boolean_t);
+extern void dtrace_set_thread_inprobe(thread_t, uint16_t);
 extern vm_offset_t dtrace_set_thread_recover(thread_t, vm_offset_t);
 extern vm_offset_t dtrace_sign_and_set_thread_recover(thread_t, vm_offset_t);
 extern void dtrace_thread_bootstrap(void);
@@ -1182,7 +1230,7 @@ extern void mach_port_guard_ast(thread_t,
 extern void virt_memory_guard_ast(thread_t,
     mach_exception_code_t, mach_exception_subcode_t);
 extern void thread_guard_violation(thread_t,
-    mach_exception_code_t, mach_exception_subcode_t);
+    mach_exception_code_t, mach_exception_subcode_t, boolean_t);
 extern void thread_update_io_stats(thread_t, int size, int io_flags);
 
 extern kern_return_t    thread_set_voucher_name(mach_port_name_t name);
@@ -1191,22 +1239,6 @@ extern kern_return_t thread_get_current_voucher_origin_pid(int32_t *pid);
 extern void set_thread_rwlock_boost(void);
 extern void clear_thread_rwlock_boost(void);
 
-/*! @function thread_has_thread_name
- *   @abstract Checks if a thread has a name.
- *   @discussion This function takes one input, a thread, and returns a boolean value indicating if that thread already has a name associated with it.
- *   @param th The thread to inspect.
- *   @result TRUE if the thread has a name, FALSE otherwise.
- */
-extern boolean_t thread_has_thread_name(thread_t th);
-
-/*! @function thread_set_thread_name
- *   @abstract Set a thread's name.
- *   @discussion This function takes two input parameters: a thread to name, and the name to apply to the thread.  The name will be attached to the thread in order to better identify the thread.
- *   @param th The thread to be named.
- *   @param name The name to apply to the thread.
- */
-extern void thread_set_thread_name(thread_t th, const char* name);
-
 extern void thread_enable_send_importance(thread_t thread, boolean_t enable);
 
 /*
@@ -1268,6 +1300,21 @@ extern bool thread_get_no_smt(void);
 
 #endif  /* XNU_KERNEL_PRIVATE */
 
+/*! @function thread_has_thread_name
+ *   @abstract Checks if a thread has a name.
+ *   @discussion This function takes one input, a thread, and returns a boolean value indicating if that thread already has a name associated with it.
+ *   @param th The thread to inspect.
+ *   @result TRUE if the thread has a name, FALSE otherwise.
+ */
+extern boolean_t thread_has_thread_name(thread_t th);
+
+/*! @function thread_set_thread_name
+ *   @abstract Set a thread's name.
+ *   @discussion This function takes two input parameters: a thread to name, and the name to apply to the thread.  The name will be copied over to the thread in order to better identify the thread.  If the name is longer than MAXTHREADNAMESIZE - 1, it will be truncated.
+ *   @param th The thread to be named.
+ *   @param name The name to apply to the thread.
+ */
+extern void thread_set_thread_name(thread_t th, const char* name);
 
 /*! @function kernel_thread_start
  *   @abstract Create a kernel thread.
@@ -1293,6 +1340,8 @@ extern ipc_port_t convert_thread_inspect_to_port(thread_inspect_t);
 extern boolean_t is_vm_privileged(void);
 extern boolean_t set_vm_privilege(boolean_t);
 extern kern_allocation_name_t thread_set_allocation_name(kern_allocation_name_t new_name);
+extern void *thread_iokit_tls_get(uint32_t index);
+extern void thread_iokit_tls_set(uint32_t index, void * data);
 #endif /* KERNEL_PRIVATE */
 
 __END_DECLS