]> git.saurik.com Git - apple/libpthread.git/blame - tests/wq_kevent.c
libpthread-218.30.1.tar.gz
[apple/libpthread.git] / tests / wq_kevent.c
CommitLineData
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
18static dispatch_semaphore_t sema;
19static dispatch_time_t timeout;
20
21static 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
33static void workqueue_func(pthread_priority_t priority){
34 fprintf(stderr, "WARNING: workqueue_func called.\n");
35 dispatch_semaphore_signal(sema);
36}
37
2546420a 38void (^cb)(pthread_priority_t p) = NULL;
964d3577
A
39static 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
50int 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}