]>
Commit | Line | Data |
---|---|---|
f1a1da6c A |
1 | /* |
2 | * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
a0619f9c | 5 | * |
f1a1da6c A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
a0619f9c | 14 | * |
f1a1da6c A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
a0619f9c | 17 | * |
f1a1da6c A |
18 | * The Original Code and all software distributed under the License are |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
a0619f9c | 25 | * |
f1a1da6c A |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ | |
28 | ||
29 | #ifndef _SYS_PTHREAD_INTERNAL_H_ | |
30 | #define _SYS_PTHREAD_INTERNAL_H_ | |
31 | ||
214d78a2 A |
32 | #include <pthread/bsdthread_private.h> |
33 | #include <pthread/priority_private.h> | |
34 | #include <pthread/workqueue_syscalls.h> | |
35 | ||
f1a1da6c | 36 | #ifdef KERNEL |
214d78a2 | 37 | struct ksyn_waitq_element; |
a0619f9c | 38 | #include <stdatomic.h> |
f1a1da6c | 39 | #include <kern/thread_call.h> |
a0619f9c | 40 | #include <kern/kcdata.h> |
f1a1da6c A |
41 | #include <sys/pthread_shims.h> |
42 | #include <sys/queue.h> | |
a0619f9c A |
43 | #include <sys/proc_info.h> |
44 | ||
45 | #ifdef __arm64__ | |
46 | #define PTHREAD_INLINE_RMW_ATOMICS 0 | |
47 | #else | |
48 | #define PTHREAD_INLINE_RMW_ATOMICS 1 | |
f1a1da6c | 49 | #endif |
a0619f9c | 50 | #endif // KERNEL |
f1a1da6c A |
51 | |
52 | #include "kern/synch_internal.h" | |
53 | #include "kern/workqueue_internal.h" | |
54 | #include "kern/kern_trace.h" | |
55 | #include "pthread/qos.h" | |
56 | #include "private/qos_private.h" | |
57 | ||
58 | /* pthread userspace SPI feature checking, these constants are returned from bsdthread_register, | |
59 | * as a bitmask, to inform userspace of the supported feature set. Old releases of OS X return | |
60 | * from this call either zero or -1, allowing us to return a positive number for feature bits. | |
61 | */ | |
62 | #define PTHREAD_FEATURE_DISPATCHFUNC 0x01 /* same as WQOPS_QUEUE_NEWSPISUPP, checks for dispatch function support */ | |
63 | #define PTHREAD_FEATURE_FINEPRIO 0x02 /* are fine grained prioirities available */ | |
64 | #define PTHREAD_FEATURE_BSDTHREADCTL 0x04 /* is the bsdthread_ctl syscall available */ | |
65 | #define PTHREAD_FEATURE_SETSELF 0x08 /* is the BSDTHREAD_CTL_SET_SELF command of bsdthread_ctl available */ | |
66 | #define PTHREAD_FEATURE_QOS_MAINTENANCE 0x10 /* is QOS_CLASS_MAINTENANCE available */ | |
2546420a A |
67 | #define PTHREAD_FEATURE_RESERVED 0x20 /* burnt, shipped in OSX 10.11 & iOS 9 with partial kevent delivery support */ |
68 | #define PTHREAD_FEATURE_KEVENT 0x40 /* supports direct kevent delivery */ | |
a0619f9c | 69 | #define PTHREAD_FEATURE_WORKLOOP 0x80 /* supports workloops */ |
f1a1da6c A |
70 | #define PTHREAD_FEATURE_QOS_DEFAULT 0x40000000 /* the kernel supports QOS_CLASS_DEFAULT */ |
71 | ||
f1a1da6c A |
72 | /* userspace <-> kernel registration struct, for passing data to/from the kext during main thread init. */ |
73 | struct _pthread_registration_data { | |
2546420a A |
74 | /* |
75 | * version == sizeof(struct _pthread_registration_data) | |
76 | * | |
77 | * The structure can only grow, so we use its size as the version. | |
78 | * Userspace initializes this to the size of its structure and the kext | |
79 | * will copy out the version that was actually consumed. | |
80 | * | |
81 | * n.b. you must make sure the size of this structure isn't LP64-dependent | |
82 | */ | |
83 | uint64_t version; | |
84 | ||
f1a1da6c | 85 | uint64_t dispatch_queue_offset; /* copy-in */ |
2546420a A |
86 | uint64_t /* pthread_priority_t */ main_qos; /* copy-out */ |
87 | uint32_t tsd_offset; /* copy-in */ | |
a0619f9c A |
88 | uint32_t return_to_kernel_offset; /* copy-in */ |
89 | uint32_t mach_thread_self_offset; /* copy-in */ | |
214d78a2 | 90 | mach_vm_address_t stack_addr_hint; /* copy-out */ |
76b7b9a2 | 91 | uint32_t mutex_default_policy; /* copy-out */ |
2546420a | 92 | } __attribute__ ((packed)); |
f1a1da6c | 93 | |
214d78a2 A |
94 | /* |
95 | * "error" flags returned by fail condvar syscalls | |
96 | */ | |
97 | #define ECVCLEARED 0x100 | |
98 | #define ECVPREPOST 0x200 | |
99 | ||
f1a1da6c A |
100 | #ifdef KERNEL |
101 | ||
102 | /* The set of features, from the feature bits above, that we support. */ | |
103 | #define PTHREAD_FEATURE_SUPPORTED ( \ | |
104 | PTHREAD_FEATURE_DISPATCHFUNC | \ | |
105 | PTHREAD_FEATURE_FINEPRIO | \ | |
106 | PTHREAD_FEATURE_BSDTHREADCTL | \ | |
107 | PTHREAD_FEATURE_SETSELF | \ | |
108 | PTHREAD_FEATURE_QOS_MAINTENANCE | \ | |
964d3577 | 109 | PTHREAD_FEATURE_QOS_DEFAULT | \ |
a0619f9c A |
110 | PTHREAD_FEATURE_KEVENT | \ |
111 | PTHREAD_FEATURE_WORKLOOP ) | |
f1a1da6c A |
112 | |
113 | extern pthread_callbacks_t pthread_kern; | |
114 | ||
115 | struct ksyn_waitq_element { | |
116 | TAILQ_ENTRY(ksyn_waitq_element) kwe_list; /* link to other list members */ | |
117 | void * kwe_kwqqueue; /* queue blocked on */ | |
214d78a2 A |
118 | thread_t kwe_thread; |
119 | uint16_t kwe_state; /* state */ | |
120 | uint16_t kwe_flags; | |
f1a1da6c A |
121 | uint32_t kwe_lockseq; /* the sequence of the entry */ |
122 | uint32_t kwe_count; /* upper bound on number of matches still pending */ | |
123 | uint32_t kwe_psynchretval; /* thread retval */ | |
124 | void *kwe_uth; /* uthread */ | |
f1a1da6c A |
125 | }; |
126 | typedef struct ksyn_waitq_element * ksyn_waitq_element_t; | |
127 | ||
f1a1da6c A |
128 | #define PTH_DEFAULT_STACKSIZE 512*1024 |
129 | #define MAX_PTHREAD_SIZE 64*1024 | |
130 | ||
131 | /* exported from the kernel but not present in any headers. */ | |
132 | extern thread_t port_name_to_thread(mach_port_name_t port_name); | |
133 | ||
134 | /* function declarations for pthread_kext.c */ | |
135 | void pthread_init(void); | |
136 | void psynch_zoneinit(void); | |
137 | void _pth_proc_hashinit(proc_t p); | |
138 | void _pth_proc_hashdelete(proc_t p); | |
139 | void pth_global_hashinit(void); | |
140 | void psynch_wq_cleanup(void*, void*); | |
141 | ||
142 | void _pthread_init(void); | |
143 | int _fill_procworkqueue(proc_t p, struct proc_workqueueinfo * pwqinfo); | |
2546420a | 144 | uint32_t _get_pwq_state_kdp(proc_t p); |
f1a1da6c A |
145 | void _workqueue_exit(struct proc *p); |
146 | void _workqueue_mark_exiting(struct proc *p); | |
147 | void _workqueue_thread_yielded(void); | |
148 | sched_call_t _workqueue_get_sched_callback(void); | |
149 | ||
150 | int _bsdthread_create(struct proc *p, user_addr_t user_func, user_addr_t user_funcarg, user_addr_t user_stack, user_addr_t user_pthread, uint32_t flags, user_addr_t *retval); | |
151 | int _bsdthread_register(struct proc *p, user_addr_t threadstart, user_addr_t wqthread, int pthsize, user_addr_t dummy_value, user_addr_t targetconc_ptr, uint64_t dispatchqueue_offset, int32_t *retval); | |
152 | int _bsdthread_terminate(struct proc *p, user_addr_t stackaddr, size_t size, uint32_t kthport, uint32_t sem, int32_t *retval); | |
153 | int _bsdthread_ctl_set_qos(struct proc *p, user_addr_t cmd, mach_port_name_t kport, user_addr_t tsd_priority_addr, user_addr_t arg3, int *retval); | |
154 | int _bsdthread_ctl_set_self(struct proc *p, user_addr_t cmd, pthread_priority_t priority, mach_port_name_t voucher, _pthread_set_flags_t flags, int *retval); | |
215aeb03 A |
155 | int _bsdthread_ctl_qos_override_start(struct proc *p, user_addr_t cmd, mach_port_name_t kport, pthread_priority_t priority, user_addr_t resource, int *retval); |
156 | int _bsdthread_ctl_qos_override_end(struct proc *p, user_addr_t cmd, mach_port_name_t kport, user_addr_t resource, user_addr_t arg3, int *retval); | |
f1a1da6c A |
157 | int _bsdthread_ctl_qos_override_dispatch(struct proc __unused *p, user_addr_t __unused cmd, mach_port_name_t kport, pthread_priority_t priority, user_addr_t arg3, int __unused *retval); |
158 | int _bsdthread_ctl_qos_override_reset(struct proc __unused *p, user_addr_t __unused cmd, user_addr_t arg1, user_addr_t arg2, user_addr_t arg3, int __unused *retval); | |
215aeb03 A |
159 | int _bsdthread_ctl_qos_dispatch_asynchronous_override_add(struct proc __unused *p, user_addr_t __unused cmd, mach_port_name_t kport, pthread_priority_t priority, user_addr_t resource, int __unused *retval); |
160 | int _bsdthread_ctl_qos_dispatch_asynchronous_override_reset(struct proc __unused *p, user_addr_t __unused cmd, int reset_all, user_addr_t resource, user_addr_t arg3, int __unused *retval); | |
f1a1da6c A |
161 | int _bsdthread_ctl(struct proc *p, user_addr_t cmd, user_addr_t arg1, user_addr_t arg2, user_addr_t arg3, int *retval); |
162 | int _thread_selfid(__unused struct proc *p, uint64_t *retval); | |
163 | int _workq_kernreturn(struct proc *p, int options, user_addr_t item, int arg2, int arg3, int32_t *retval); | |
164 | int _workq_open(struct proc *p, int32_t *retval); | |
165 | ||
166 | int _psynch_mutexwait(proc_t p, user_addr_t mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags, uint32_t * retval); | |
167 | int _psynch_mutexdrop(proc_t p, user_addr_t mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags, uint32_t * retval); | |
168 | int _psynch_cvbroad(proc_t p, user_addr_t cv, uint64_t cvlsgen, uint64_t cvudgen, uint32_t flags, user_addr_t mutex, uint64_t mugen, uint64_t tid, uint32_t *retval); | |
169 | int _psynch_cvsignal(proc_t p, user_addr_t cv, uint64_t cvlsgen, uint32_t cvugen, int thread_port, user_addr_t mutex, uint64_t mugen, uint64_t tid, uint32_t flags, uint32_t * retval); | |
170 | int _psynch_cvwait(proc_t p, user_addr_t cv, uint64_t cvlsgen, uint32_t cvugen, user_addr_t mutex, uint64_t mugen, uint32_t flags, int64_t sec, uint32_t nsec, uint32_t * retval); | |
171 | int _psynch_cvclrprepost(proc_t p, user_addr_t cv, uint32_t cvgen, uint32_t cvugen, uint32_t cvsgen, uint32_t prepocnt, uint32_t preposeq, uint32_t flags, int *retval); | |
172 | int _psynch_rw_longrdlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t * retval); | |
173 | int _psynch_rw_rdlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t *retval); | |
174 | int _psynch_rw_unlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t *retval); | |
175 | int _psynch_rw_wrlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t *retval); | |
176 | int _psynch_rw_yieldwrlock(proc_t p, user_addr_t rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags, uint32_t *retval); | |
177 | ||
010efe49 A |
178 | void _pthread_find_owner(thread_t thread, struct stackshot_thread_waitinfo *waitinfo); |
179 | void * _pthread_get_thread_kwq(thread_t thread); | |
180 | ||
f1a1da6c A |
181 | extern lck_grp_attr_t *pthread_lck_grp_attr; |
182 | extern lck_grp_t *pthread_lck_grp; | |
183 | extern lck_attr_t *pthread_lck_attr; | |
184 | extern lck_mtx_t *pthread_list_mlock; | |
185 | extern thread_call_t psynch_thcall; | |
186 | ||
187 | struct uthread* current_uthread(void); | |
188 | ||
214d78a2 A |
189 | int |
190 | workq_create_threadstack(proc_t p, vm_map_t vmap, mach_vm_offset_t *out_addr); | |
964d3577 | 191 | |
214d78a2 A |
192 | int |
193 | workq_destroy_threadstack(proc_t p, vm_map_t vmap, mach_vm_offset_t stackaddr); | |
964d3577 | 194 | |
214d78a2 A |
195 | void |
196 | workq_setup_thread(proc_t p, thread_t th, vm_map_t map, user_addr_t stackaddr, | |
197 | mach_port_name_t kport, int th_qos, int setup_flags, int upcall_flags); | |
a0619f9c | 198 | |
214d78a2 A |
199 | int |
200 | workq_handle_stack_events(proc_t p, thread_t th, vm_map_t map, | |
201 | user_addr_t stackaddr, mach_port_name_t kport, | |
202 | user_addr_t events, int nevents, int upcall_flags); | |
a0619f9c | 203 | |
214d78a2 A |
204 | void |
205 | workq_markfree_threadstack(proc_t p, thread_t th, vm_map_t vmap, | |
206 | user_addr_t stackaddr); | |
a0619f9c | 207 | |
f1a1da6c A |
208 | #endif // KERNEL |
209 | ||
210 | #endif /* _SYS_PTHREAD_INTERNAL_H_ */ | |
211 |