]>
Commit | Line | Data |
---|---|---|
964d3577 A |
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 | } | |
2546420a | 29 | fprintf(stderr, "\tsuccessfully signaled by %d threads.\n\n", threads); |
964d3577 A |
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 | ||
2546420a | 38 | void (^cb)(pthread_priority_t p) = NULL; |
964d3577 A |
39 | static void workqueue_func_kevent(void **buf, int *count){ |
40 | pthread_priority_t p = (pthread_priority_t)pthread_getspecific(4); | |
2546420a | 41 | fprintf(stderr, "\tthread with qos %s spawned. (buf: %p, count: %d)\n", describe_pri(p), buf ? *buf : NULL, count ? *count : 0); |
964d3577 A |
42 | |
43 | if (cb){ | |
2546420a | 44 | cb(p); |
964d3577 A |
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 | ||
2546420a A |
91 | // whole bunch of constrained threads (must be last) |
92 | ||
93 | dispatch_semaphore_t mgr_sema = dispatch_semaphore_create(0); | |
94 | assert(mgr_sema != NULL); | |
964d3577 A |
95 | |
96 | requests[0].priority = _pthread_qos_class_encode(QOS_CLASS_USER_INTERACTIVE, 0, 0); | |
97 | requests[0].count = 1; | |
98 | ||
2546420a A |
99 | cb = ^(pthread_priority_t p){ |
100 | if (p & _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG){ | |
101 | dispatch_semaphore_signal(mgr_sema); | |
102 | } | |
103 | ||
964d3577 A |
104 | // burn some CPU |
105 | for (int i = 0; i < 1000000; i++){ | |
106 | char c[32]; | |
107 | sprintf(c, "%d", i); | |
108 | } | |
109 | }; | |
110 | for (int i = 0; i < 8; i++) | |
111 | if ((ret = do_req()) < 0) return ret; | |
2546420a A |
112 | ret = dispatch_semaphore_wait(mgr_sema, timeout); |
113 | if (ret) { | |
114 | fprintf(stderr, "timeout waiting for a manager thread"); | |
115 | return 1; | |
116 | } | |
117 | fprintf(stderr, "\tsucessfully signaled by a manager thread.\n"); | |
964d3577 A |
118 | |
119 | return 0; | |
120 | } |