From 7395b1431d5e2160682de273b46252c747ccbf36 Mon Sep 17 00:00:00 2001 From: rpj Date: Sun, 8 May 2005 16:52:50 +0000 Subject: '' --- tests/Bmakefile | 3 +- tests/Debug.dsp | 6 +- tests/Debug.plg | 21 +++--- tests/GNUmakefile | 6 +- tests/Makefile | 3 +- tests/semaphore1.c | 6 +- tests/tsd1.c | 4 +- tests/tsd2.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 243 insertions(+), 21 deletions(-) create mode 100644 tests/tsd2.c (limited to 'tests') diff --git a/tests/Bmakefile b/tests/Bmakefile index 7e18d56..81b79db 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/Debug.dsp b/tests/Debug.dsp index 1e1b1ee..191b978 100644 --- a/tests/Debug.dsp +++ b/tests/Debug.dsp @@ -65,7 +65,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /Ze /W3 /WX /Gm /vd1 /GR- /GX- /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CLEANUP_C" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /WX /Gm /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CLEANUP_C" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0xc09 /d "_DEBUG" # ADD RSC /l 0xc09 /d "_DEBUG" BSC32=bscmake.exe @@ -73,7 +73,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreadVC2.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:".." +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreadVC2d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:".." !ENDIF @@ -87,7 +87,7 @@ SOURCE=.\Debug.txt # End Source File # Begin Source File -SOURCE=.\semaphore4.c +SOURCE=.\semaphore1.c # End Source File # End Target # End Project diff --git a/tests/Debug.plg b/tests/Debug.plg index 9b26377..22ce672 100644 --- a/tests/Debug.plg +++ b/tests/Debug.plg @@ -6,25 +6,22 @@ --------------------Configuration: Debug - Win32 Debug--------------------

Command Lines

-Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8EA.tmp" with contents +Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP9.tmp" with contents [ -/nologo /MDd /Ze /W3 /WX /Gm /vd1 /GR- /GX- /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CLEANUP_C" /FR"Debug/" /Fp"Debug/Debug.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c -"E:\PTHREADS\pthreads\tests\semaphore4.c" +/nologo /MDd /W3 /WX /Gm /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CLEANUP_C" /FR"Debug/" /Fp"Debug/Debug.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c +"E:\PTHREADS\pthreads.2\tests\semaphore1.c" ] -Creating command line "cl.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8EA.tmp" -Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8EB.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP9.tmp" +Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSPA.tmp" with contents [ -kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreadVC.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/Debug.pdb" /debug /machine:I386 /out:"Debug/Debug.exe" /pdbtype:sept /libpath:".." -.\Debug\semaphore4.obj +kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib pthreadVC2d.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/Debug.pdb" /debug /machine:I386 /out:"Debug/Debug.exe" /pdbtype:sept /libpath:".." +.\Debug\semaphore1.obj ] -Creating command line "link.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8EB.tmp" +Creating command line "link.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSPA.tmp"

Output Window

Compiling... -semaphore4.c +semaphore1.c Linking... -Creating command line "bscmake.exe /nologo /o"Debug/Debug.bsc" .\Debug\semaphore4.sbr" -Creating browse info file... -

Output Window

diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 15d8dcc..806a82c 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 0a7738a..8c5c937 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/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/tsd1.c b/tests/tsd1.c index 4d89165..c28e4c5 100644 --- a/tests/tsd1.c +++ b/tests/tsd1.c @@ -112,6 +112,8 @@ setkey(void * arg) 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); @@ -144,7 +146,7 @@ main() for (i = 1; i < NUM_THREADS/2; i++) { - accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; + accesscount[i] = thread_set[i] = thread_destroyed[i] = 0; assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0); } 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