X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..5ba3f43ea354af8ad55bea84372a2bc834d8757c:/bsd/sys/pthread_shims.h diff --git a/bsd/sys/pthread_shims.h b/bsd/sys/pthread_shims.h index 872173b09..2256a4a01 100644 --- a/bsd/sys/pthread_shims.h +++ b/bsd/sys/pthread_shims.h @@ -35,22 +35,38 @@ #include #include +#include #include +#include #include #include #include -#include #ifndef PTHREAD_INTERNAL struct uthread; #define M_PROC 41 #endif -#ifdef NEEDS_SCHED_CALL_T +#if !defined(_SCHED_CALL_T_DEFINED) +#define _SCHED_CALL_T_DEFINED typedef void (*sched_call_t)(int type, thread_t thread); #endif typedef struct workq_reqthreads_req_s {unsigned long priority; int count;} *workq_reqthreads_req_t; +typedef struct workq_threadreq_s { void *opaqueptr[2]; uint32_t opaqueint[2];} *workq_threadreq_t; +enum workq_threadreq_type { + WORKQ_THREADREQ_KEVENT = 1, + WORKQ_THREADREQ_WORKLOOP = 2, + WORKQ_THREADREQ_WORKLOOP_NO_THREAD_CALL = 3, + WORKQ_THREADREQ_REDRIVE = 4, +}; +enum workq_threadreq_op { + WORKQ_THREADREQ_CHANGE_PRI = 1, + WORKQ_THREADREQ_CANCEL = 2, + WORKQ_THREADREQ_CHANGE_PRI_NO_THREAD_CALL = 3, +}; +#define WORKQ_THREADREQ_FLAG_NOEMERGENCY 0x1 + /* * Increment each time new reserved slots are used. When the pthread @@ -59,14 +75,16 @@ typedef struct workq_reqthreads_req_s {unsigned long priority; int count;} *work */ #define PTHREAD_FUNCTIONS_TABLE_VERSION 1 -typedef struct pthread_functions_s { +typedef const struct pthread_functions_s { int version; /* internal calls, kernel core -> kext */ void (*pthread_init)(void); - int (*fill_procworkqueue)(proc_t p, struct proc_workqueueinfo * pwqinfo); - void (*workqueue_init_lock)(proc_t p); - void (*workqueue_destroy_lock)(proc_t p); + int (*fill_procworkqueue)(proc_t p, void* pwqinfo); + + void (*__unused1)(void); + void (*__unused2)(void); + void (*workqueue_exit)(struct proc *p); void (*workqueue_mark_exiting)(struct proc *p); void (*workqueue_thread_yielded)(void); @@ -108,11 +126,57 @@ typedef struct pthread_functions_s { /* Resolve a pthread_priority_t to a QoS/relative pri */ integer_t (*thread_qos_from_pthread_priority)(unsigned long pthread_priority, unsigned long *flags); + /* try to get wq flags in debugger context */ + uint32_t (*get_pwq_state_kdp)(proc_t p); + + void (*__unused3)(void); + unsigned long (*pthread_priority_canonicalize2)(unsigned long pthread_priority, boolean_t propagation); + + /* Returns true on success, false on mismatch */ + boolean_t (*workq_thread_has_been_unbound)(thread_t th, int qos_class); + + void (*pthread_find_owner)(thread_t thread, struct stackshot_thread_waitinfo *waitinfo); + void *(*pthread_get_thread_kwq)(thread_t thread); + + /* + * Submits a threadreq to the workq system. + * + * If type is WORKQ_THREADREQ_KEVENT, the semantics are similar to a call + * to workq_reqthreads and the kevent bind function will be called to + * indicate the thread fulfilling the request. The req argument is ignored. + * + * If type is WORKQ_THREADREQ_WORKLOOP, The req argument should point to + * allocated memory of at least the sizeof(workq_threadreq_t). That memory + * is lent to the workq system until workloop_fulfill_threadreq is called + * and passed the pointer, at which point it may be freed. + * + * The properties of the request are passed in the (pthread) priority and flags arguments. + * + * Will return zero upon success or an error value on failure. An error of + * ENOTSUP means the type argument was not understood. + */ + int (*workq_threadreq)(struct proc *p, workq_threadreq_t req, + enum workq_threadreq_type, unsigned long priority, int flags); + + /* + * Modifies an already submitted thread request. + * + * If operation is WORKQ_THREADREQ_CHANGE_PRI, arg1 is the new priority and arg2 is unused. + * + * If operation is WORKQ_THREADREQ_CANCEL, arg1 and arg2 are unused. + * + * Will return zero upon success or an error value on failure. An error of + * ENOTSUP means the operation argument was not understood. + */ + int (*workq_threadreq_modify)(struct proc *t, workq_threadreq_t req, + enum workq_threadreq_op operation, + unsigned long arg1, unsigned long arg2); + /* padding for future */ - void* _pad[95]; -} *pthread_functions_t; + void * _pad[87]; +} * pthread_functions_t; -typedef struct pthread_callbacks_s { +typedef const struct pthread_callbacks_s { int version; /* config information */ @@ -129,16 +193,22 @@ typedef struct pthread_callbacks_s { void (*proc_set_wqthread)(struct proc *t, user_addr_t addr); int (*proc_get_pthsize)(struct proc *t); void (*proc_set_pthsize)(struct proc *t, int size); - user_addr_t (*proc_get_targconc)(struct proc *t); - void (*proc_set_targconc)(struct proc *t, user_addr_t addr); +#if defined(__arm64__) + unsigned __int128 (*atomic_fetch_add_128_relaxed)(_Atomic unsigned __int128 *ptr, + unsigned __int128 value); + unsigned __int128 (*atomic_load_128_relaxed)(_Atomic unsigned __int128 *ptr); +#else + void *unused_was_proc_get_targconc; + void *unused_was_proc_set_targconc; +#endif uint64_t (*proc_get_dispatchqueue_offset)(struct proc *t); void (*proc_set_dispatchqueue_offset)(struct proc *t, uint64_t offset); - lck_spin_t* (*proc_get_wqlockptr)(struct proc *t); - boolean_t* (*proc_get_wqinitingptr)(struct proc *t); + void *unused_was_proc_get_wqlockptr; + void *unused_was_proc_get_wqinitingptr; void* (*proc_get_wqptr)(struct proc *t); void (*proc_set_wqptr)(struct proc *t, void* ptr); - int (*proc_get_wqsize)(struct proc *t); - void (*proc_set_wqsize)(struct proc *t, int sz); + void *unused_was_proc_get_wqsize; + void *unused_was_proc_set_wqsize; void (*proc_lock)(struct proc *t); void (*proc_unlock)(struct proc *t); task_t (*proc_get_task)(struct proc *t); @@ -165,18 +235,19 @@ typedef struct pthread_callbacks_s { /* wq functions */ kern_return_t (*thread_set_wq_state32)(thread_t thread, thread_state_t state); +#if !defined(__arm__) kern_return_t (*thread_set_wq_state64)(thread_t thread, thread_state_t state); +#endif /* sched_prim.h */ - void (*thread_exception_return)(); - void (*thread_bootstrap_return)(); + void (*thread_exception_return)(void); + void (*thread_bootstrap_return)(void); /* kern/clock.h */ void (*absolutetime_to_microtime)(uint64_t abstime, clock_sec_t *secs, clock_usec_t *microsecs); - /* osfmk/kern/task.h */ - int (*proc_restore_workq_bgthreadpolicy)(thread_t t); - int (*proc_apply_workq_bgthreadpolicy)(thread_t t); + kern_return_t (*thread_set_workq_pri)(thread_t thread, integer_t priority, integer_t policy); + kern_return_t (*thread_set_workq_qos)(thread_t thread, int qos_tier, int relprio); /* osfmk/kern/thread.h */ struct uthread* (*get_bsdthread_info)(thread_t th); @@ -216,13 +287,17 @@ typedef struct pthread_callbacks_s { /* osfmk//machine_routines.h */ int (*ml_get_max_cpus)(void); + #if defined(__arm__) + uint32_t (*map_is_1gb)(vm_map_t); + #endif /* xnu: struct proc p_dispatchqueue_serialno_offset additions */ uint64_t (*proc_get_dispatchqueue_serialno_offset)(struct proc *p); void (*proc_set_dispatchqueue_serialno_offset)(struct proc *p, uint64_t offset); - user_addr_t (*proc_get_stack_addr_hint)(struct proc *p); - void (*proc_set_stack_addr_hint)(struct proc *p, user_addr_t stack_addr_hint); + int (*proc_usynch_thread_qos_add_override_for_resource_check_owner)(thread_t thread, int override_qos, boolean_t first_override_for_resource, + user_addr_t resource, int resource_type, user_addr_t user_lock_addr, mach_port_name_t user_lock_owner); + void *unused_was_proc_set_stack_addr_hint; uint32_t (*proc_get_pthread_tsd_offset)(struct proc *p); void (*proc_set_pthread_tsd_offset)(struct proc *p, uint32_t pthread_tsd_offset); @@ -230,8 +305,8 @@ typedef struct pthread_callbacks_s { kern_return_t (*thread_set_tsd_base)(thread_t thread, mach_vm_offset_t tsd_base); int (*proc_usynch_get_requested_thread_qos)(struct uthread *); - boolean_t (*proc_usynch_thread_qos_add_override)(struct uthread *, uint64_t tid, int override_qos, boolean_t first_override_for_resource); - boolean_t (*proc_usynch_thread_qos_remove_override)(struct uthread *, uint64_t tid); + uint64_t (*proc_get_mach_thread_self_tsd_offset)(struct proc *p); + void (*proc_set_mach_thread_self_tsd_offset)(struct proc *p, uint64_t mach_thread_self_tsd_offset); kern_return_t (*thread_policy_get)(thread_t t, thread_policy_flavor_t flavor, thread_policy_t info, mach_msg_type_number_t *count, boolean_t *get_default); boolean_t (*qos_main_thread_active)(void); @@ -242,8 +317,37 @@ typedef struct pthread_callbacks_s { boolean_t (*proc_usynch_thread_qos_remove_override_for_resource)(task_t task, struct uthread *, uint64_t tid, user_addr_t resource, int resource_type); boolean_t (*proc_usynch_thread_qos_reset_override_for_resource)(task_t task, struct uthread *, uint64_t tid, user_addr_t resource, int resource_type); + boolean_t (*proc_init_wqptr_or_wait)(proc_t proc); + + uint16_t (*thread_set_tag)(thread_t thread, uint16_t tag); + uint16_t (*thread_get_tag)(thread_t thread); + + int (*proc_usynch_thread_qos_squash_override_for_resource)(thread_t thread, user_addr_t resource, int resource_type); + int (*task_get_default_manager_qos)(task_t task); + + int (*thread_create_workq_waiting)(task_t task, thread_continue_t thread_return, event_t event, thread_t *new_thread); + + user_addr_t (*proc_get_stack_addr_hint)(struct proc *p); + void (*proc_set_stack_addr_hint)(struct proc *p, user_addr_t stack_addr_hint); + + uint64_t (*proc_get_return_to_kernel_offset)(struct proc *t); + void (*proc_set_return_to_kernel_offset)(struct proc *t, uint64_t offset); + + /* indicates call is being made synchronously with workq_threadreq call */ +# define WORKLOOP_FULFILL_THREADREQ_SYNC 0x1 +# define WORKLOOP_FULFILL_THREADREQ_CANCEL 0x2 + int (*workloop_fulfill_threadreq)(struct proc *p, workq_threadreq_t req, thread_t thread, int flags); + void (*thread_will_park_or_terminate)(thread_t thread); + + /* For getting maximum parallelism for a given QoS */ + uint32_t (*qos_max_parallelism)(int qos, uint64_t options); + + /* proc_internal.h: struct proc user_stack accessor */ + user_addr_t (*proc_get_user_stack)(struct proc *p); + void (*proc_set_user_stack)(struct proc *p, user_addr_t user_stack); + /* padding for future */ - void* _pad[84]; + void* _pad[69]; } *pthread_callbacks_t;