-static int pthread_setschedparam_internal(pthread_t, mach_port_t, int, const struct sched_param *);
-extern pthread_t __bsdthread_create(void *(*func)(void *), void * func_arg, void * stack, pthread_t thread, unsigned int flags);
-extern int __bsdthread_register(void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), void (*)(pthread_t, mach_port_t, void *, void *, int), int,void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), int32_t *,__uint64_t);
-extern int __bsdthread_terminate(void * freeaddr, size_t freesize, mach_port_t kport, mach_port_t joinsem);
-extern __uint64_t __thread_selfid( void );
-extern int __pthread_canceled(int);
-extern int __pthread_kill(mach_port_t, int);
-
-extern int __workq_open(void);
-extern int __workq_kernreturn(int, void *, int, int);
-
-#if defined(__i386__) || defined(__x86_64__)
-static const mach_vm_address_t PTHREAD_STACK_HINT = 0xB0000000;
-#else
-#error no PTHREAD_STACK_HINT for this architecture
-#endif
-
-// Check that offsets of _PTHREAD_STRUCT_DIRECT_*_OFFSET values hasn't changed
-_Static_assert(offsetof(struct _pthread, tsd) + _PTHREAD_STRUCT_DIRECT_THREADID_OFFSET
- == offsetof(struct _pthread, thread_id),
- "_PTHREAD_STRUCT_DIRECT_THREADID_OFFSET is correct");
-
-// Allocate a thread structure, stack and guard page.
-//
-// The thread structure may optionally be placed in the same allocation as the
-// stack, residing above the top of the stack. This cannot be done if a
-// custom stack address is provided.
-//
-// Similarly the guard page cannot be allocated if a custom stack address is
-// provided.
-//
-// The allocated thread structure is initialized with values that indicate how
-// it should be freed.
-
-static int
-_pthread_allocate(pthread_t *thread, const pthread_attr_t *attrs, void **stack)
-{
- int res;
- kern_return_t kr;
- pthread_t t = NULL;
- mach_vm_address_t allocaddr = PTHREAD_STACK_HINT;
- size_t allocsize = 0;
- size_t guardsize = 0;
- size_t stacksize = 0;
-
- PTHREAD_ASSERT(attrs->stacksize >= PTHREAD_STACK_MIN);
-
- *thread = NULL;
- *stack = NULL;
-
- // Allocate a pthread structure if necessary
-
- if (attrs->stackaddr != NULL) {
- PTHREAD_ASSERT(((uintptr_t)attrs->stackaddr % vm_page_size) == 0);
- *stack = attrs->stackaddr;
- allocsize = PTHREAD_SIZE;
- } else {
- guardsize = attrs->guardsize;
- stacksize = attrs->stacksize;
- allocsize = stacksize + guardsize + PTHREAD_SIZE;
- }
-
- kr = mach_vm_map(mach_task_self(),
- &allocaddr,
- allocsize,
- vm_page_size - 1,
- VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE,
- MEMORY_OBJECT_NULL,
- 0,
- FALSE,
- VM_PROT_DEFAULT,
- VM_PROT_ALL,
- VM_INHERIT_DEFAULT);
-
- if (kr != KERN_SUCCESS) {
- kr = mach_vm_allocate(mach_task_self(),
- &allocaddr,
- allocsize,
- VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE);
- }
-
- if (kr == KERN_SUCCESS) {
- // The stack grows down.
- // Set the guard page at the lowest address of the
- // newly allocated stack. Return the highest address
- // of the stack.
- if (guardsize) {
- (void)mach_vm_protect(mach_task_self(), allocaddr, guardsize, FALSE, VM_PROT_NONE);
- }
-
- // Thread structure resides at the top of the stack.
- t = (void *)(allocaddr + stacksize + guardsize);
- if (stacksize) {
- // Returns the top of the stack.
- *stack = t;
- }
- }
-
- if (t != NULL) {
- _pthread_struct_init(t, attrs,
- *stack, attrs->stacksize,
- allocaddr, allocsize);
- *thread = t;
- res = 0;
- } else {
- res = EAGAIN;
- }
- return res;
-}
-
-static int
-_pthread_deallocate(pthread_t t)
-{
- // Don't free the main thread.
- if (t != &_thread) {
- kern_return_t ret;
- ret = mach_vm_deallocate(mach_task_self(), t->freeaddr, t->freesize);
- PTHREAD_ASSERT(ret == KERN_SUCCESS);
- }
- return 0;
-}
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wreturn-stack-address"
-
-PTHREAD_NOINLINE
-static void*
-_current_stack_address(void)
-{
- int a;
- return &a;
-}
-
-#pragma clang diagnostic pop
-
-// Terminates the thread if called from the currently running thread.
-PTHREAD_NORETURN PTHREAD_NOINLINE
-static void
-_pthread_terminate(pthread_t t)
-{
- PTHREAD_ASSERT(t == pthread_self());
-
- uintptr_t freeaddr = (uintptr_t)t->freeaddr;
- size_t freesize = t->freesize;
-
- // the size of just the stack
- size_t freesize_stack = t->freesize;