Thread and thread_ro structures
Core thread structures and accessors. thread_ro_t / struct thread_ro hold the read-only, immutable half of a thread's state (credentials, task, proc); get_thread_ro and related accessors retrieve it.
thread_set_tag_internal source
static inline thread_tag_t thread_set_tag_internal(thread_t thread, thread_tag_t tag) { return os_atomic_or_orig(&thread->thread_tag, tag, relaxed); }
thread_get_tag_internal source
static inline thread_tag_t thread_get_tag_internal(thread_t thread) { return thread->thread_tag; }
thread_ro source struct
!
@struct thread_ro
@brief
A structure allocated in a read only zone that safely
represents the linkages of a thread to its cred, proc, task, ...
@discussion
The lifetime of a @c thread_ro structure is 1:1 with that
of a @c thread_t or a @c uthread_t and holding a thread reference
always allows to dereference this structure safely.
struct thread_ro { struct thread *tro_owner; #if MACH_BSD __xnu_struct_group(thread_ro_creds, tro_creds, { /* * @c tro_cred holds the current thread credentials. * * For most threads, this is a cache of the proc's * credentials that has been updated at the last * syscall boundary via current_cached_proc_cred_update(). * * If the thread assumed a different identity using settid(), * then the proc cached credential lives in @c tro_realcred * instead. */ struct ucred *tro_cred; struct ucred *tro_realcred; }); struct proc *tro_proc; struct proc_ro *tro_proc_ro; #endif struct task *tro_task; struct ipc_port *tro_ports[THREAD_SELF_PORT_COUNT]; /* no right */ #if CONFIG_CSR struct ipc_port *tro_settable_self_port; /* send right */ #endif /* CONFIG_CSR */ struct exception_action *tro_exc_actions; }
thread source struct
struct thread { #if MACH_ASSERT #define THREAD_MAGIC 0x1234ABCDDCBA4321ULL /* Ensure nothing uses &thread as a queue entry */ uint64_t thread_magic; #endif /* MACH_ASSERT */ /* * NOTE: The runq field in the thread structure has an unusual * locking protocol. If its value is PROCESSOR_NULL, then it is * locked by the thread_lock, but if its value is something else * then it is locked by the associated run queue lock. It is * set to PROCESSOR_NULL without holding the thread lock, but the * transition from PROCESSOR_NULL to non-null must be done * under the thread lock and the run queue lock. To enforce the * protocol, runq should only be accessed using the * thread_get/set/clear_runq functions and locked variants below. * * New waitq APIs allow the 'links' and '__runq' fields to be * anywhere in the thread structure. */ 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_sched wait_prioq_links; /* priority ordered waitq links */ }; event64_t wait_event; /* wait queue event */ struct { processor_t runq; } __runq; /* internally managed run queue assignment, see above comment */ … more in source
task_watch_t source typedef
Taskwatch related. TODO: find this a better home
typedef struct task_watcher task_watch_t;
thread_rr_state_t source typedef
CONFIG_EXCLAVES
typedef union thread_rr_state { uint32_t trr_value; struct { #define TRR_FAULT_NONE 0 #define TRR_FAULT_PENDING 1 #define TRR_FAULT_OBSERVED 2 /* * Set to TRR_FAULT_PENDING with interrupts disabled * by the thread when it is entering a user fault codepath. * * Moved to TRR_FAULT_OBSERVED from TRR_FAULT_PENDING: * - by the thread if at IPI time, * - or by task_restartable_ranges_synchronize() if the thread * is interrupted (under the thread lock) * * Cleared by the thread when returning from a user fault * codepath. */ uint8_t trr_fault_state; /* * Set by task_restartable_ranges_synchronize() * if trr_fault_state is TRR_FAULT_OBSERVED * and a rendez vous at the AST is required. * * Set atomically if trr_fault_state == TRR_FAULT_OBSERVED, * and trr_ipi_ack_pending == 0 */ uint8_t trr_sync_waiting; /* * Updated under the thread_lock(), * set by task_restartable_ranges_synchronize() * when the thread was IPIed and the caller is waiting * for an ACK. */ uint16_t trr_ipi_ack_pending; }; } thread_rr_state_t;thread_pri_floor_t source typedef
XNU_KERNEL_PRIVATE
typedef struct thread_pri_floor { thread_t thread; } thread_pri_floor_t;thread_deallocate source · thread_deallocate reference
extern void thread_deallocate( thread_t thread);
thread_terminate source · thread_terminate reference
extern kern_return_t thread_terminate( thread_t thread);
thread_start_in_assert_wait source
extern void thread_start_in_assert_wait( thread_t thread, struct waitq *waitq, event64_t event, wait_interrupt_t interruptible) __attribute__ ((noinline));
thread_exception_enqueue source
extern void thread_exception_enqueue( task_t task, thread_t thread, exception_type_t etype);
thread_backtrace_enqueue source
extern void thread_backtrace_enqueue( kcdata_object_t obj, exception_port_t ports[static BT_EXC_PORTS_COUNT], exception_type_t etype);
thread_copy_resource_info source
extern void thread_copy_resource_info( thread_t dst_thread, thread_t src_thread);
thread_info_internal source
extern kern_return_t thread_info_internal( thread_t thread, thread_flavor_t flavor, thread_info_t thread_info_out, mach_msg_type_number_t *thread_info_count);
kernel_thread_create source
extern kern_return_t kernel_thread_create( thread_continue_t continuation, void *parameter, integer_t priority, thread_t *new_thread);
kernel_thread_start_priority source
extern kern_return_t kernel_thread_start_priority( thread_continue_t continuation, void *parameter, integer_t priority, thread_t *new_thread);
machine_switch_context source
extern thread_t machine_switch_context( thread_t old_thread, thread_continue_t continuation, thread_t new_thread);
machine_load_context source
extern void machine_load_context( thread_t thread) __attribute__((noreturn));
machine_thread_state_initialize source
extern void machine_thread_state_initialize( thread_t thread);
machine_thread_set_state source
extern kern_return_t machine_thread_set_state( thread_t thread, thread_flavor_t flavor, thread_state_t state, mach_msg_type_number_t count);
machine_thread_reset_pc source
extern void machine_thread_reset_pc( thread_t thread, mach_vm_address_t pc);
machine_thread_on_core_allow_invalid source
extern boolean_t machine_thread_on_core_allow_invalid( thread_t thread);
machine_thread_get_state source
extern kern_return_t machine_thread_get_state( thread_t thread, thread_flavor_t flavor, thread_state_t state, mach_msg_type_number_t *count);
machine_thread_state_convert_from_user source
extern kern_return_t machine_thread_state_convert_from_user( thread_t thread, thread_flavor_t flavor, thread_state_t tstate, mach_msg_type_number_t count, thread_state_t old_tstate, mach_msg_type_number_t old_count, thread_set_status_flags_t tssf_flags);
machine_thread_state_convert_to_user source
extern kern_return_t machine_thread_state_convert_to_user( thread_t thread, thread_flavor_t flavor, thread_state_t tstate, mach_msg_type_number_t *count, thread_set_status_flags_t tssf_flags);
machine_thread_dup source
extern kern_return_t machine_thread_dup( thread_t self, thread_t target, boolean_t is_corpse);
machine_thread_state_is_debug_flavor source
extern bool machine_thread_state_is_debug_flavor(int flavor);
machine_thread_create source
__has_feature(ptrauth_calls)
extern void machine_thread_create( thread_t thread, task_t task, bool first_thread);
machine_thread_process_signature source
extern kern_return_t machine_thread_process_signature( thread_t thread, task_t task);
machine_thread_get_kern_state source
extern kern_return_t machine_thread_get_kern_state( thread_t thread, thread_flavor_t flavor, thread_state_t tstate, mach_msg_type_number_t *count);
machine_thread_inherit_taskwide source
extern kern_return_t machine_thread_inherit_taskwide( thread_t thread, task_t parent_task);
machine_thread_set_tsd_base source
extern kern_return_t machine_thread_set_tsd_base( thread_t thread, mach_vm_offset_t tsd_base);
processor_active_thread_no_smt source
extern bool processor_active_thread_no_smt(processor_t processor);
port_name_to_thread source
extern thread_t port_name_to_thread( mach_port_name_t port_name, port_intrans_options_t options);
thread_last_run_time source
MACH_KERNEL_PRIVATE
extern uint64_t thread_last_run_time( thread_t thread);
thread_setstatus source
extern kern_return_t thread_setstatus( thread_t thread, int flavor, thread_state_t tstate, mach_msg_type_number_t count);
thread_setstatus_from_user source
extern kern_return_t thread_setstatus_from_user( thread_t thread, int flavor, thread_state_t tstate, mach_msg_type_number_t count, thread_state_t old_tstate, mach_msg_type_number_t old_count, thread_set_status_flags_t flags);
thread_getstatus source
extern kern_return_t thread_getstatus( thread_t thread, int flavor, thread_state_t tstate, mach_msg_type_number_t *count);
thread_getstatus_to_user source
extern kern_return_t thread_getstatus_to_user( thread_t thread, int flavor, thread_state_t tstate, mach_msg_type_number_t *count, thread_set_status_flags_t flags);
thread_create_with_continuation source
extern kern_return_t thread_create_with_continuation( task_t task, thread_t *new_thread, thread_continue_t continuation);
main_thread_create_waiting source
extern kern_return_t main_thread_create_waiting( task_t task, thread_continue_t continuation, event_t event, thread_t *new_thread);
thread_create_workq_waiting source
extern kern_return_t thread_create_workq_waiting( task_t task, thread_continue_t thread_return, thread_t *new_thread, bool is_permanently_bound);
thread_create_aio_workq_waiting source
extern kern_return_t thread_create_aio_workq_waiting( task_t task, thread_continue_t thread_return, thread_t *new_thread);
thread_get_cpulimit source
extern int thread_get_cpulimit(int *action, uint8_t *percentage, uint64_t *interval_ns);
thread_set_cpulimit source
extern int thread_set_cpulimit(int action, uint8_t percentage, uint64_t interval_ns);
thread_cpulimit_interval_has_expired source
extern bool thread_cpulimit_interval_has_expired(uint64_t now);
thread_read_times source
extern void thread_read_times( thread_t thread, time_value_t *user_time, time_value_t *system_time, time_value_t *runnable_time);
thread_read_times_unsafe source
extern void thread_read_times_unsafe( thread_t thread, time_value_t *user_time, time_value_t *system_time, time_value_t *runnable_time);
thread_setuserstack source
extern void thread_setuserstack( thread_t thread, mach_vm_offset_t user_stack);
thread_setentrypoint source
extern void thread_setentrypoint( thread_t thread, mach_vm_offset_t entry);
thread_set_tsd_base source
extern kern_return_t thread_set_tsd_base( thread_t thread, mach_vm_offset_t tsd_base);
thread_userstack source
extern kern_return_t thread_userstack( thread_t, int, thread_state_t, unsigned int, mach_vm_offset_t *, int *, boolean_t);
thread_entrypoint source
extern kern_return_t thread_entrypoint( thread_t, int, thread_state_t, unsigned int, mach_vm_offset_t *);
thread_userstackdefault source
extern kern_return_t thread_userstackdefault( mach_vm_offset_t *, boolean_t);
thread_wire_internal source
extern kern_return_t thread_wire_internal( host_priv_t host_priv, thread_t thread, boolean_t wired, boolean_t *prev_state);
aio_workq_thread_init_and_wq_lock source
bsd/pthread/
extern event_t aio_workq_thread_init_and_wq_lock(task_t, thread_t);
thread_get_sigreturn_diversifier source
extern uint32_t thread_get_sigreturn_diversifier(thread_t thread);
uthread_set_exec_data source
extern void uthread_set_exec_data(struct uthread *uth, struct image_params *imgp);
uthread_assert_zero_proc_refcount source
extern void uthread_assert_zero_proc_refcount(struct uthread *);
uthread_get_syscall_rejection_flags source
extern uint64_t uthread_get_syscall_rejection_flags(void *);
uthread_get_syscall_rejection_mask source
extern uint64_t *uthread_get_syscall_rejection_mask(void *);
uthread_get_syscall_rejection_once_mask source
extern uint64_t *uthread_get_syscall_rejection_once_mask(void *);
uthread_syscall_rejection_is_enabled source
extern bool uthread_syscall_rejection_is_enabled(void *);
uthread_joiner_port source
CONFIG_DEBUG_SYSCALL_REJECTION
extern mach_port_name_t uthread_joiner_port(struct uthread *);
thread_process_signature source
extern kern_return_t thread_process_signature(thread_t thread, task_t task);
thread_set_wq_state32 source
extern kern_return_t thread_set_wq_state32( thread_t thread, thread_state_t tstate);
thread_set_wq_state64 source
extern kern_return_t thread_set_wq_state64( thread_t thread, thread_state_t tstate);
fd_guard_ast source
extern void fd_guard_ast(thread_t, mach_exception_code_t, mach_exception_subcode_t);
vn_guard_ast source
extern void vn_guard_ast(thread_t, mach_exception_code_t, mach_exception_subcode_t);
mach_port_guard_ast source
extern void mach_port_guard_ast(thread_t, mach_exception_code_t, mach_exception_subcode_t);
virt_memory_guard_ast source
extern void virt_memory_guard_ast(thread_t, mach_exception_code_t, mach_exception_subcode_t);
thread_ast_mach_exception source
extern void thread_ast_mach_exception(thread_t, int, exception_type_t, mach_exception_code_t, mach_exception_subcode_t, bool, bool);
thread_guard_violation source
extern void thread_guard_violation(thread_t, mach_exception_code_t, mach_exception_subcode_t, bool);
thread_get_voucher_origin_pid source
extern kern_return_t thread_get_voucher_origin_pid(thread_t thread, int32_t *pid);
thread_get_voucher_origin_proximate_pid source
extern kern_return_t thread_get_voucher_origin_proximate_pid(thread_t thread, int32_t *origin_pid, int32_t *proximate_pid);
thread_get_current_voucher_origin_pid source
extern kern_return_t thread_get_current_voucher_origin_pid(int32_t *pid);
thread_enable_send_importance source
extern void thread_enable_send_importance(thread_t thread, boolean_t enable);
machine_thread_siguctx_pointer_convert_to_user source
Translate signal context data pointer to userspace representation
extern kern_return_t machine_thread_siguctx_pointer_convert_to_user( thread_t thread, user_addr_t *uctxp);
machine_thread_set_insn_copy_optout source
extern void machine_thread_set_insn_copy_optout(thread_t thr);
machine_thread_function_pointers_convert_from_user source
Translate array of function pointer syscall arguments from userspace representation
extern kern_return_t machine_thread_function_pointers_convert_from_user( thread_t thread, user_addr_t *fptrs, uint32_t count);
ctid_get_thread source
! @function ctid_get_thread
@abstract translates a ctid_t to thread_t
@discussion ctid are system wide compact thread-id
associated to thread_t at thread creation
and recycled at thread termination. If a ctid is
referenced past the corresponding thread termination,
it is considered stale, and the behavior is not defined.
Note that this call does not acquire a reference on the thread,
so as soon as the matching thread terminates, the ctid
will become stale, and it could be re-used and associated with
another thread. You must externally guarantee that the thread
will not exit while you are using its ctid.
@result thread_t corresponding to ctid
extern thread_t ctid_get_thread(ctid_t ctid);
ctid_get_thread_unsafe source
! @function ctid_get_thread
@abstract translates a ctid_t to thread_t
@discussion Unsafe variant of ctid_get_thread() to be used
when the caller can't guarantee the liveness of this ctid_t.
may return NULL or a freed thread_t.
extern thread_t ctid_get_thread_unsafe(ctid_t ctid);
thread_get_ctid source
!
@function thread_get_ctid
@abstract returns the ctid of thread.
@param thread to find the corresponding ctid.
@discussion the ctid provided will become stale after the matching thread
terminates.
@result uint32_t ctid.
extern ctid_t thread_get_ctid(thread_t thread);
thread_floor_boost_set_promotion_locked source
extern void thread_floor_boost_set_promotion_locked(thread_t thread);
thread_priority_floor_start source
! @function thread_priority_floor_start
@abstract boost the current thread priority to floor.
@discussion Increase the priority of the current thread to at least MINPRI_FLOOR.
The boost will be mantained until a corresponding thread_priority_floor_end()
is called. Every call of thread_priority_floor_start() needs to have a corresponding
call to thread_priority_floor_end() from the same thread.
No thread can return to userspace before calling thread_priority_floor_end().
NOTE: avoid to use this function. Try to use gate_t or sleep_with_inheritor()
instead.
@result a token to be given to the corresponding thread_priority_floor_end()
extern thread_pri_floor_t thread_priority_floor_start(void);
thread_priority_floor_end source
! @function thread_priority_floor_end
@abstract ends the floor boost.
@param token the token obtained from thread_priority_floor_start()
@discussion ends the priority floor boost started with thread_priority_floor_start()
extern void thread_priority_floor_end(thread_pri_floor_t *token);
convert_thread_to_port_immovable source
extern ipc_port_t convert_thread_to_port_immovable(thread_t);
convert_thread_inspect_to_port source
extern ipc_port_t convert_thread_inspect_to_port(thread_inspect_t);
convert_thread_array_to_ports source
extern void convert_thread_array_to_ports(thread_act_array_t, size_t, mach_thread_flavor_t);
thread_set_allocation_name source
extern kern_allocation_name_t thread_set_allocation_name(kern_allocation_name_t new_name);
thread_create_immovable source
extern kern_return_t thread_create_immovable(task_t task, thread_t *new_thread);
thread_get_ipc_propagate_attr source
extern kern_return_t thread_get_ipc_propagate_attr(thread_t thread, struct thread_attr_for_ipc_propagation *attr);
thread_get_current_exec_path source
extern size_t thread_get_current_exec_path(char *path, size_t size);
thread_get_thread_name source
KERNEL_PRIVATE
extern void thread_get_thread_name(thread_t th, char* name);
thread_get_runq source
Read the runq assignment, under the thread lock.
extern processor_t thread_get_runq(thread_t thread);
thread_get_runq_locked source
Read the runq assignment, under both the thread lock and
the pset lock corresponding to the last non-null assignment.
extern processor_t thread_get_runq_locked(thread_t thread);
thread_set_runq_locked source
Set the runq assignment to a non-null value, under both the
thread lock and the pset lock corresponding to the new
assignment.
extern void thread_set_runq_locked(thread_t thread, processor_t new_runq);
thread_clear_runq source
Set the runq assignment to PROCESSOR_NULL, under the pset
lock corresponding to the current non-null assignment.
extern void thread_clear_runq(thread_t thread);
thread_clear_runq_locked source
Set the runq assignment to PROCESSOR_NULL, under both the
thread lock and the pset lock corresponding to the current
non-null assignment.
extern void thread_clear_runq_locked(thread_t thread);
thread_assert_runq_null source
Assert the runq assignment to be PROCESSOR_NULL, under
some guarantee that the runq will not change from null to
non-null, such as holding the thread lock.
extern void thread_assert_runq_null(thread_t thread);
thread_assert_runq_nonnull source
Assert the runq assignment to be non-null, under the pset
lock corresponding to the current non-null assignment.
extern void thread_assert_runq_nonnull(thread_t thread);
thread_supports_cooperative_workqueue source
extern bool thread_supports_cooperative_workqueue(thread_t thread);
thread_evaluate_workqueue_quantum_expiry source
extern void thread_evaluate_workqueue_quantum_expiry(thread_t thread);
thread_has_expired_workqueue_quantum source
extern bool thread_has_expired_workqueue_quantum(thread_t thread, bool should_trace);
thread_associate_txm_thread_stack source
extern void thread_associate_txm_thread_stack(uintptr_t thread_stack);
thread_disassociate_txm_thread_stack source
extern void thread_disassociate_txm_thread_stack(uintptr_t thread_stack);
thread_get_exception_ports source · thread_get_exception_ports reference
Kernel side prototypes for MIG routines
extern kern_return_t thread_get_exception_ports( thread_t thread, exception_mask_t exception_mask, exception_mask_array_t masks, mach_msg_type_number_t *CountCnt, exception_port_array_t ports, exception_behavior_array_t behaviors, thread_state_flavor_array_t flavors);
thread_get_special_port source · thread_get_special_port reference
extern kern_return_t thread_get_special_port( thread_inspect_t thread, int which, ipc_port_t *portp);
thread_has_thread_name source · thread_has_thread_name reference
! @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);
thread_set_thread_name source · thread_set_thread_name reference
! @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);
kernel_thread_start source · kernel_thread_start reference
! @function kernel_thread_start
@abstract Create a kernel thread.
@discussion This function takes three input parameters, namely reference
to the function that the thread should execute, caller specified data
and a reference which is used to return the newly created kernel
thread. The function returns KERN_SUCCESS on success or an appropriate
kernel code type indicating the error. It may be noted that the caller
is responsible for explicitly releasing the reference to the created
thread when no longer needed. This should be done by calling
thread_deallocate(new_thread).
@param continuation A C-function pointer where the thread will begin execution.
@param parameter Caller specified data to be passed to the new thread.
@param new_thread Reference to the new thread is returned in this parameter.
@result Returns KERN_SUCCESS on success or an appropriate kernel code type.
extern kern_return_t kernel_thread_start( thread_continue_t continuation, void *parameter, thread_t *new_thread);