xref: /xnu-8796.101.5/tests/workq/workq_sigprof.c (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5)
1 #include <pthread.h>
2 #include <stdbool.h>
3 #include <signal.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <sys/time.h>
8 #include <mach/mach_time.h>
9 #include <dispatch/dispatch.h>
10 
11 #include <darwintest.h>
12 
13 T_GLOBAL_META(
14 	T_META_NAMESPACE("xnu.workq"),
15 	T_META_RADAR_COMPONENT_NAME("xnu"),
16 	T_META_RADAR_COMPONENT_VERSION("workq"),
17 	T_META_RUN_CONCURRENTLY(true));
18 
19 
20 static pthread_t workq_thread;
21 static bool signal_received;
22 
23 static void
signal_handler(int sig __unused,siginfo_t * b __unused,void * unused __unused)24 signal_handler(int sig __unused, siginfo_t *b __unused, void* unused __unused)
25 {
26 	if (pthread_self() == workq_thread) {
27 		signal_received = true;
28 	}
29 }
30 
31 static void
workq_block(void * unused __unused)32 workq_block(void *unused __unused)
33 {
34 	workq_thread = pthread_self();
35 
36 	/*
37 	 *  sigset_t set;
38 	 *  sigemptyset(&set);
39 	 *  sigaddset(&set, SIGPROF);
40 	 *  pthread_sigmask(SIG_UNBLOCK, &set, NULL);
41 	 */
42 
43 	uint64_t spin_start = mach_absolute_time();
44 	while (mach_absolute_time() - spin_start < 30 * NSEC_PER_SEC) {
45 		if (signal_received) {
46 			T_PASS("Got SIGPROF!");
47 			T_END;
48 		}
49 	}
50 }
51 
52 T_DECL(workq_sigprof, "test that workqueue threads can receive sigprof")
53 {
54 	struct sigaction sa = {
55 		.sa_sigaction = signal_handler
56 	};
57 	sigfillset(&sa.sa_mask);
58 	T_ASSERT_POSIX_ZERO(sigaction(SIGPROF, &sa, NULL), NULL);
59 
60 	dispatch_queue_t q = dispatch_get_global_queue(0, 0);
61 	dispatch_async_f(q, NULL, workq_block);
62 
63 	struct itimerval timerval = {
64 		.it_interval = {.tv_usec = 10000},
65 		.it_value = {.tv_usec = 10000}
66 	};
67 	T_ASSERT_POSIX_ZERO(setitimer(ITIMER_PROF, &timerval, NULL), NULL);
68 
69 	dispatch_main();
70 }
71