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