summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Bmakefile3
-rw-r--r--tests/GNUmakefile6
-rw-r--r--tests/Makefile3
-rw-r--r--tests/Wmakefile2
-rw-r--r--tests/semaphore1.c6
-rw-r--r--tests/tsd2.c215
6 files changed, 229 insertions, 6 deletions
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 <sched.h>
+#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);
+}