]>
Commit | Line | Data |
---|---|---|
2546420a A |
1 | #include <stdio.h> |
2 | #include <pthread.h> | |
c1f56ec9 | 3 | #include <pthread/private.h> |
2546420a A |
4 | #include <errno.h> |
5 | #include <stdlib.h> | |
6 | #include <unistd.h> | |
7 | ||
a0619f9c | 8 | #include "darwintest_defaults.h" |
2546420a A |
9 | |
10 | #define STACK_SIZE 32768 | |
11 | #define THREAD_DEPTH 2000 | |
12 | ||
13 | static unsigned int glob = 0; | |
14 | static unsigned int i; | |
15 | ||
16 | static pthread_mutex_t count_lock = PTHREAD_MUTEX_INITIALIZER; | |
17 | ||
18 | static void * | |
19 | thread_exit(__unused void *arg) | |
20 | { | |
21 | unsigned int count; | |
22 | ||
23 | sleep(5); | |
24 | pthread_mutex_lock(&count_lock); | |
25 | count = ++glob; | |
26 | pthread_mutex_unlock(&count_lock); | |
27 | ||
28 | T_QUIET; T_EXPECT_NE(pthread_mach_thread_np(pthread_self()), (mach_port_t)0, NULL); | |
29 | ||
30 | if (count == THREAD_DEPTH){ | |
31 | T_PASS("all the threads survived main thread exit"); | |
32 | T_END; | |
33 | } | |
34 | return NULL; | |
35 | } | |
36 | ||
a0619f9c | 37 | T_DECL(pthread_exit, "pthread_exit", T_META_LTEPHASE(LTE_INSTALLEDUSEROS)) |
2546420a A |
38 | { |
39 | int j; | |
40 | pthread_t th[THREAD_DEPTH]; | |
41 | ||
42 | T_LOG("Creating threads %d..%d", i, i+THREAD_DEPTH-1); | |
43 | for (j = 0; j < THREAD_DEPTH; j++) { | |
44 | pthread_attr_t attr; | |
45 | ||
46 | pthread_attr_init(&attr); | |
47 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
48 | T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_create(&th[j], &attr, thread_exit, (void *)&glob), NULL); | |
49 | pthread_attr_destroy(&attr); | |
50 | } | |
51 | pthread_exit(pthread_self()); | |
52 | T_FAIL("Zombie walks"); | |
53 | } | |
54 | ||
55 | static void * | |
56 | thread_stub(__unused void *arg) | |
57 | { | |
58 | return NULL; | |
59 | } | |
60 | ||
a0619f9c A |
61 | T_DECL(pthread_exit_private_stacks, "pthread_exit with private stacks", |
62 | T_META_CHECK_LEAKS(NO)) | |
2546420a A |
63 | { |
64 | int j; | |
65 | pthread_t th[THREAD_DEPTH]; | |
66 | void *stacks[THREAD_DEPTH]; | |
67 | ||
68 | for (j = 0; j < THREAD_DEPTH; j++) { | |
69 | T_QUIET; T_ASSERT_NOTNULL((stacks[j] = malloc(STACK_SIZE)), NULL); | |
70 | } | |
71 | ||
72 | for (i=0;i < 20; i++) { | |
73 | for (j = 0; j < THREAD_DEPTH; j++) { | |
74 | pthread_attr_t attr; | |
75 | pthread_attr_init(&attr); | |
76 | pthread_attr_setstack(&attr, stacks[j], STACK_SIZE); | |
77 | T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_create(&th[j], &attr, thread_stub, (void *)&glob), NULL); | |
78 | pthread_attr_destroy(&attr); | |
79 | } | |
80 | for (j = 0; j < THREAD_DEPTH; j++) { | |
81 | T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_join(th[j], NULL), NULL); | |
82 | } | |
83 | T_PASS("Created threads %d..%d", i*THREAD_DEPTH, (i+1)*THREAD_DEPTH-1); | |
84 | } | |
85 | ||
86 | } | |
87 | ||
88 | T_DECL(pthread_exit_detached, "pthread_exit with detached threads") | |
89 | { | |
90 | int j; | |
91 | pthread_t th[THREAD_DEPTH]; | |
92 | ||
93 | for (i=0;i < 20; i++) { | |
94 | for (j = 0; j < THREAD_DEPTH; j++) { | |
95 | pthread_attr_t attr; | |
96 | pthread_attr_init(&attr); | |
97 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
98 | T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_create(&th[j], &attr, thread_stub, (void *)&glob), NULL); | |
99 | pthread_attr_destroy(&attr); | |
100 | } | |
101 | sleep(1); | |
102 | T_PASS("Created threads %d..%d", i*THREAD_DEPTH, (i+1)*THREAD_DEPTH-1); | |
103 | } | |
104 | T_PASS("Success!"); | |
105 | } | |
c1f56ec9 A |
106 | |
107 | static void | |
108 | key_dtor(void *value) | |
109 | { | |
110 | T_ASSERT_EQ(1, pthread_self_is_exiting_np(), "exiting"); | |
111 | } | |
112 | ||
113 | T_DECL(pthread_self_is_exiting_np, "pthread_self_is_exiting_np") | |
114 | { | |
115 | pthread_key_t key; | |
116 | ||
117 | T_ASSERT_POSIX_ZERO(pthread_key_create(&key, key_dtor), NULL); | |
118 | pthread_setspecific(key, (void *)-1); | |
119 | T_ASSERT_EQ(0, pthread_self_is_exiting_np(), "not exiting"); | |
120 | pthread_exit(NULL); | |
121 | } |