summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrpj <rpj>1999-02-22 02:54:12 +0000
committerrpj <rpj>1999-02-22 02:54:12 +0000
commit2ef097640758653a0e9d63e90a4aac329cd86368 (patch)
tree71751f699b0aedba3227446ac228d30f2a127173
parent943bc9bb02212649a83ec32152299d50d34226e6 (diff)
1999-02-23 Ross Johnson <rpj@ise.canberra.edu.au>
* Makefile: Some refinement. * *.c: More exhaustive checking through assertions; clean up; add some more tests.
-rw-r--r--tests/ChangeLog5
-rw-r--r--tests/Makefile46
-rw-r--r--tests/count1.c42
-rw-r--r--tests/create1.c26
-rw-r--r--tests/exit2.c24
-rw-r--r--tests/exit3.c12
-rw-r--r--tests/eyal1.c182
-rw-r--r--tests/join1.c41
-rw-r--r--tests/mutex1.c25
-rw-r--r--tests/mutex2.c27
-rw-r--r--tests/mutex3.c42
-rw-r--r--tests/once1.c32
-rw-r--r--tests/self1.c23
-rw-r--r--tests/self2.c41
-rw-r--r--tests/self3.c32
-rw-r--r--tests/tsd1.c156
16 files changed, 407 insertions, 349 deletions
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 2d57206..ecbaa2a 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,10 @@
1999-02-23 Ross Johnson <rpj@ise.canberra.edu.au>
+ * Makefile: Some refinement.
+
+ * *.c: More exhaustive checking through assertions; clean up;
+ add some more tests.
+
* Makefile: Now actually runs the tests.
* tests.h: Define our own assert macro. The Mingw32
diff --git a/tests/Makefile b/tests/Makefile
index 56968e5..4fef3c3 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -4,52 +4,66 @@
CP = copy
RM = erase
+MKDIR = mkdir
TOUCH = echo Passed >
+ECHO = @echo
#
# Mingw32
#
CC = gcc
CFLAGS = -g -O2 -UNDEBUG -Wall -o $@ $^
-BUILD_DIR = ../build
-RELEASE_DIR = ../release
-INCLUDES = -I$(BUILD_DIR)/include
-LIBS = $(BUILD_DIR)/lib/libpthread32.a
+BUILD_DIR = ..\build
+INCLUDES = -I./include
+LIBS = ./lib/libpthread32.a
##
## MSVC
##
#CC = cl
#CFLAGS = /W3 /MT /nologo /Yd /Zi /Fe$@ $^
-#BUILD_DIR = ..\build
-#RELEASE_DIR = ..\release
-#INCLUDES = -I$(BUILD_DIR)\include
-#LIBS = $(BUILD_DIR)\lib\pthread.lib
+#BUILD_DIR = ..
+#INCLUDES = -I.\include
+#LIBS = .\lib\pthread.lib
+HDR = .\include\pthread.h
+LIB = .\lib\libpthread32.a
DLL = pthread.dll
# If a test case returns a non-zero exit code to the shell, make will
# stop.
-TESTS = count1 create1 equal1 exit1 exit2 \
- exit3 eyal1 mutex1 mutex2 mutex3 \
- once1 self1 self2 self3 tsd1
+TESTS = count1 create1 equal1 exit1 exit2 exit3 \
+ join1 eyal1 mutex1 mutex2 mutex3 \
+ once1 self1 self2 tsd1
PASSES = $(TESTS:%=%.pass)
all: $(PASSES)
+ @ $(ECHO) ALL TESTS PASSED! Congratulations!
-%.pass: %.exe $(DLL)
+%.pass: %.exe $(LIB) $(DLL) $(HDR)
$*
- $(TOUCH) $@
+ @$(ECHO) Passed
+ @ $(TOUCH) $@
%.exe: %.c
- $(CC) $(CFLAGS) $(INCLUDES) $(LIBS)
+ @ $(CC) $(CFLAGS) $(INCLUDES) $(LIBS)
+
+$(LIB):
+ @- $(MKDIR) .\lib
+ @ $(CP) $(BUILD_DIR)\$@ .\$@
+
+$(HDR):
+ @- $(MKDIR) .\include
+ @ $(CP) $(BUILD_DIR)\$@ .\$@
$(DLL):
- $(CP) ..\build\bin\$@ .
+ @ $(CP) $(BUILD_DIR)\$@ .\$@
clean:
+ - $(RM) *.dll
+ - $(RM) $(LIB)
+ - $(RM) $(HDR)
- $(RM) *.exe
- $(RM) *.pass
-
diff --git a/tests/count1.c b/tests/count1.c
index c4e0c4e..61e82e0 100644
--- a/tests/count1.c
+++ b/tests/count1.c
@@ -7,8 +7,7 @@
* Test some basic assertions about the number of threads at runtime.
*/
-#include <windows.h>
-#include <pthread.h>
+#include "test.h"
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t threads[10];
@@ -27,36 +26,37 @@ myfunc(void *arg)
int
main()
{
- int i, result;
+ int i;
int maxThreads = sizeof(threads) / sizeof(pthread_t);
- /* Spawn ten threads. Each thread should increment the numThreads
- variable, sleep for one second, decrement the variable and then
- exit. The final result of numThreads should be 1 again. */
+ /*
+ * Spawn ten threads. Each thread should increment the numThreads
+ * variable, sleep for one second, decrement the variable and then
+ * exit. The final result of numThreads should be 1 again.
+ */
for (i = 0; i < maxThreads; i++)
{
- result = pthread_create(&threads[i], NULL, myfunc, 0);
- if (result != 0)
- {
- return 1;
- }
+ assert(pthread_create(&threads[i], NULL, myfunc, 0) == 0);
}
- /* Wait for all the threads to exit. */
+ /*
+ * Wait for all the threads to exit.
+ */
for (i = 0; i < maxThreads; i++)
{
- pthread_join(threads[i], NULL);
- pthread_mutex_lock(&lock);
+ assert(pthread_join(threads[i], NULL) == 0);
+ assert(pthread_mutex_lock(&lock) == 0);
numThreads--;
- pthread_mutex_unlock(&lock);
+ assert(pthread_mutex_unlock(&lock) == 0);
}
- /* Check the number of live threads. */
- if (numThreads != 1)
- {
- return 1;
- }
+ /*
+ * Check the number of live threads.
+ */
+ assert(numThreads == 1);
- /* Success. */
+ /*
+ * Success.
+ */
return 0;
}
diff --git a/tests/create1.c b/tests/create1.c
index 2741401..192e52d 100644
--- a/tests/create1.c
+++ b/tests/create1.c
@@ -1,9 +1,19 @@
-#include <pthread.h>
-#include <stdio.h>
-#include <windows.h>
+/*
+ * create1.c
+ *
+ * Description:
+ * Create a thread and check that it ran.
+ *
+ * Depends on API functions: None.
+ */
+
+#include "test.h"
+
+static int washere = 0;
void * func(void * arg)
{
+ washere = 1;
return 0;
}
@@ -11,14 +21,14 @@ int
main()
{
pthread_t t;
- if (pthread_create(&t, NULL, func, NULL) != 0)
- {
- return 1;
- }
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
/* A dirty hack, but we cannot rely on pthread_join in this
primitive test. */
- Sleep(5000);
+ Sleep(2000);
+
+ assert(washere == 1);
return 0;
}
diff --git a/tests/exit2.c b/tests/exit2.c
index 48ad5d0..786e4aa 100644
--- a/tests/exit2.c
+++ b/tests/exit2.c
@@ -1,12 +1,30 @@
/*
* Test for pthread_exit().
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_exit()
*/
-#include <pthread.h>
+#include "test.h"
+
+void *
+func(void * arg)
+{
+ pthread_exit(arg);
+
+ /* Never reached. */
+ exit(1);
+}
int
main(int argc, char * argv[])
{
- /* Should be the same as return 0; */
- pthread_exit(0);
+ pthread_t t;
+
+ assert(pthread_create(&t, NULL, func, (void *) NULL) == 0);
+
+ Sleep(2000);
+
+ return 0;
}
diff --git a/tests/exit3.c b/tests/exit3.c
index f15b39d..b666624 100644
--- a/tests/exit3.c
+++ b/tests/exit3.c
@@ -4,8 +4,7 @@
* Depends on API functions: pthread_create().
*/
-#include <pthread.h>
-#include <stdio.h>
+#include "test.h"
void *
func(void * arg)
@@ -13,7 +12,7 @@ func(void * arg)
pthread_exit(arg);
/* Never reached. */
- return 0;
+ exit(1);
}
int
@@ -25,11 +24,8 @@ main(int argc, char * argv[])
/* Create a few threads and then exit. */
for (i = 0; i < 4; i++)
{
- if (pthread_create(&id[i], NULL, func, (void *) i) != 0)
- {
- return 1;
- }
- }
+ assert(pthread_create(&id[i], NULL, func, (void *) i) == 0);
+ }
/* Success. */
return 0;
diff --git a/tests/eyal1.c b/tests/eyal1.c
index f51bc9c..4345452 100644
--- a/tests/eyal1.c
+++ b/tests/eyal1.c
@@ -43,13 +43,11 @@
* the threads knows its 'id' and also filles in the 'work' done).
*/
-#include <stdio.h>
+#include "test.h"
+
#include <stdlib.h>
#include <math.h>
-#include <pthread.h>
-
-
struct thread_control {
int id;
pthread_t thread; /* thread id */
@@ -63,8 +61,8 @@ struct thread_control {
typedef struct thread_control TC;
static TC *tcs = NULL;
-static int nthreads = 2;
-static int nwork = 0;
+static int nthreads = 7;
+static int nwork = 50;
static int quiet = 0;
static int todo = -1;
@@ -112,8 +110,7 @@ do_work_unit (int who, int n)
else {
/* get lock on stdout
*/
- if (pthread_mutex_lock (&mutex_stdout))
- return (-1);
+ assert(pthread_mutex_lock (&mutex_stdout) == 0);
/* do our job
*/
@@ -125,8 +122,7 @@ do_work_unit (int who, int n)
/* release lock on stdout
*/
- if (pthread_mutex_unlock (&mutex_stdout))
- return (-2);
+ assert(pthread_mutex_unlock (&mutex_stdout) == 0);
}
n = rand () % 10000; /* ignore incoming 'n' */
@@ -142,25 +138,19 @@ print_server (void *ptr)
int n;
TC *tc = (TC *)ptr;
- if (pthread_mutex_lock (&tc->mutex_started))
- return (-1);
+ assert(pthread_mutex_lock (&tc->mutex_started) == 0);
for (;;) {
- if (pthread_mutex_lock (&tc->mutex_start))
- return (-2);
- if (pthread_mutex_unlock (&tc->mutex_start))
- return (-3);
- if (pthread_mutex_lock (&tc->mutex_ended))
- return (-4);
- if (pthread_mutex_unlock (&tc->mutex_started))
- return (-5);
+ assert(pthread_mutex_lock (&tc->mutex_start) == 0);
+ assert(pthread_mutex_unlock (&tc->mutex_start) == 0);
+ assert(pthread_mutex_lock (&tc->mutex_ended) == 0);
+ assert(pthread_mutex_unlock (&tc->mutex_started) == 0);
for (;;) {
/* get lock on todo list
*/
- if (pthread_mutex_lock (&mutex_todo))
- return (-6);
+ assert(pthread_mutex_lock (&mutex_todo) == 0);
mywork = todo;
if (todo >= 0) {
@@ -168,140 +158,102 @@ print_server (void *ptr)
if (todo >= nwork)
todo = -1;
}
- if (pthread_mutex_unlock (&mutex_todo))
- return (-7);
+ assert(pthread_mutex_unlock (&mutex_todo) == 0);
if (mywork < 0)
break;
- if ((n = do_work_unit (tc->id, mywork)) < 0)
- return (-8);
+ assert((n = do_work_unit (tc->id, mywork)) >= 0);
tc->work += n;
}
- if (pthread_mutex_lock (&tc->mutex_end))
- return (-9);
- if (pthread_mutex_unlock (&tc->mutex_end))
- return (-10);
- if (pthread_mutex_lock (&tc->mutex_started))
- return (-11);
- if (pthread_mutex_unlock (&tc->mutex_ended))
- return (-12);
+ assert(pthread_mutex_lock (&tc->mutex_end) == 0);
+ assert(pthread_mutex_unlock (&tc->mutex_end) == 0);
+ assert(pthread_mutex_lock (&tc->mutex_started) == 0);
+ assert(pthread_mutex_unlock (&tc->mutex_ended) == 0);
if (-2 == mywork)
break;
}
- if (pthread_mutex_unlock (&tc->mutex_started))
- return (-13);
+ assert(pthread_mutex_unlock (&tc->mutex_started) == 0);
return (0);
}
-static int
+static void
dosync (void)
{
int i;
for (i = 0; i < nthreads; ++i) {
- if (pthread_mutex_lock (&tcs[i].mutex_end))
- return (-1);
- if (pthread_mutex_unlock (&tcs[i].mutex_start))
- return (-2);
- if (pthread_mutex_lock (&tcs[i].mutex_started))
- return (-3);
- if (pthread_mutex_unlock (&tcs[i].mutex_started))
- return (-4);
+ assert(pthread_mutex_lock (&tcs[i].mutex_end) == 0);
+ assert(pthread_mutex_unlock (&tcs[i].mutex_start) == 0);
+ assert(pthread_mutex_lock (&tcs[i].mutex_started) == 0);
+ assert(pthread_mutex_unlock (&tcs[i].mutex_started) == 0);
}
/* Now threads do their work
*/
for (i = 0; i < nthreads; ++i) {
- if (pthread_mutex_lock (&tcs[i].mutex_start))
- return (-5);
- if (pthread_mutex_unlock (&tcs[i].mutex_end))
- return (-6);
- if (pthread_mutex_lock (&tcs[i].mutex_ended))
- return (-7);
- if (pthread_mutex_unlock (&tcs[i].mutex_ended))
- return (-8);
+ assert(pthread_mutex_lock (&tcs[i].mutex_start) == 0);
+ assert(pthread_mutex_unlock (&tcs[i].mutex_end) == 0);
+ assert(pthread_mutex_lock (&tcs[i].mutex_ended) == 0);
+ assert(pthread_mutex_unlock (&tcs[i].mutex_ended) == 0);
}
-
- return (0);
}
-static int
+static void
dowork (void)
{
todo = 0;
- if (dosync () < 0)
- return (-1);
+ dosync();
todo = 0;
- if (dosync () < 0)
- return (-2);
-
- return (0);
+ dosync();
}
int
main (int argc, char *argv[])
{
int i;
- int nargs;
-
- nthreads = 1;
- nwork = 100;
- nargs = 0;
- for (i = 1; i < argc; ++i) {
- if (!strcmp ("-q", argv[i])) {
- quiet = 1;
- continue;
- }
- if (!strcmp ("-h", argv[i])) {
- printf ("usage: pthreads [nthreads] [nwork] [-q]\n");
- exit (0);
- }
- switch (++nargs) {
- case 1:
- nthreads = atoi (argv[i]);
- if (nthreads > 36) {
- printf ("max 36 threads allowed\n");
- die (1);
- }
- break;
- case 2:
- nwork = atoi (argv[i]);
- break;
- default:
- printf ("bad argument '%s'\n", argv[i]);
- die (1);
- break;
- }
- }
- if (NULL == (tcs = calloc (nthreads, sizeof (*tcs))))
- die (1);
+ assert(NULL != (tcs = calloc (nthreads, sizeof (*tcs))));
/* Launch threads
*/
for (i = 0; i < nthreads; ++i) {
tcs[i].id = i;
- pthread_mutex_init (&tcs[i].mutex_start, NULL);
- pthread_mutex_init (&tcs[i].mutex_started, NULL);
- pthread_mutex_init (&tcs[i].mutex_end, NULL);
- pthread_mutex_init (&tcs[i].mutex_ended, NULL);
+
+ assert(pthread_mutex_init (&tcs[i].mutex_start, NULL) == 0);
+ assert(pthread_mutex_init (&tcs[i].mutex_started, NULL) == 0);
+ assert(pthread_mutex_init (&tcs[i].mutex_end, NULL) == 0);
+ assert(pthread_mutex_init (&tcs[i].mutex_ended, NULL) == 0);
+
tcs[i].work = 0;
- if (pthread_mutex_lock (&tcs[i].mutex_start))
- {}
- tcs[i].stat = pthread_create (&tcs[i].thread,
- NULL /*&pthread_attr_default*/,
- (void*)&print_server, (void *)&tcs[i]);
+
+ assert(pthread_mutex_lock (&tcs[i].mutex_start) == 0);
+ assert((tcs[i].stat =
+ pthread_create (&tcs[i].thread,
+ NULL,
+ (void*)&print_server, (void *)&tcs[i])
+ ) == 0);
/* Wait for thread initialisation
*/
- while (!pthread_mutex_trylock (&tcs[i].mutex_started))
- pthread_mutex_unlock (&tcs[i].mutex_started);
+ while (1)
+ {
+ int trylock;
+
+ trylock = pthread_mutex_trylock(&tcs[i].mutex_started);
+ assert(trylock == 0 || trylock == EBUSY);
+
+ if (trylock == 0)
+ {
+ assert(pthread_mutex_unlock (&tcs[i].mutex_started) == 0);
+ break;
+ }
+ }
}
dowork ();
@@ -309,18 +261,17 @@ main (int argc, char *argv[])
/* Terminate threads
*/
todo = -2; /* please terminate */
- if (dosync () < 0)
- die (2);
+ dosync();
for (i = 0; i < nthreads; ++i) {
if (0 == tcs[i].stat)
- pthread_join (tcs[i].thread, NULL);
+ assert(pthread_join (tcs[i].thread, NULL) == 0);
}
/* destroy locks
*/
- pthread_mutex_destroy (&mutex_stdout);
- pthread_mutex_destroy (&mutex_todo);
+ assert(pthread_mutex_destroy (&mutex_stdout) == 0);
+ assert(pthread_mutex_destroy (&mutex_todo) == 0);
/* Cleanup
*/
@@ -334,10 +285,11 @@ main (int argc, char *argv[])
printf ("%10ld\n", tcs[i].work);
else
printf ("failed %d\n", tcs[i].stat);
- pthread_mutex_destroy (&tcs[i].mutex_start);
- pthread_mutex_destroy (&tcs[i].mutex_started);
- pthread_mutex_destroy (&tcs[i].mutex_end);
- pthread_mutex_destroy (&tcs[i].mutex_ended);
+
+ assert(pthread_mutex_destroy (&tcs[i].mutex_start) == 0);
+ assert(pthread_mutex_destroy (&tcs[i].mutex_started) == 0);
+ assert(pthread_mutex_destroy (&tcs[i].mutex_end) == 0);
+ assert(pthread_mutex_destroy (&tcs[i].mutex_ended) == 0);
}
die (0);
diff --git a/tests/join1.c b/tests/join1.c
new file mode 100644
index 0000000..f6240de
--- /dev/null
+++ b/tests/join1.c
@@ -0,0 +1,41 @@
+/*
+ * Test for pthread_join().
+ *
+ * Depends on API functions: pthread_create(), pthread_exit().
+ */
+
+#include "test.h"
+
+void *
+func(void * arg)
+{
+ Sleep(1000);
+
+ pthread_exit(arg);
+
+ /* Never reached. */
+ exit(1);
+}
+
+int
+main(int argc, char * argv[])
+{
+ pthread_t id[4];
+ int i;
+ int result;
+
+ /* Create a few threads and then exit. */
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_create(&id[i], NULL, func, (void *) i) == 0);
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ assert(pthread_join(id[i], (void *) &result) == 0);
+ assert(result == i);
+ }
+
+ /* Success. */
+ return 0;
+}
diff --git a/tests/mutex1.c b/tests/mutex1.c
index f1c9240..60bb4e7 100644
--- a/tests/mutex1.c
+++ b/tests/mutex1.c
@@ -3,29 +3,28 @@
*
* Create a simple mutex object, lock it, and then unlock it again.
* This is the simplest test of the pthread mutex family that we can do.
+ *
+ * Depends on API functions:
+ * pthread_mutex_init()
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
+ * pthread_mutex_destroy()
*/
-#include <pthread.h>
+#include "test.h"
pthread_mutex_t mutex1;
int
main()
{
- if (pthread_mutex_init(&mutex1, NULL) != 0)
- {
- return 1;
- }
+ assert(pthread_mutex_init(&mutex1, NULL) == 0);
+
+ assert(pthread_mutex_lock(&mutex1) == 0);
- if (pthread_mutex_lock(&mutex1) != 0)
- {
- return 1;
- }
+ assert(pthread_mutex_unlock(&mutex1) == 0);
- if (pthread_mutex_unlock(&mutex1) != 0)
- {
- return 1;
- }
+ assert(pthread_mutex_destroy(&mutex1) == 0);
return 0;
}
diff --git a/tests/mutex2.c b/tests/mutex2.c
index cfbebdc..7956f14 100644
--- a/tests/mutex2.c
+++ b/tests/mutex2.c
@@ -1,29 +1,24 @@
/*
- * mutex1.c
+ * mutex2.c
*
- * Declare a static mutex object, lock it, and then unlock it again.
+ * Declare a static mutex object, lock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_unlock()
*/
-#include <pthread.h>
#include "test.h"
-pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+int
main()
{
- int result;
-
- result = pthread_mutex_trylock(&mutex1);
- printf("pthread_mutex_trylock returned %s\n", error_string[result]);
- if (result != 0)
- {
- return 1;
- }
+ assert(pthread_mutex_lock(&mutex) == 0);
- if (pthread_mutex_unlock(&mutex1) != 0)
- {
- return 1;
- }
+ assert(pthread_mutex_unlock(&mutex) == 0);
return 0;
}
diff --git a/tests/mutex3.c b/tests/mutex3.c
index 2bb6106..26cb070 100644
--- a/tests/mutex3.c
+++ b/tests/mutex3.c
@@ -1,12 +1,44 @@
-#include <pthread.h>
+/*
+ * mutex3.c
+ *
+ * Declare a static mutex object, lock it, trylock it,
+ * and then unlock it again.
+ *
+ * Depends on API functions:
+ * pthread_mutex_lock()
+ * pthread_mutex_trylock()
+ * pthread_mutex_unlock()
+ */
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#include "test.h"
+
+pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
+static int washere = 0;
+
+void * func(void * arg)
+{
+ assert(pthread_mutex_trylock(&mutex1) == EBUSY);
+
+ washere = 1;
+
+ return 0;
+}
+
int
main()
{
- pthread_mutex_lock(&mutex);
- /* do stuff */
- pthread_mutex_unlock(&mutex);
+ pthread_t t;
+
+ assert(pthread_mutex_lock(&mutex1) == 0);
+
+ assert(pthread_create(&t, NULL, func, NULL) == 0);
+
+ Sleep(2000);
+
+ assert(pthread_mutex_unlock(&mutex1) == 0);
+
+ assert(washere == 1);
+
return 0;
}
diff --git a/tests/once1.c b/tests/once1.c
index 661d322..91dc038 100644
--- a/tests/once1.c
+++ b/tests/once1.c
@@ -1,25 +1,29 @@
/*
- * Test for pthread_once().
+ * once1.c
*
- * Depends on functions: pthread_create.
+ * Create a static pthread_once and test that it calls myfunc once.
+ *
+ * Depends on API functions:
+ * pthread_once()
+ * pthread_create()
*/
-#include <pthread.h>
-#include <stdio.h>
+#include "test.h"
pthread_once_t once = PTHREAD_ONCE_INIT;
+static int washere = 0;
+
void
myfunc(void)
{
- printf("only see this once\n");
+ washere++;
}
void *
mythread(void * arg)
{
- int rc = pthread_once(&once, myfunc);
- printf("returned %d\n", rc);
+ assert(pthread_once(&once, myfunc) == 0);
return 0;
}
@@ -27,19 +31,15 @@ mythread(void * arg)
int
main()
{
- int rc;
pthread_t t1, t2;
- if (pthread_create(&t1, NULL, mythread, NULL) != 0)
- {
- return 1;
- }
+ assert(pthread_create(&t1, NULL, mythread, NULL) == 0);
- if (pthread_create(&t2, NULL, mythread, NULL) != 0)
- {
- return 1;
- }
+ assert(pthread_create(&t2, NULL, mythread, NULL) == 0);
Sleep(2000);
+
+ assert(washere == 1);
+
return 0;
}
diff --git a/tests/self1.c b/tests/self1.c
index 0addfc8..d460818 100644
--- a/tests/self1.c
+++ b/tests/self1.c
@@ -1,21 +1,26 @@
/*
+ * self1.c
+ *
* Test for pthread_self().
*
- * Depends on API functions: None.
+ * Depends on API functions:
+ * pthread_self()
+ *
+ * Implicitly depends on:
+ * pthread_getspecific()
+ * pthread_setspecific()
*/
-#include <pthread.h>
+#include "test.h"
int
main(int argc, char * argv[])
{
- pthread_t id;
-
- /* We can't do anything with this, though, because it is not
- safe to assume anything about the internal structure of
- a `pthread_t'. */
-
- id = pthread_self();
+ /*
+ * This should always succeed unless the system has no
+ * resources (memory) left.
+ */
+ assert(pthread_self() != NULL);
return 0;
}
diff --git a/tests/self2.c b/tests/self2.c
index 461e5f9..83339f1 100644
--- a/tests/self2.c
+++ b/tests/self2.c
@@ -1,33 +1,46 @@
-#include <pthread.h>
-#include <assert.h>
-#include <stdio.h>
+/*
+ * self2.c
+ *
+ * Test for pthread_self().
+ *
+ * Depends on API functions:
+ * pthread_create()
+ * pthread_self()
+ *
+ * Implicitly depends on:
+ * pthread_getspecific()
+ * pthread_setspecific()
+ */
+
+#include "test.h"
+#include <string.h>
+
+static pthread_t me;
void *
entry(void * arg)
{
- /* Like systems such as HP-UX, we can't print the value of the thread ID
- because it's not an integral type. Instead, we'll poke our noses into
- the pthread_t structure and dump a useful internal value. This is
- ordinarily bad, m'kay? */
+ me = pthread_self();
- pthread_t t = pthread_self();
- printf("my thread is %lx\n", t->threadH);
return arg;
}
int
main()
{
- int rc;
pthread_t t;
- if (pthread_create(&t, NULL, entry, NULL) != 0)
- {
- return 1;
- }
+ assert(pthread_create(&t, NULL, entry, NULL) == 0);
Sleep(2000);
+ /*
+ * Not much more we can do here but bytewise compare t with
+ * what pthread_self returned.
+ */
+ assert(t == me);
+ assert(memcmp((const void *) t, (const void *) me, sizeof t) == 0);
+
/* Success. */
return 0;
}
diff --git a/tests/self3.c b/tests/self3.c
deleted file mode 100644
index dc220b7..0000000
--- a/tests/self3.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <pthread.h>
-#include <assert.h>
-#include <stdio.h>
-
-void *
-entry(void * arg)
-{
- /* Like systems such as HP-UX, we can't print the value of the thread ID
- because it's not an integral type. Instead, we'll poke our noses into
- the pthread_t structure and dump a useful internal value. This is
- ordinarily bad, m'kay? */
-
- pthread_t t = pthread_self();
- printf("thread no. %d has id %lx\n", (int) arg, t->threadH);
- return 0;
-}
-
-int
-main()
-{
- int rc;
- pthread_t t[2];
-
- rc = pthread_create(&t[0], NULL, entry, (void *) 1);
- assert(rc == 0);
-
- rc = pthread_create(&t[1], NULL, entry, (void *) 2);
- assert(rc == 0);
-
- Sleep(2000);
- return 0;
-}
diff --git a/tests/tsd1.c b/tests/tsd1.c
index 8137a64..93403b1 100644
--- a/tests/tsd1.c
+++ b/tests/tsd1.c
@@ -1,8 +1,7 @@
/*
- * File: tsd1.c
+ * tsd1.c
*
- * Test Synopsis:
- * - Thread Specific Data (TSD) key creation and destruction.
+ * Test Thread Specific Data (TSD) key creation and destruction.
*
* Description:
* -
@@ -44,74 +43,53 @@
* - output identifies failed component
*/
-#include <pthread.h>
-#include <stdio.h>
+#include "test.h"
-pthread_key_t key = NULL;
-pthread_once_t key_once = PTHREAD_ONCE_INIT;
+static pthread_key_t key = NULL;
+static int accesscount[10];
+static int thread_set[10];
+static int thread_destroyed[10];
-void
+static void
destroy_key(void * arg)
{
- /* arg is not NULL if we get to here. */
- printf("SUCCESS: %s: destroying key.\n", (char *) arg);
+ int * j = (int *) arg;
- free((char *) arg);
-}
+ (*j)++;
-void
-make_key(void)
-{
- if (pthread_key_create(&key, destroy_key) != 0)
- {
- printf("Key create failed\n");
- exit(1);
- }
+ assert(*j == 2);
+
+ thread_destroyed[j - accesscount] = 1;
}
-void
+static void
setkey(void * arg)
{
- void * ptr;
+ int * j = (int *) arg;
- if ((ptr = pthread_getspecific(key)) != NULL)
- {
- printf("ERROR: Thread %d, Key not initialised to NULL\n",
- (int) arg);
- exit(1);
- }
- else
- {
- ptr = (void *) malloc(80);
- sprintf((char *) ptr, "Thread %d Key",
- (int) arg);
- (void) pthread_setspecific(key, ptr);
- }
+ thread_set[j - accesscount] = 1;
- if ((ptr = pthread_getspecific(key)) == NULL)
- {
- printf("FAILED: Thread %d Key value set or get failed.\n",
- (int) arg);
- exit(1);
- }
- else
- {
- printf("SUCCESS: Thread %d Key value set and get succeeded.\n",
- (int) arg);
+ assert(*j == 0);
- printf("SUCCESS: %s: exiting thread.\n", (char *) ptr);
- }
+ assert(pthread_getspecific(key) == NULL);
+
+ assert(pthread_setspecific(key, arg) == 0);
+
+ assert(pthread_getspecific(key) == arg);
+
+ (*j)++;
+
+ assert(*j == 1);
}
-void *
+static void *
mythread(void * arg)
{
while (key == NULL)
{
+ Sleep(0);
}
- printf("Thread %d, Key created\n", (int) arg);
-
setkey(arg);
return 0;
@@ -122,38 +100,70 @@ mythread(void * arg)
int
main()
{
- int rc;
- int t;
+ int i;
+ int fail = 0;
pthread_t thread[10];
- for (t = 0; t < 5; t++)
+ for (i = 1; i < 5; i++)
+ {
+ accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
+ assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
+ }
+
+ Sleep(2000);
+
+ /*
+ * Here we test that existing threads will get a key created
+ * for them.
+ */
+ assert(pthread_key_create(&key, destroy_key) == 0);
+
+ /*
+ * 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 = 5; i < 10; i++)
{
- rc = pthread_create(&thread[t], NULL, mythread, (void *) (t + 1));
- printf("pthread_create returned %d\n", rc);
- if (rc != 0)
- {
- return 1;
- }
+ accesscount[i] = thread_set[i] = thread_destroyed[i] = 0;
+ assert(pthread_create(&thread[i], NULL, mythread, (void *)&accesscount[i]) == 0);
}
- (void) pthread_once(&key_once, make_key);
+ /*
+ * Wait for all threads to complete.
+ */
+ for (i = 1; i < 10; i++)
+ {
+ int result = 0;
- /* Test main thread key. */
- setkey((void *) 0);
+ assert(pthread_join(thread[i], (void *) &result) == 0);
+ }
- Sleep(500);
+ assert(pthread_key_delete(key) == 0);
- for (t = 5; t < 10; t++)
+ for (i = 0; i < 10; i++)
{
- rc = pthread_create(&thread[t], NULL, mythread, (void *) (t + 1));
- printf("pthread_create returned %d\n", rc);
- if (rc != 0)
- {
- return 1;
- }
+ /*
+ * 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] != 2)
+ {
+ fail++;
+ fprintf(stderr, "Thread %d key, set = %d, destroyed = %d\n",
+ i, thread_set[i], thread_destroyed[i]);
+ }
}
- Sleep(2000);
- return 0;
-}
+ fflush(stderr);
+ return (fail) ? 1 : 0;
+}