]>
Commit | Line | Data |
---|---|---|
2546420a A |
1 | #include <stdatomic.h> |
2 | #include <pthread.h> | |
3 | #include <pthread/introspection_private.h> | |
4 | #include <dispatch/dispatch.h> | |
5 | ||
a0619f9c | 6 | #include "darwintest_defaults.h" |
2546420a A |
7 | |
8 | static pthread_introspection_hook_t prev_pthread_introspection_hook; | |
9 | ||
10 | #define THREAD_COUNT 3 | |
11 | ||
12 | static void my_pthread_introspection_hook(unsigned int event, pthread_t thread, | |
13 | void *addr, size_t size) | |
14 | { | |
15 | static atomic_int create_count; | |
16 | static atomic_int terminate_count; | |
17 | ||
18 | uint64_t tid; | |
19 | pthread_threadid_np(NULL, &tid); | |
20 | ||
21 | if (event == PTHREAD_INTROSPECTION_THREAD_CREATE) { | |
22 | T_LOG("event = PTHREAD_INTROSPECTION_THREAD_CREATE, thread = %p:%lld, addr = %p, size = 0x%zx", thread, tid, addr, size); | |
23 | create_count++; | |
24 | } else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) { | |
25 | T_LOG("event = PTHREAD_INTROSPECTION_THREAD_TERMINATE, thread = %p:%lld, addr = %p, size = 0x%zx", thread, tid, addr, size); | |
26 | terminate_count++; | |
27 | T_ASSERT_GE(create_count, THREAD_COUNT, NULL); | |
28 | T_PASS("Got termination events"); | |
29 | T_END; | |
30 | } | |
31 | ||
32 | if (prev_pthread_introspection_hook != NULL){ | |
33 | prev_pthread_introspection_hook(event, thread, addr, size); | |
34 | } | |
35 | } | |
36 | ||
a0619f9c A |
37 | T_DECL(pthread_introspection, "PR-25679871", |
38 | T_META_TIMEOUT(30), T_META_ALL_VALID_ARCHS(YES)) | |
2546420a A |
39 | { |
40 | prev_pthread_introspection_hook = pthread_introspection_hook_install(&my_pthread_introspection_hook); | |
41 | ||
a0619f9c A |
42 | // minus one that comes after this block |
43 | for (int i = 0; i < THREAD_COUNT - 1; i++) { | |
44 | T_LOG("Creating dispatch_async thread %d.", i); | |
2546420a | 45 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
a0619f9c | 46 | T_LOG("Started dispatch_async thread %d.", i); |
2546420a A |
47 | sleep(3); |
48 | }); | |
49 | } | |
50 | dispatch_queue_t serial_queue = dispatch_queue_create("test queue", NULL); | |
51 | __block dispatch_block_t looping_block = ^{ | |
52 | static int count; | |
a0619f9c | 53 | if (count++ < 20) { |
2546420a | 54 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 50 * NSEC_PER_MSEC), serial_queue, looping_block); |
a0619f9c A |
55 | } else { |
56 | T_LOG("Looping block complete"); | |
2546420a A |
57 | } |
58 | }; | |
a0619f9c | 59 | T_LOG("Starting looping block"); |
2546420a A |
60 | dispatch_async(serial_queue, looping_block); |
61 | ||
62 | sleep(30); | |
63 | ||
64 | T_FAIL("Why are we still alive?"); | |
65 | } |