3 #include <kern/restartable.h>
5 #include <darwintest.h>
10 T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
12 extern task_restartable_range_t range
;
13 extern void restartable_function(int *);
16 #if defined(__x86_64__)
19 " .private_extern _restartable_function\n"
20 "_restartable_function:\n"
21 // this should use $arg1 but I don't know intel calling conventions
22 // so the argument to restartable_function() is actually ignored
23 // as we know what it is anyway, and Intel PC-relative addressing,
24 // unlike ARM, is pretty readable
29 "LExit_restartable_function:\n"
31 #elif defined(__arm64__)
34 " .private_extern _restartable_function\n"
35 "_restartable_function:\n"
41 "LExit_restartable_function:\n"
43 #elif defined(__arm__)
47 " .private_extern _restartable_function\n"
49 "_restartable_function:\n"
56 "LExit_restartable_function:\n"
58 #elif defined(__i386__)
61 #error Architecture unsupported
67 " .private_extern _range\n"
70 " .quad _restartable_function\n"
72 " .long _restartable_function\n"
75 " .short LExit_restartable_function - _restartable_function\n"
76 " .short LExit_restartable_function - _restartable_function\n"
81 noop_signal(int signo __unused
)
86 task_restartable_ranges_thread(void *_ctx
)
89 restartable_function(stepp
); // increments step
90 T_PASS("was successfully restarted\n");
96 wait_for_step(int which
)
98 for (int i
= 0; step
!= which
&& i
< 10; i
++) {
103 T_DECL(task_restartable_ranges
, "test task_restartable_ranges")
106 T_SKIP("Not supported");
112 signal(SIGUSR1
, noop_signal
);
114 kr
= task_restartable_ranges_register(mach_task_self(), &range
, 1);
115 T_ASSERT_MACH_SUCCESS(kr
, "task_restartable_ranges_register");
118 rc
= pthread_create(&th
, NULL
, &task_restartable_ranges_thread
, &step
);
119 T_ASSERT_POSIX_SUCCESS(rc
, "pthread_create");
122 T_ASSERT_EQ(step
, 1, "The thread started (sync)");
124 kr
= task_restartable_ranges_synchronize(mach_task_self());
125 T_ASSERT_MACH_SUCCESS(kr
, "task_restartable_ranges_synchronize");
127 T_LOG("wait for the function to be restarted (sync)");
129 T_ASSERT_EQ(step
, 2, "The thread exited (sync)");
130 pthread_join(th
, NULL
);
134 rc
= pthread_create(&th
, NULL
, &task_restartable_ranges_thread
, &step
);
135 T_ASSERT_POSIX_SUCCESS(rc
, "pthread_create");
138 T_ASSERT_EQ(step
, 3, "The thread started (signal)");
140 rc
= pthread_kill(th
, SIGUSR1
);
141 T_ASSERT_POSIX_SUCCESS(rc
, "pthread_kill");
143 T_LOG("wait for the function to be restarted (signal)");
145 T_ASSERT_EQ(step
, 4, "The thread exited (signal)");
146 pthread_join(th
, NULL
);