]> git.saurik.com Git - apple/libpthread.git/blob - tests/wq_kevent.c
808cc2552a20c9dd3c507ca9f6456ccc18d8974d
[apple/libpthread.git] / tests / wq_kevent.c
1 #include <assert.h>
2 #include <errno.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/sysctl.h>
9 #include <sys/qos.h>
10
11 #include <dispatch/dispatch.h>
12
13 #include "../private/workqueue_private.h"
14 #include "../private/qos_private.h"
15
16 #include "wq_kevent.h"
17
18 static dispatch_semaphore_t sema;
19 static dispatch_time_t timeout;
20
21 static int do_wait(int threads){
22 for (int i = 0; i < threads; i++){
23 int ret = dispatch_semaphore_wait(sema, timeout);
24 if (ret){
25 fprintf(stderr, "timout waiting for thread %d.\n", i);
26 return 1;
27 }
28 }
29 fprintf(stderr, "\tsuccessfully signaled by %d threads.\n", threads);
30 return 0;
31 }
32
33 static void workqueue_func(pthread_priority_t priority){
34 fprintf(stderr, "WARNING: workqueue_func called.\n");
35 dispatch_semaphore_signal(sema);
36 }
37
38 void (^cb)(void) = NULL;
39 static void workqueue_func_kevent(void **buf, int *count){
40 pthread_priority_t p = (pthread_priority_t)pthread_getspecific(4);
41 fprintf(stderr, "\tthread with qos %s spawned.\n", describe_pri(p));
42
43 if (cb){
44 cb();
45 }
46
47 dispatch_semaphore_signal(sema);
48 }
49
50 int main(int argc, char *argv[]){
51 int ret = 0;
52 int exit_status = 0;
53
54 ret = _pthread_workqueue_init_with_kevent(workqueue_func, workqueue_func_kevent, 0, 0);
55 assert(ret == 0);
56
57 sema = dispatch_semaphore_create(0);
58 assert(sema != NULL);
59 timeout = dispatch_time(DISPATCH_TIME_NOW, 5LL * NSEC_PER_SEC);
60
61 _pthread_workqueue_set_event_manager_priority(_pthread_qos_class_encode(QOS_CLASS_UTILITY,0,0));
62
63 // one constrained thread
64 requests[0].priority = _pthread_qos_class_encode(QOS_CLASS_USER_INTERACTIVE, 0, 0);
65 requests[0].count = 1;
66
67 if ((ret = do_req()) < 0) return ret;
68 if ((ret = do_wait(1)) < 0) return ret;
69
70 // one overcommit thread
71 requests[0].priority = _pthread_qos_class_encode(QOS_CLASS_USER_INTERACTIVE, 0, _PTHREAD_PRIORITY_OVERCOMMIT_FLAG);
72 requests[0].count = 1;
73
74 if ((ret = do_req()) < 0) return ret;
75 if ((ret = do_wait(1)) < 0) return ret;
76
77 // one event manager
78 requests[0].priority = _pthread_qos_class_encode(QOS_CLASS_USER_INTERACTIVE, 0, _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG);
79 requests[0].count = 1;
80
81 if ((ret = do_req()) < 0) return ret;
82 if ((ret = do_wait(1)) < 0) return ret;
83
84 // one constrained thread
85 requests[0].priority = _pthread_qos_class_encode(QOS_CLASS_USER_INTERACTIVE, 0, 0);
86 requests[0].count = 1;
87
88 if ((ret = do_req()) < 0) return ret;
89 if ((ret = do_wait(1)) < 0) return ret;
90
91 // whole bunch of constrained threads
92
93 requests[0].priority = _pthread_qos_class_encode(QOS_CLASS_USER_INTERACTIVE, 0, 0);
94 requests[0].count = 1;
95
96 cb = ^{
97 // burn some CPU
98 for (int i = 0; i < 1000000; i++){
99 char c[32];
100 sprintf(c, "%d", i);
101 }
102 };
103 for (int i = 0; i < 8; i++)
104 if ((ret = do_req()) < 0) return ret;
105 if ((ret = do_wait(8)) < 0) return ret;
106
107 return 0;
108 }