]> git.saurik.com Git - apple/libpthread.git/blame - tests/pthread_create_from_mach_thread.c
libpthread-454.100.8.tar.gz
[apple/libpthread.git] / tests / pthread_create_from_mach_thread.c
CommitLineData
c6e5f90c
A
1
2#include <pthread.h>
3#include <mach/mach.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <signal.h>
7#include <pthread_spis.h>
8
9#include "darwintest_defaults.h"
10
11#define CHILD_STACK_COUNT 1024
12static uint64_t child_stack[CHILD_STACK_COUNT];
13
14static void*
15pthread_runner(void* __unused arg)
16{
17 T_PASS("mach -> pthread conversion successful");
18 T_END;
19}
20
21static void *
22mach_bootstrap(void * __unused arg)
23{
24 pthread_t thread;
25 pthread_create_from_mach_thread(&thread, NULL, pthread_runner, NULL);
26 while (1) {
27 swtch_pri(0); // mach_yield
28 }
29}
30
31T_DECL(pthread_create_from_mach_thread, "pthread_create_from_mach_thread",
32 T_META_ALL_VALID_ARCHS(YES),
33 // Having leaks running will suppress the behavior we are testing
34 T_META_CHECK_LEAKS(false),
35 T_META_ENVVAR("MallocStackLogging=1")
36 )
37{
38 T_PASS("MallocStackLogging: %s", getenv("MallocStackLogging"));
39
40 // Create a mach_thread to start with
41 mach_port_t task = mach_task_self();
42
43 thread_state_flavor_t flavor;
44 mach_msg_type_number_t count;
45
46 uintptr_t start_addr = (uintptr_t)&mach_bootstrap;
47 // Force alignment to 16-bytes
48 uintptr_t stack_top = ((uintptr_t)&child_stack[CHILD_STACK_COUNT]) & ~0xf;
49
50#if defined(__x86_64__)
51 T_PASS("x86_64");
52 flavor = x86_THREAD_STATE64;
53 count = x86_THREAD_STATE64_COUNT;
54 x86_thread_state64_t state = {
55 .__rip = start_addr,
56 // Must be 16-byte-off-by-8 aligned <rdar://problem/15886599>
57 .__rsp = stack_top - 8,
58 };
59#elif defined(__arm64__)
60 T_PASS("arm64");
61 flavor = ARM_THREAD_STATE64;
62 count = ARM_THREAD_STATE64_COUNT;
63 arm_thread_state64_t state = { };
64 arm_thread_state64_set_pc_fptr(state, &mach_bootstrap);
65 arm_thread_state64_set_sp(state, stack_top);
66 (void)start_addr;
67#elif defined(__arm__)
68 T_PASS("arm (32)");
69 flavor = ARM_THREAD_STATE;
70 count = ARM_THREAD_STATE_COUNT;
71 arm_thread_state_t state = {
72 .__pc = start_addr,
73 .__sp = stack_top,
74 .__cpsr = 0x20,
75 };
76#else
77#error Unknown architecture
78#endif
79
80 thread_state_t state_ptr = (thread_state_t)&state;
81 thread_t task_thread;
82 T_PASS("Launching Thread");
83
84 kern_return_t ret = thread_create_running(task, flavor, state_ptr, count, &task_thread);
85 T_ASSERT_MACH_SUCCESS(ret, "mach thread created");
86 // Wait forever
87 sigset_t empty;
88 T_QUIET; T_ASSERT_POSIX_ZERO(sigemptyset(&empty), NULL);
89 while (sigsuspend(&empty)) {
90 continue;
91 }
92 T_FAIL("Didn't wait forever?");
93}