1 // tls_test.cc -- test TLS variables for gold, main function 2 3 // Copyright (C) 2006-2014 Free Software Foundation, Inc. 4 // Written by Ian Lance Taylor <iant (at) 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> 27 #include <cstdio> 28 #include <pthread.h> 29 #include <semaphore.h> 30 31 #include "tls_test.h" 32 33 // We make these macros so the assert() will give useful line-numbers. 34 #define safe_lock(semptr) \ 35 do \ 36 { \ 37 int err = sem_wait(semptr); \ 38 assert(err == 0); \ 39 } \ 40 while (0) 41 42 #define safe_unlock(semptr) \ 43 do \ 44 { \ 45 int err = sem_post(semptr); \ 46 assert(err == 0); \ 47 } \ 48 while (0) 49 50 struct Sem_set 51 { 52 sem_t sem1; 53 sem_t sem2; 54 sem_t sem3; 55 }; 56 57 Sem_set sems1; 58 Sem_set sems2; 59 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 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. 76 77 void* 78 thread_routine(void* arg) 79 { 80 Sem_set* pms = static_cast<Sem_set*>(arg); 81 82 // Acquire the first semaphore. 83 if (pms) 84 safe_lock(&pms->sem1); 85 86 // Run the tests. 87 check("t1", t1()); 88 check("t2", t2()); 89 check("t3", t3()); 90 check("t4", t4()); 91 f5b(f5a()); 92 check("t5", t5()); 93 f6b(f6a()); 94 check("t6", t6()); 95 check("t8", t8()); 96 check("t9", t9()); 97 f10b(f10a()); 98 check("t10", t10()); 99 check("t11", t11() != 0); 100 check("t12", t12()); 101 check("t_last", t_last()); 102 103 // Release the second semaphore. 104 if (pms) 105 safe_unlock(&pms->sem2); 106 107 // Acquire the third semaphore. 108 if (pms) 109 safe_lock(&pms->sem3); 110 111 check("t_last", t_last()); 112 113 return 0; 114 } 115 116 // The main function. 117 118 int 119 main() 120 { 121 // First, as a sanity check, run through the tests in the "main" thread. 122 thread_routine(0); 123 124 // Set up the semaphores. We want the first thread to start right 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. 129 sem_init(&sems1.sem1, 0, 1); 130 sem_init(&sems1.sem2, 0, 0); 131 sem_init(&sems1.sem3, 0, 0); 132 133 sem_init(&sems2.sem1, 0, 0); 134 sem_init(&sems2.sem2, 0, 0); 135 sem_init(&sems2.sem3, 0, 0); 136 137 pthread_t thread1; 138 int err = pthread_create(&thread1, NULL, thread_routine, &sems1); 139 assert(err == 0); 140 141 pthread_t thread2; 142 err = pthread_create(&thread2, NULL, thread_routine, &sems2); 143 assert(err == 0); 144 145 // Wait for the first thread to complete the first part. 146 safe_lock(&sems1.sem2); 147 148 // Tell the second thread to start. 149 safe_unlock(&sems2.sem1); 150 151 // Wait for the second thread to complete the first part. 152 safe_lock(&sems2.sem2); 153 154 // Tell the first thread to continue and finish. 155 safe_unlock(&sems1.sem3); 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. 164 safe_unlock(&sems2.sem3); 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. 172 return failed ? 1 : 0; 173 } 174