]>
Commit | Line | Data |
---|---|---|
964d3577 A |
1 | #include <assert.h> |
2 | #include <pthread.h> | |
3 | #include <stdint.h> | |
4 | #include <stdio.h> | |
5 | #include <unistd.h> | |
6 | #include <mach/mach.h> | |
7 | ||
2546420a A |
8 | #include <darwintest.h> |
9 | ||
964d3577 A |
10 | #define WAITTIME (100 * 1000) |
11 | ||
12 | static inline void* | |
13 | test(void) | |
14 | { | |
15 | static uintptr_t idx; | |
964d3577 A |
16 | return (void*)idx; |
17 | } | |
18 | ||
19 | static void * | |
20 | thread(void *param) | |
21 | { | |
22 | usleep(WAITTIME); | |
23 | return param; | |
24 | } | |
25 | ||
2546420a | 26 | /* |
964d3577 A |
27 | static void * |
28 | thread1(void *param) | |
29 | { | |
30 | int res; | |
31 | pthread_t p = param; | |
32 | ||
33 | usleep(WAITTIME); | |
34 | res = pthread_join(p, NULL); | |
35 | assert(res == 0); | |
964d3577 A |
36 | return 0; |
37 | } | |
2546420a | 38 | */ |
964d3577 | 39 | |
2546420a A |
40 | T_DECL(join, "pthread_join", |
41 | T_META_ALL_VALID_ARCHS(YES)) | |
964d3577 A |
42 | { |
43 | int res; | |
44 | kern_return_t kr; | |
45 | pthread_t p = NULL; | |
46 | void *param, *value; | |
47 | ||
48 | param = test(); | |
49 | res = pthread_create(&p, NULL, thread, param); | |
2546420a | 50 | T_ASSERT_POSIX_ZERO(res, "pthread_create"); |
964d3577 A |
51 | value = NULL; |
52 | res = pthread_join(p, &value); | |
2546420a A |
53 | T_ASSERT_POSIX_ZERO(res, "pthread_join"); |
54 | T_ASSERT_EQ_PTR(param, value, "early join value"); | |
964d3577 A |
55 | |
56 | param = test(); | |
57 | res = pthread_create(&p, NULL, thread, param); | |
2546420a | 58 | T_ASSERT_POSIX_ZERO(res, "pthread_create"); |
964d3577 A |
59 | usleep(3 * WAITTIME); |
60 | value = NULL; | |
61 | res = pthread_join(p, &value); | |
2546420a A |
62 | T_ASSERT_POSIX_ZERO(res, "pthread_join"); |
63 | T_ASSERT_EQ_PTR(param, value, "late join value"); | |
964d3577 A |
64 | |
65 | param = test(); | |
66 | res = pthread_create_suspended_np(&p, NULL, thread, param); | |
2546420a | 67 | T_ASSERT_POSIX_ZERO(res, "pthread_create_suspended_np"); |
964d3577 | 68 | kr = thread_resume(pthread_mach_thread_np(p)); |
2546420a | 69 | T_ASSERT_EQ_INT(kr, 0, "thread_resume"); |
964d3577 A |
70 | value = NULL; |
71 | res = pthread_join(p, &value); | |
2546420a A |
72 | T_ASSERT_POSIX_ZERO(res, "pthread_join"); |
73 | T_ASSERT_EQ_PTR(param, value, "suspended early join value"); | |
964d3577 A |
74 | |
75 | param = test(); | |
76 | res = pthread_create_suspended_np(&p, NULL, thread, param); | |
2546420a | 77 | T_ASSERT_POSIX_ZERO(res, "pthread_create_suspended_np"); |
964d3577 | 78 | kr = thread_resume(pthread_mach_thread_np(p)); |
2546420a | 79 | T_ASSERT_EQ_INT(kr, 0, "thread_resume"); |
964d3577 A |
80 | usleep(3 * WAITTIME); |
81 | value = NULL; | |
82 | res = pthread_join(p, &value); | |
2546420a A |
83 | T_ASSERT_POSIX_ZERO(res, "pthread_join"); |
84 | T_ASSERT_EQ_PTR(param, value, "suspended late join value"); | |
964d3577 | 85 | |
2546420a A |
86 | // This test is supposed to test joining on the main thread. It's not |
87 | // clear how to express this with libdarwintest for now. | |
88 | /* | |
964d3577 A |
89 | test(); |
90 | param = pthread_self(); | |
91 | res = pthread_create_suspended_np(&p, NULL, thread1, param); | |
2546420a | 92 | T_ASSERT_POSIX_ZERO(res, "pthread_create_suspended_np"); |
964d3577 | 93 | res = pthread_detach(p); |
2546420a | 94 | T_ASSERT_POSIX_ZERO(res, "pthread_detach"); |
964d3577 | 95 | kr = thread_resume(pthread_mach_thread_np(p)); |
2546420a | 96 | T_ASSERT_EQ_INT(kr, 0, "thread_resume"); |
964d3577 | 97 | pthread_exit(0); |
2546420a A |
98 | */ |
99 | } | |
100 | ||
101 | static void * | |
102 | thread_stub(__unused void *arg) | |
103 | { | |
104 | return NULL; | |
964d3577 A |
105 | } |
106 | ||
2546420a A |
107 | T_DECL(pthread_join_stress, "pthread_join in a loop") |
108 | { | |
109 | for (int i = 0; i < 1000; i++) { | |
110 | pthread_t th[16]; | |
111 | for (int j = 0; j < i%16; j++){ | |
112 | T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_create(&th[j], NULL, thread_stub, NULL), NULL); | |
113 | } | |
114 | for (int j = i%16; j >= 0; j--){ | |
115 | T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_join(th[j], NULL), NULL); | |
116 | } | |
117 | } | |
118 | T_PASS("Success!"); | |
119 | } |