From ac8e3d247fa03af61b5411f92508481e7c3f49f8 Mon Sep 17 00:00:00 2001 From: rpj Date: Sun, 8 May 2005 16:55:02 +0000 Subject: '' --- tests/Bmakefile | 3 +- tests/GNUmakefile | 6 +- tests/Makefile | 3 +- tests/Wmakefile | 2 +- tests/semaphore1.c | 6 +- tests/tsd2.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 tests/tsd2.c (limited to 'tests') diff --git a/tests/Bmakefile b/tests/Bmakefile index 60b0a75..6141ffe 100644 --- a/tests/Bmakefile +++ b/tests/Bmakefile @@ -96,7 +96,7 @@ PASSES= loadfree.pass \ cancel1.pass cancel2.pass \ semaphore4.pass semaphore4t.pass \ barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass \ - tsd1.pass delay1.pass delay2.pass eyal1.pass \ + tsd1.pass tsd2.pass delay1.pass delay2.pass eyal1.pass \ condvar3.pass condvar3_1.pass condvar3_2.pass condvar3_3.pass \ condvar4.pass condvar5.pass condvar6.pass \ condvar7.pass condvar8.pass condvar9.pass \ @@ -342,5 +342,6 @@ spin3.pass: spin2.pass spin4.pass: spin3.pass stress1.pass: barrier5.pass tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass valid1.pass: join1.pass valid2.pass: valid1.pass diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 641164d..e9df21a 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -90,7 +90,7 @@ TESTS = sizes loadfree \ cancel1 cancel2 \ semaphore4 semaphore4t \ barrier1 barrier2 barrier3 barrier4 barrier5 \ - tsd1 delay1 delay2 eyal1 \ + tsd1 tsd2 delay1 delay2 eyal1 \ condvar3 condvar3_1 condvar3_2 condvar3_3 \ condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \ errno1 \ @@ -149,6 +149,9 @@ GC-bench: GCE-bench: $(MAKE) TEST=GCE CC=g++ XXCFLAGS="-mthreads -D__CLEANUP_CXX" XXLIBS="benchlib." all-bench +GC-debug: + $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C" DLL_VER="$(DLL_VER)d" all-pass + GC-static: $(MAKE) TEST=GC CC=gcc XXCFLAGS="-D__CLEANUP_C -DPTW32_STATIC_LIB" DLL="" all-static @@ -305,6 +308,7 @@ spin2.pass: spin1.pass spin3.pass: spin2.pass spin4.pass: spin3.pass tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass valid1.pass: join1.pass valid2.pass: valid1.pass diff --git a/tests/Makefile b/tests/Makefile index 8fa72b4..d12a1f1 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -100,7 +100,7 @@ PASSES= sizes.pass loadfree.pass \ cancel1.pass cancel2.pass \ semaphore4.pass semaphore4t.pass \ barrier1.pass barrier2.pass barrier3.pass barrier4.pass barrier5.pass \ - tsd1.pass delay1.pass delay2.pass eyal1.pass \ + tsd1.pass tsd2.pass delay1.pass delay2.pass eyal1.pass \ condvar3.pass condvar3_1.pass condvar3_2.pass condvar3_3.pass \ condvar4.pass condvar5.pass condvar6.pass \ condvar7.pass condvar8.pass condvar9.pass \ @@ -397,5 +397,6 @@ spin2.pass: spin1.pass spin3.pass: spin2.pass spin4.pass: spin3.pass tsd1.pass: barrier5.pass join1.pass +tsd2.pass: tsd1.pass valid1.pass: join1.pass valid2.pass: valid1.pass diff --git a/tests/Wmakefile b/tests/Wmakefile index c8db27a..4f003df 100644 --- a/tests/Wmakefile +++ b/tests/Wmakefile @@ -32,7 +32,7 @@ # -DLL_VER = 1 +DLL_VER = 2 .EXTENSIONS: diff --git a/tests/semaphore1.c b/tests/semaphore1.c index 4327e73..f89a430 100644 --- a/tests/semaphore1.c +++ b/tests/semaphore1.c @@ -86,7 +86,8 @@ thr(void * arg) if ( result == -1 ) { int err = errno; - perror("thread: sem_trywait 1: expect an EAGAIN error"); // No error + printf("thread: sem_trywait 1: expecting error %s: got %s\n", + error_string[EAGAIN], error_string[err]); fflush(stdout); assert(err == EAGAIN); } else @@ -131,7 +132,8 @@ main() if ( result == -1 ) { int err = errno; - perror("main: sem_trywait 1: expect an EAGAIN error"); // No error + printf("main: sem_trywait 1: expecting error %s: got %s\n", + error_string[EAGAIN], error_string[err]); fflush(stdout); assert(err == EAGAIN); } else diff --git a/tests/tsd2.c b/tests/tsd2.c new file mode 100644 index 0000000..d1f50cd --- /dev/null +++ b/tests/tsd2.c @@ -0,0 +1,215 @@ +/* + * tsd2.c + * + * Test Thread Specific Data (TSD) key creation and destruction. + * + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * + * -------------------------------------------------------------------------- + * + * Description: + * - + * + * Test Method (validation or falsification): + * - validation + * + * Requirements Tested: + * - keys are created for each existing thread including the main thread + * - keys are created for newly created threads + * - keys are thread specific + * - destroy routine is called on each thread exit including the main thread + * + * Features Tested: + * - + * + * Cases Tested: + * - + * + * Environment: + * - + * + * Input: + * - none + * + * Output: + * - text to stdout + * + * Assumptions: + * - already validated: pthread_create() + * pthread_once() + * - main thread also has a POSIX thread identity + * + * Pass Criteria: + * - stdout matches file reference/tsd1.out + * + * Fail Criteria: + * - fails to match file reference/tsd1.out + * - output identifies failed component + */ + +#include +#include "test.h" + +enum { + NUM_THREADS = 100 +}; + +static pthread_key_t key = NULL; +static int accesscount[NUM_THREADS]; +static int thread_set[NUM_THREADS]; +static int thread_destroyed[NUM_THREADS]; +static pthread_barrier_t startBarrier; + +static void +destroy_key(void * arg) +{ + int * j = (int *) arg; + + (*j)++; + + /* Set TSD key from the destructor to test destructor iteration */ + if (*j == 2) + assert(pthread_setspecific(key, arg) == 0); + else + assert(*j == 3); + + thread_destroyed[j - accesscount] = 1; +} + +static void +setkey(void * arg) +{ + int * j = (int *) arg; + + thread_set[j - accesscount] = 1; + + assert(*j == 0); + + assert(pthread_getspecific(key) == NULL); + + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + assert(pthread_setspecific(key, arg) == 0); + + assert(pthread_getspecific(key) == arg); + + (*j)++; + + assert(*j == 1); +} + +static void * +mythread(void * arg) +{ + (void) pthread_barrier_wait(&startBarrier); + + setkey(arg); + + return 0; + + /* Exiting the thread will call the key destructor. */ +} + +int +main() +{ + int i; + int fail = 0; + pthread_t thread[NUM_THREADS]; + + assert(pthread_barrier_init(&startBarrier, NULL, NUM_THREADS/2) == 0); + + for (i = 1; i < NUM_THREADS/2; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Here we test that existing threads will get a key created + * for them. + */ + assert(pthread_key_create(&key, destroy_key) == 0); + + (void) pthread_barrier_wait(&startBarrier); + + /* + * Test main thread key. + */ + accesscount[0] = 0; + setkey((void *) &accesscount[0]); + + /* + * Here we test that new threads will get a key created + * for them. + */ + for (i = NUM_THREADS/2; i < NUM_THREADS; i++) + { + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); + } + + /* + * Wait for all threads to complete. + */ + for (i = 1; i < NUM_THREADS; i++) + { + int result = 0; + + assert(pthread_join(thread[i], (void **) &result) == 0); + } + + assert(pthread_key_delete(key) == 0); + + assert(pthread_barrier_destroy(&startBarrier) == 0); + + for (i = 1; i < NUM_THREADS; i++) + { + /* + * The counter is incremented once when the key is set to + * a value, and again when the key is destroyed. If the key + * doesn't get set for some reason then it will still be + * NULL and the destroy function will not be called, and + * hence accesscount will not equal 2. + */ + if (accesscount[i] != 3) + { + fail++; + fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n", + i, thread_set[i], thread_destroyed[i]); + } + } + + fflush(stderr); + + return (fail); +} -- cgit v1.2.3