Thread and thread_ro structures

osfmk/kern/thread.h · 2027 lines · browse source

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_ro_t source typedef
typedef struct thread_ro *thread_ro_t;
ctid_t source typedef
Size in bits of compact thread id (ctid).
typedef uint32_t ctid_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;
sched_call_t source typedef
typedef void (*sched_call_t)( int type, thread_t thread);
cpuvn_e source typedef
typedef enum cpuvn { CPUVN_CI = 1 } cpuvn_e;
thread_pri_floor_t source typedef
XNU_KERNEL_PRIVATE
typedef struct thread_pri_floor { thread_t thread; } thread_pri_floor_t;
thread_init source
extern void thread_init(void);
thread_start source
extern void thread_start( thread_t thread) __attribute__ ((noinline));
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));
kernel_thread_create source
extern kern_return_t kernel_thread_create( thread_continue_t continuation, void *parameter, integer_t priority, thread_t *new_thread);
machine_load_context source
extern void machine_load_context( thread_t thread) __attribute__((noreturn));
machine_thread_create source
__has_feature(ptrauth_calls)
extern void machine_thread_create( thread_t thread, task_t task, bool first_thread);
thread_set_options source
CONFIG_SCHED_SMT
extern void thread_set_options(uint32_t thopt);
port_name_to_thread source
extern thread_t port_name_to_thread( mach_port_name_t port_name, port_intrans_options_t options);
thread_require source
BSD_KERNEL_PRIVATE
extern void thread_require( thread_t thread);
thread_last_run_time source
MACH_KERNEL_PRIVATE
extern uint64_t thread_last_run_time( thread_t 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_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_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);
get_bsdthread_info source
extern struct uthread *get_bsdthread_info(thread_t) __pure2;
get_machthread source
extern thread_t get_machthread(struct uthread *) __pure2;
uthread_tid source
extern uint64_t uthread_tid(struct uthread *) __pure2;
uthread_init source
extern void uthread_init(task_t, struct uthread *, thread_ro_t, int);
uthread_cleanup_name source
extern void uthread_cleanup_name(struct uthread *uthread);
uthread_cleanup source
extern void uthread_cleanup(struct uthread *, thread_ro_t);
uthread_destroy source
extern void uthread_destroy(struct uthread *);
uthread_set_exec_data source
extern void uthread_set_exec_data(struct uthread *uth, struct image_params *imgp);
uthread_is64bit source
extern bool uthread_is64bit(struct uthread *uth) __pure2;
uthread_joiner_port source
CONFIG_DEBUG_SYSCALL_REJECTION
extern mach_port_name_t uthread_joiner_port(struct uthread *);
uthread_joiner_wake source
extern void uthread_joiner_wake(task_t task, struct uthread *);
thread_update_io_stats source
extern void thread_update_io_stats(thread_t, int size, int io_flags);
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_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);
thread_set_allocation_name source
extern kern_allocation_name_t thread_set_allocation_name(kern_allocation_name_t new_name);
thread_iokit_tls_set source
extern void thread_iokit_tls_set(uint32_t index, void * data);
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_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);
current_thread source · current_thread reference
extern thread_t current_thread(void) __pure2;
thread_tid source · thread_tid reference
extern uint64_t thread_tid(thread_t thread) __pure2;
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);