X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=gold%2Ftestsuite%2Ftls_test_main.cc;fp=gold%2Ftestsuite%2Ftls_test_main.cc;h=0ff02c6bc10413d8fbaa8e1edf8de7d5bab43d21;hp=0000000000000000000000000000000000000000;hb=d5da4f291af551c0b8b79e1d4a9b173d60e5c10e;hpb=7b5ea4fcdf2819e070665ab5610f8b48e3867c10 diff --git a/gold/testsuite/tls_test_main.cc b/gold/testsuite/tls_test_main.cc new file mode 100644 index 0000000..0ff02c6 --- /dev/null +++ b/gold/testsuite/tls_test_main.cc @@ -0,0 +1,175 @@ +// tls_test.cc -- test TLS variables for gold, main function + +// Copyright 2006, 2007, 2008 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +// This is the main function for the TLS test. See tls_test.cc for +// more information. + +#include +#include +#include + +#include "tls_test.h" + +// We make these macros so the assert() will give useful line-numbers. +#define safe_lock(muptr) \ + do \ + { \ + int err = pthread_mutex_lock(muptr); \ + assert(err == 0); \ + } \ + while (0) + +#define safe_unlock(muptr) \ + do \ + { \ + int err = pthread_mutex_unlock(muptr); \ + assert(err == 0); \ + } \ + while (0) + +struct Mutex_set +{ + pthread_mutex_t mutex1; + pthread_mutex_t mutex2; + pthread_mutex_t mutex3; +}; + +Mutex_set mutexes1 = { PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER }; + +Mutex_set mutexes2 = { PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER } ; + +bool failed = false; + +void +check(const char* name, bool val) +{ + if (!val) + { + fprintf(stderr, "Test %s failed\n", name); + failed = true; + } +} + +// The body of the thread function. This gets a lock on the first +// mutex, runs the tests, and then unlocks the second mutex. Then it +// locks the third mutex, and the runs the verification test again. + +void* +thread_routine(void* arg) +{ + Mutex_set* pms = static_cast(arg); + + // Lock the first mutex. + if (pms) + safe_lock(&pms->mutex1); + + // Run the tests. + check("t1", t1()); + check("t2", t2()); + check("t3", t3()); + check("t4", t4()); + f5b(f5a()); + check("t5", t5()); + f6b(f6a()); + check("t6", t6()); + check("t8", t8()); + check("t9", t9()); + f10b(f10a()); + check("t10", t10()); + check("t11", t11() != 0); + check("t12", t12()); + check("t_last", t_last()); + + // Unlock the second mutex. + if (pms) + safe_unlock(&pms->mutex2); + + // Lock the third mutex. + if (pms) + safe_lock(&pms->mutex3); + + check("t_last", t_last()); + + return 0; +} + +// The main function. + +int +main() +{ + // First, as a sanity check, run through the tests in the "main" thread. + thread_routine(0); + + // Set up the mutex locks. We want the first thread to start right + // away, tell us when it is done with the first part, and wait for + // us to release it. We want the second thread to wait to start, + // tell us when it is done with the first part, and wait for us to + // release it. + safe_lock(&mutexes1.mutex2); + safe_lock(&mutexes1.mutex3); + + safe_lock(&mutexes2.mutex1); + safe_lock(&mutexes2.mutex2); + safe_lock(&mutexes2.mutex3); + + pthread_t thread1; + int err = pthread_create(&thread1, NULL, thread_routine, &mutexes1); + assert(err == 0); + + pthread_t thread2; + err = pthread_create(&thread2, NULL, thread_routine, &mutexes2); + assert(err == 0); + + // Wait for the first thread to complete the first part. + safe_lock(&mutexes1.mutex2); + + // Tell the second thread to start. + safe_unlock(&mutexes2.mutex1); + + // Wait for the second thread to complete the first part. + safe_lock(&mutexes2.mutex2); + + // Tell the first thread to continue and finish. + safe_unlock(&mutexes1.mutex3); + + // Wait for the first thread to finish. + void* thread_val; + err = pthread_join(thread1, &thread_val); + assert(err == 0); + assert(thread_val == 0); + + // Tell the second thread to continue and finish. + safe_unlock(&mutexes2.mutex3); + + // Wait for the second thread to finish. + err = pthread_join(thread2, &thread_val); + assert(err == 0); + assert(thread_val == 0); + + // All done. + return failed ? 1 : 0; +}