Commit | Line | Data |
---|---|---|
6eee141f ILT |
1 | // tls_test.cc -- test TLS variables for gold, main function |
2 | ||
b3adc24a | 3 | // Copyright (C) 2006-2020 Free Software Foundation, Inc. |
6eee141f ILT |
4 | // Written by Ian Lance Taylor <iant@google.com>. |
5 | ||
6 | // This file is part of gold. | |
7 | ||
8 | // This program is free software; you can redistribute it and/or modify | |
9 | // it under the terms of the GNU General Public License as published by | |
10 | // the Free Software Foundation; either version 3 of the License, or | |
11 | // (at your option) any later version. | |
12 | ||
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | ||
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | |
21 | // MA 02110-1301, USA. | |
22 | ||
23 | // This is the main function for the TLS test. See tls_test.cc for | |
24 | // more information. | |
25 | ||
26 | #include <cassert> | |
e9821041 | 27 | #include <cstdio> |
6eee141f | 28 | #include <pthread.h> |
732e31de | 29 | #include <semaphore.h> |
6eee141f ILT |
30 | |
31 | #include "tls_test.h" | |
32 | ||
8261e3bf | 33 | // We make these macros so the assert() will give useful line-numbers. |
732e31de | 34 | #define safe_lock(semptr) \ |
8261e3bf ILT |
35 | do \ |
36 | { \ | |
732e31de | 37 | int err = sem_wait(semptr); \ |
2ea97941 | 38 | assert(err == 0); \ |
8261e3bf ILT |
39 | } \ |
40 | while (0) | |
41 | ||
732e31de | 42 | #define safe_unlock(semptr) \ |
8261e3bf ILT |
43 | do \ |
44 | { \ | |
732e31de | 45 | int err = sem_post(semptr); \ |
2ea97941 | 46 | assert(err == 0); \ |
8261e3bf ILT |
47 | } \ |
48 | while (0) | |
49 | ||
732e31de | 50 | struct Sem_set |
6eee141f | 51 | { |
732e31de ILT |
52 | sem_t sem1; |
53 | sem_t sem2; | |
54 | sem_t sem3; | |
6eee141f ILT |
55 | }; |
56 | ||
732e31de ILT |
57 | Sem_set sems1; |
58 | Sem_set sems2; | |
6eee141f | 59 | |
e9821041 ILT |
60 | bool failed = false; |
61 | ||
62 | void | |
63 | check(const char* name, bool val) | |
64 | { | |
65 | if (!val) | |
66 | { | |
67 | fprintf(stderr, "Test %s failed\n", name); | |
68 | failed = true; | |
69 | } | |
70 | } | |
71 | ||
732e31de ILT |
72 | // The body of the thread function. This acquires the first |
73 | // semaphore, runs the tests, and then releases the second semaphore. | |
74 | // Then it acquires the third semaphore, and the runs the verification | |
75 | // test again. | |
6eee141f ILT |
76 | |
77 | void* | |
78 | thread_routine(void* arg) | |
79 | { | |
732e31de | 80 | Sem_set* pms = static_cast<Sem_set*>(arg); |
6eee141f | 81 | |
732e31de | 82 | // Acquire the first semaphore. |
8261e3bf | 83 | if (pms) |
732e31de | 84 | safe_lock(&pms->sem1); |
6eee141f ILT |
85 | |
86 | // Run the tests. | |
e9821041 ILT |
87 | check("t1", t1()); |
88 | check("t2", t2()); | |
89 | check("t3", t3()); | |
90 | check("t4", t4()); | |
6eee141f | 91 | f5b(f5a()); |
e9821041 | 92 | check("t5", t5()); |
6eee141f | 93 | f6b(f6a()); |
e9821041 | 94 | check("t6", t6()); |
e0374858 ILT |
95 | check("t8", t8()); |
96 | check("t9", t9()); | |
97 | f10b(f10a()); | |
98 | check("t10", t10()); | |
155a0dd7 | 99 | check("t11", t11() != 0); |
d85c80a3 | 100 | check("t12", t12()); |
e0374858 | 101 | check("t_last", t_last()); |
6eee141f | 102 | |
732e31de | 103 | // Release the second semaphore. |
8261e3bf | 104 | if (pms) |
732e31de | 105 | safe_unlock(&pms->sem2); |
6eee141f | 106 | |
732e31de | 107 | // Acquire the third semaphore. |
8261e3bf | 108 | if (pms) |
732e31de | 109 | safe_lock(&pms->sem3); |
6eee141f | 110 | |
e0374858 | 111 | check("t_last", t_last()); |
6eee141f ILT |
112 | |
113 | return 0; | |
114 | } | |
115 | ||
116 | // The main function. | |
117 | ||
118 | int | |
119 | main() | |
120 | { | |
8261e3bf ILT |
121 | // First, as a sanity check, run through the tests in the "main" thread. |
122 | thread_routine(0); | |
123 | ||
732e31de | 124 | // Set up the semaphores. We want the first thread to start right |
6eee141f ILT |
125 | // away, tell us when it is done with the first part, and wait for |
126 | // us to release it. We want the second thread to wait to start, | |
127 | // tell us when it is done with the first part, and wait for us to | |
128 | // release it. | |
732e31de ILT |
129 | sem_init(&sems1.sem1, 0, 1); |
130 | sem_init(&sems1.sem2, 0, 0); | |
131 | sem_init(&sems1.sem3, 0, 0); | |
6eee141f | 132 | |
732e31de ILT |
133 | sem_init(&sems2.sem1, 0, 0); |
134 | sem_init(&sems2.sem2, 0, 0); | |
135 | sem_init(&sems2.sem3, 0, 0); | |
6eee141f ILT |
136 | |
137 | pthread_t thread1; | |
732e31de | 138 | int err = pthread_create(&thread1, NULL, thread_routine, &sems1); |
6eee141f ILT |
139 | assert(err == 0); |
140 | ||
141 | pthread_t thread2; | |
732e31de | 142 | err = pthread_create(&thread2, NULL, thread_routine, &sems2); |
6eee141f ILT |
143 | assert(err == 0); |
144 | ||
145 | // Wait for the first thread to complete the first part. | |
732e31de | 146 | safe_lock(&sems1.sem2); |
6eee141f ILT |
147 | |
148 | // Tell the second thread to start. | |
732e31de | 149 | safe_unlock(&sems2.sem1); |
6eee141f ILT |
150 | |
151 | // Wait for the second thread to complete the first part. | |
732e31de | 152 | safe_lock(&sems2.sem2); |
6eee141f ILT |
153 | |
154 | // Tell the first thread to continue and finish. | |
732e31de | 155 | safe_unlock(&sems1.sem3); |
6eee141f ILT |
156 | |
157 | // Wait for the first thread to finish. | |
158 | void* thread_val; | |
159 | err = pthread_join(thread1, &thread_val); | |
160 | assert(err == 0); | |
161 | assert(thread_val == 0); | |
162 | ||
163 | // Tell the second thread to continue and finish. | |
732e31de | 164 | safe_unlock(&sems2.sem3); |
6eee141f ILT |
165 | |
166 | // Wait for the second thread to finish. | |
167 | err = pthread_join(thread2, &thread_val); | |
168 | assert(err == 0); | |
169 | assert(thread_val == 0); | |
170 | ||
171 | // All done. | |
e9821041 | 172 | return failed ? 1 : 0; |
6eee141f | 173 | } |