Commit | Line | Data |
---|---|---|
6eee141f ILT |
1 | // tls_test.cc -- test TLS variables for gold, main function |
2 | ||
ebdbb458 | 3 | // Copyright 2006, 2007, 2008 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 ILT |
28 | #include <pthread.h> |
29 | ||
30 | #include "tls_test.h" | |
31 | ||
8261e3bf ILT |
32 | // We make these macros so the assert() will give useful line-numbers. |
33 | #define safe_lock(muptr) \ | |
34 | do \ | |
35 | { \ | |
2ea97941 ILT |
36 | int err = pthread_mutex_lock(muptr); \ |
37 | assert(err == 0); \ | |
8261e3bf ILT |
38 | } \ |
39 | while (0) | |
40 | ||
41 | #define safe_unlock(muptr) \ | |
42 | do \ | |
43 | { \ | |
2ea97941 ILT |
44 | int err = pthread_mutex_unlock(muptr); \ |
45 | assert(err == 0); \ | |
8261e3bf ILT |
46 | } \ |
47 | while (0) | |
48 | ||
6eee141f ILT |
49 | struct Mutex_set |
50 | { | |
51 | pthread_mutex_t mutex1; | |
52 | pthread_mutex_t mutex2; | |
53 | pthread_mutex_t mutex3; | |
54 | }; | |
55 | ||
56 | Mutex_set mutexes1 = { PTHREAD_MUTEX_INITIALIZER, | |
57 | PTHREAD_MUTEX_INITIALIZER, | |
58 | PTHREAD_MUTEX_INITIALIZER }; | |
59 | ||
60 | Mutex_set mutexes2 = { PTHREAD_MUTEX_INITIALIZER, | |
61 | PTHREAD_MUTEX_INITIALIZER, | |
62 | PTHREAD_MUTEX_INITIALIZER } ; | |
63 | ||
e9821041 ILT |
64 | bool failed = false; |
65 | ||
66 | void | |
67 | check(const char* name, bool val) | |
68 | { | |
69 | if (!val) | |
70 | { | |
71 | fprintf(stderr, "Test %s failed\n", name); | |
72 | failed = true; | |
73 | } | |
74 | } | |
75 | ||
6eee141f ILT |
76 | // The body of the thread function. This gets a lock on the first |
77 | // mutex, runs the tests, and then unlocks the second mutex. Then it | |
78 | // locks the third mutex, and the runs the verification test again. | |
79 | ||
80 | void* | |
81 | thread_routine(void* arg) | |
82 | { | |
83 | Mutex_set* pms = static_cast<Mutex_set*>(arg); | |
84 | ||
85 | // Lock the first mutex. | |
8261e3bf ILT |
86 | if (pms) |
87 | safe_lock(&pms->mutex1); | |
6eee141f ILT |
88 | |
89 | // Run the tests. | |
e9821041 ILT |
90 | check("t1", t1()); |
91 | check("t2", t2()); | |
92 | check("t3", t3()); | |
93 | check("t4", t4()); | |
6eee141f | 94 | f5b(f5a()); |
e9821041 | 95 | check("t5", t5()); |
6eee141f | 96 | f6b(f6a()); |
e9821041 | 97 | check("t6", t6()); |
e0374858 ILT |
98 | check("t8", t8()); |
99 | check("t9", t9()); | |
100 | f10b(f10a()); | |
101 | check("t10", t10()); | |
155a0dd7 | 102 | check("t11", t11() != 0); |
d85c80a3 | 103 | check("t12", t12()); |
e0374858 | 104 | check("t_last", t_last()); |
6eee141f ILT |
105 | |
106 | // Unlock the second mutex. | |
8261e3bf ILT |
107 | if (pms) |
108 | safe_unlock(&pms->mutex2); | |
6eee141f ILT |
109 | |
110 | // Lock the third mutex. | |
8261e3bf ILT |
111 | if (pms) |
112 | safe_lock(&pms->mutex3); | |
6eee141f | 113 | |
e0374858 | 114 | check("t_last", t_last()); |
6eee141f ILT |
115 | |
116 | return 0; | |
117 | } | |
118 | ||
119 | // The main function. | |
120 | ||
121 | int | |
122 | main() | |
123 | { | |
8261e3bf ILT |
124 | // First, as a sanity check, run through the tests in the "main" thread. |
125 | thread_routine(0); | |
126 | ||
6eee141f ILT |
127 | // Set up the mutex locks. We want the first thread to start right |
128 | // away, tell us when it is done with the first part, and wait for | |
129 | // us to release it. We want the second thread to wait to start, | |
130 | // tell us when it is done with the first part, and wait for us to | |
131 | // release it. | |
8261e3bf ILT |
132 | safe_lock(&mutexes1.mutex2); |
133 | safe_lock(&mutexes1.mutex3); | |
6eee141f | 134 | |
8261e3bf ILT |
135 | safe_lock(&mutexes2.mutex1); |
136 | safe_lock(&mutexes2.mutex2); | |
137 | safe_lock(&mutexes2.mutex3); | |
6eee141f ILT |
138 | |
139 | pthread_t thread1; | |
8261e3bf | 140 | int err = pthread_create(&thread1, NULL, thread_routine, &mutexes1); |
6eee141f ILT |
141 | assert(err == 0); |
142 | ||
143 | pthread_t thread2; | |
144 | err = pthread_create(&thread2, NULL, thread_routine, &mutexes2); | |
145 | assert(err == 0); | |
146 | ||
147 | // Wait for the first thread to complete the first part. | |
8261e3bf | 148 | safe_lock(&mutexes1.mutex2); |
6eee141f ILT |
149 | |
150 | // Tell the second thread to start. | |
8261e3bf | 151 | safe_unlock(&mutexes2.mutex1); |
6eee141f ILT |
152 | |
153 | // Wait for the second thread to complete the first part. | |
8261e3bf | 154 | safe_lock(&mutexes2.mutex2); |
6eee141f ILT |
155 | |
156 | // Tell the first thread to continue and finish. | |
8261e3bf | 157 | safe_unlock(&mutexes1.mutex3); |
6eee141f ILT |
158 | |
159 | // Wait for the first thread to finish. | |
160 | void* thread_val; | |
161 | err = pthread_join(thread1, &thread_val); | |
162 | assert(err == 0); | |
163 | assert(thread_val == 0); | |
164 | ||
165 | // Tell the second thread to continue and finish. | |
8261e3bf | 166 | safe_unlock(&mutexes2.mutex3); |
6eee141f ILT |
167 | |
168 | // Wait for the second thread to finish. | |
169 | err = pthread_join(thread2, &thread_val); | |
170 | assert(err == 0); | |
171 | assert(thread_val == 0); | |
172 | ||
173 | // All done. | |
e9821041 | 174 | return failed ? 1 : 0; |
6eee141f | 175 | } |