From ac8e3d247fa03af61b5411f92508481e7c3f49f8 Mon Sep 17 00:00:00 2001
From: rpj <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 <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);
+}
-- 
cgit v1.2.3