summaryrefslogtreecommitdiff
path: root/libpthread/tests
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/tests')
-rw-r--r--libpthread/tests/.cvsignore1
-rw-r--r--libpthread/tests/Makefile29
-rw-r--r--libpthread/tests/test-1.c49
-rw-r--r--libpthread/tests/test-10.c46
-rw-r--r--libpthread/tests/test-11.c143
-rw-r--r--libpthread/tests/test-12.c29
-rw-r--r--libpthread/tests/test-13.c66
-rw-r--r--libpthread/tests/test-14.c44
-rw-r--r--libpthread/tests/test-15.c87
-rw-r--r--libpthread/tests/test-16.c71
-rw-r--r--libpthread/tests/test-2.c39
-rw-r--r--libpthread/tests/test-3.c55
-rw-r--r--libpthread/tests/test-4.c86
-rw-r--r--libpthread/tests/test-5.c75
-rw-r--r--libpthread/tests/test-6.c95
-rw-r--r--libpthread/tests/test-7.c66
-rw-r--r--libpthread/tests/test-8.c60
-rw-r--r--libpthread/tests/test-9.c88
18 files changed, 1129 insertions, 0 deletions
diff --git a/libpthread/tests/.cvsignore b/libpthread/tests/.cvsignore
new file mode 100644
index 00000000..70845e08
--- /dev/null
+++ b/libpthread/tests/.cvsignore
@@ -0,0 +1 @@
+Makefile.in
diff --git a/libpthread/tests/Makefile b/libpthread/tests/Makefile
new file mode 100644
index 00000000..9509c957
--- /dev/null
+++ b/libpthread/tests/Makefile
@@ -0,0 +1,29 @@
+CFLAGS=-Wall -g
+
+LDLIBS = -lpthread
+
+CHECK_SRC := test-1.c test-2.c test-3.c test-6.c test-7.c test-8.c \
+ test-9.c test-10.c test-11.c test-12.c test-13.c test-14.c \
+ test-15.c test-16.c
+
+CHECK_OBJS := $(addsuffix .o,$(basename $(notdir $(CHECK_SRC))))
+CHECK_PROGS := $(basename $(notdir $(CHECK_SRC))) \
+ $(addsuffix -static, $(basename $(CHECK_SRC)))
+
+%-static: %.o
+ $(CC) -static $(CFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS)
+
+check: $(CHECK_OBJS) $(CHECK_PROGS)
+ for i in $(CHECK_PROGS); do \
+ echo -n Running $$i...\ ; \
+ if ./$$i 2>&1 > $$i.out; \
+ then \
+ echo Success.; \
+ else \
+ echo Failure.; \
+ fi \
+ done
+
+clean:
+ rm -f $(CHECK_OBJS) $(CHECK_PROGS) \
+ $(addsuffix .out,$(basename $(notdir $(CHECK_PROGS)))) \ No newline at end of file
diff --git a/libpthread/tests/test-1.c b/libpthread/tests/test-1.c
new file mode 100644
index 00000000..318fd6e9
--- /dev/null
+++ b/libpthread/tests/test-1.c
@@ -0,0 +1,49 @@
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <unistd.h>
+#include <error.h>
+#include <errno.h>
+#include <stdio.h>
+
+#define THREADS 500
+
+void *
+foo (void *arg)
+{
+ pthread_mutex_t *mutex = arg;
+ pthread_mutex_lock (mutex);
+ pthread_mutex_unlock (mutex);
+ return mutex;
+}
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ error_t err;
+ pthread_t tid[THREADS];
+ pthread_mutex_t mutex[THREADS];
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ pthread_mutex_init (&mutex[i], 0);
+ pthread_mutex_lock (&mutex[i]);
+ err = pthread_create (&tid[i], 0, foo, &mutex[i]);
+ if (err)
+ error (1, err, "pthread_create");
+ sched_yield ();
+ }
+
+ for (i = THREADS - 1; i >= 0; i --)
+ {
+ void *ret;
+ pthread_mutex_unlock (&mutex[i]);
+ err = pthread_join (tid[i], &ret);
+ if (err)
+ error (1, err, "pthread_join");
+ assert (ret == &mutex[i]);
+ }
+
+ return 0;
+}
diff --git a/libpthread/tests/test-10.c b/libpthread/tests/test-10.c
new file mode 100644
index 00000000..bec05c14
--- /dev/null
+++ b/libpthread/tests/test-10.c
@@ -0,0 +1,46 @@
+/* Test error checking mutexes. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ pthread_mutexattr_t mattr;
+ pthread_mutex_t mutex;
+
+ err = pthread_mutexattr_init (&mattr);
+ if (err)
+ error (1, err, "pthread_mutexattr_init");
+
+ err = pthread_mutexattr_settype (&mattr, PTHREAD_MUTEX_ERRORCHECK);
+ if (err)
+ error (1, err, "pthread_mutexattr_settype");
+
+ err = pthread_mutex_init (&mutex, &mattr);
+ if (err)
+ error (1, err, "pthread_mutex_init");
+
+ err = pthread_mutexattr_destroy (&mattr);
+ if (err)
+ error (1, err, "pthread_mutexattr_destroy");
+
+ err = pthread_mutex_lock (&mutex);
+ assert (err == 0);
+
+ err = pthread_mutex_lock (&mutex);
+ assert (err == EDEADLK);
+
+ err = pthread_mutex_unlock (&mutex);
+ assert (err == 0);
+
+ err = pthread_mutex_unlock (&mutex);
+ assert (err == EPERM);
+
+ return 0;
+}
diff --git a/libpthread/tests/test-11.c b/libpthread/tests/test-11.c
new file mode 100644
index 00000000..de779a40
--- /dev/null
+++ b/libpthread/tests/test-11.c
@@ -0,0 +1,143 @@
+/* Test rwlocks. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 1
+
+int a;
+int b;
+
+/* Get a read lock and assert that a == b. */
+void *
+test1 (void *arg)
+{
+ error_t err;
+ pthread_rwlock_t *lock = arg;
+ int i;
+
+ for (i = 0; i < 200; i ++)
+ {
+ err = pthread_rwlock_rdlock (lock);
+ assert (err == 0);
+
+ assert (a == b);
+
+ sched_yield ();
+
+ assert (a == b);
+
+ err = pthread_rwlock_unlock (lock);
+ assert (err == 0);
+ }
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ pthread_rwlockattr_t attr;
+ pthread_rwlock_t lock;
+ int pshared;
+
+ int i;
+ pthread_t tid[THREADS];
+ void *ret;
+
+ err = pthread_rwlockattr_init (&attr);
+ if (err)
+ error (1, err, "pthread_rwlockattr_init");
+
+ err = pthread_rwlockattr_getpshared (&attr, &pshared);
+ if (err)
+ error (1, err, "pthread_rwlockattr_getpshared");
+
+ /* Assert the default state as mandated by POSIX. */
+ assert (pshared == PTHREAD_PROCESS_PRIVATE);
+
+ err = pthread_rwlockattr_setpshared (&attr, pshared);
+ if (err)
+ error (1, err, "pthread_rwlockattr_setpshared");
+
+ err = pthread_rwlock_init (&lock, &attr);
+ if (err)
+ error (1, err, "pthread_rwlock_init");
+
+ err = pthread_rwlockattr_destroy (&attr);
+ if (err)
+ error (1, err, "pthread_rwlockattr_destroy");
+
+ /* Now test the lock. */
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ err = pthread_create (&tid[i], 0, test1, &lock);
+ if (err)
+ error (1, err, "pthread_create");
+ }
+
+ for (i = 0; i < 10; i ++)
+ {
+ sched_yield ();
+
+ /* Get a write lock. */
+ pthread_rwlock_wrlock (&lock);
+ /* Increment a and b giving other threads a chance to run in
+ between. */
+ sched_yield ();
+ a ++;
+ sched_yield ();
+ b ++;
+ sched_yield ();
+ /* Unlock. */
+ pthread_rwlock_unlock (&lock);
+ }
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ err = pthread_join (tid[i], &ret);
+ if (err)
+ error (1, err, "pthread_join");
+ }
+
+ /* Read lock it. */
+ err = pthread_rwlock_tryrdlock (&lock);
+ assert (err == 0);
+
+ /* Try to write lock it. It should fail with EBUSY. */
+ err = pthread_rwlock_trywrlock (&lock);
+ assert (err == EBUSY);
+
+ /* Drop the read lock. */
+ err = pthread_rwlock_unlock (&lock);
+ assert (err == 0);
+
+ /* Get a write lock. */
+ err = pthread_rwlock_trywrlock (&lock);
+ assert (err == 0);
+
+ /* Fail trying to acquire another write lock. */
+ err = pthread_rwlock_trywrlock (&lock);
+ assert (err == EBUSY);
+
+ /* Try to get a read lock which should also fail. */
+ err = pthread_rwlock_tryrdlock (&lock);
+ assert (err == EBUSY);
+
+ /* Unlock it. */
+ err = pthread_rwlock_unlock (&lock);
+ assert (err == 0);
+
+
+ err = pthread_rwlock_destroy (&lock);
+ if (err)
+ error (1, err, "pthread_rwlock_destroy");
+
+ return 0;
+}
diff --git a/libpthread/tests/test-12.c b/libpthread/tests/test-12.c
new file mode 100644
index 00000000..2b784908
--- /dev/null
+++ b/libpthread/tests/test-12.c
@@ -0,0 +1,29 @@
+/* Test concurrency level. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ int err;
+
+ i = pthread_getconcurrency ();
+ assert (i == 0);
+
+ err = pthread_setconcurrency (-1);
+ assert (err == EINVAL);
+
+ err = pthread_setconcurrency (4);
+ assert (err == 0);
+
+ i = pthread_getconcurrency ();
+ assert (i == 4);
+
+ return 0;
+}
diff --git a/libpthread/tests/test-13.c b/libpthread/tests/test-13.c
new file mode 100644
index 00000000..13b09051
--- /dev/null
+++ b/libpthread/tests/test-13.c
@@ -0,0 +1,66 @@
+/* Test condition attributes and pthread_cond_timedwait. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <sys/time.h>
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ int i;
+ pthread_condattr_t attr;
+ pthread_cond_t cond;
+ struct timespec ts;
+ pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+ struct timeval before, after;
+ int diff;
+
+ err = pthread_condattr_init (&attr);
+ if (err)
+ error (1, err, "pthread_condattr_init");
+
+ err = pthread_condattr_getpshared (&attr, &i);
+ if (err)
+ error (1, err, "pthread_condattr_getpshared");
+ assert (i == PTHREAD_PROCESS_PRIVATE);
+
+ err = pthread_condattr_setpshared (&attr, PTHREAD_PROCESS_PRIVATE);
+ assert (err == 0);
+
+ err = pthread_cond_init (&cond, &attr);
+ if (err)
+ error (1, err, "pthread_cond_init");
+
+ err = pthread_condattr_destroy (&attr);
+ if (err)
+ error (1, err, "pthread_condattr_destroy");
+
+ gettimeofday (&before, 0);
+ ts.tv_sec = before.tv_sec + 1;
+ ts.tv_nsec = before.tv_usec * 1000;
+
+ printf ("Starting wait @ %d\n", (int) before.tv_sec);
+
+ pthread_mutex_lock (&m);
+ err = pthread_cond_timedwait (&cond, &m, &ts);
+
+ gettimeofday (&after, 0);
+
+ printf ("End wait @ %d (err = %d)\n", (int) after.tv_sec, err);
+
+ assert (err == ETIMEDOUT);
+
+ diff = after.tv_sec * 1000000 + after.tv_usec
+ - before.tv_sec * 1000000 - before.tv_usec;
+
+ if (diff < 900000 || diff > 1100000)
+ error (1, EGRATUITOUS, "pthread_cond_timedwait waited %d us", diff);
+
+ return 0;
+}
diff --git a/libpthread/tests/test-14.c b/libpthread/tests/test-14.c
new file mode 100644
index 00000000..b1dbfa66
--- /dev/null
+++ b/libpthread/tests/test-14.c
@@ -0,0 +1,44 @@
+/* Test pthread_mutex_timedlock. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <sys/time.h>
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ struct timespec ts;
+ pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+ struct timeval before, after;
+ int diff;
+
+ gettimeofday (&before, 0);
+ ts.tv_sec = before.tv_sec + 1;
+ ts.tv_nsec = before.tv_usec * 1000;
+
+ printf ("Starting wait @ %d\n", (int) before.tv_sec);
+
+ pthread_mutex_lock (&m);
+ /* A default mutex shall dead lock if locked twice. As such we do
+ not need spawn a second thread. */
+ err = pthread_mutex_timedlock (&m, &ts);
+ assert (err == ETIMEDOUT);
+
+ gettimeofday (&after, 0);
+
+ printf ("End wait @ %d\n", (int) after.tv_sec);
+
+ diff = after.tv_sec * 1000000 + after.tv_usec
+ - before.tv_sec * 1000000 - before.tv_usec;
+
+ if (diff < 900000 || diff > 1100000)
+ error (1, EGRATUITOUS, "pthread_mutex_timedlock waited %d us", diff);
+
+ return 0;
+}
diff --git a/libpthread/tests/test-15.c b/libpthread/tests/test-15.c
new file mode 100644
index 00000000..173f8b6b
--- /dev/null
+++ b/libpthread/tests/test-15.c
@@ -0,0 +1,87 @@
+/* Test pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#define THREADS 10
+
+pthread_rwlock_t rwlock;
+
+void *
+test (void *arg)
+{
+ error_t err;
+ int foo = (int) arg;
+ struct timespec ts;
+ struct timeval before, after;
+ int diff;
+
+ gettimeofday (&before, 0);
+ ts.tv_sec = before.tv_sec + 1;
+ ts.tv_nsec = before.tv_usec * 1000;
+
+ printf ("Thread %d starting wait @ %d\n", pthread_self (),
+ (int) before.tv_sec);
+
+ if (foo % 2 == 0)
+ err = pthread_rwlock_timedrdlock (&rwlock, &ts);
+ else
+ err = pthread_rwlock_timedwrlock (&rwlock, &ts);
+
+ assert (err == ETIMEDOUT);
+
+ gettimeofday (&after, 0);
+
+ printf ("Thread %d ending wait @ %d\n", pthread_self (),
+ (int) after.tv_sec);
+
+ diff = after.tv_sec * 1000000 + after.tv_usec
+ - before.tv_sec * 1000000 - before.tv_usec;
+
+ if (diff < 900000 || diff > 1100000)
+ error (1, EGRATUITOUS, "pthread_mutex_timedlock waited %d us", diff);
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ int i;
+ pthread_t tid[THREADS];
+
+ err = pthread_rwlock_init (&rwlock, 0);
+ if (err)
+ error (1, err, "pthread_rwlock_init");
+
+ /* Lock it so all the threads will block. */
+ err = pthread_rwlock_wrlock (&rwlock);
+ assert (err == 0);
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ err = pthread_create (&tid[i], 0, test, (void *) i);
+ if (err)
+ error (1, err, "pthread_create");
+ }
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ void *ret;
+
+ err = pthread_join (tid[i], &ret);
+ if (err)
+ error (1, err, "pthread_join");
+
+ assert (ret == 0);
+ }
+
+ return 0;
+}
diff --git a/libpthread/tests/test-16.c b/libpthread/tests/test-16.c
new file mode 100644
index 00000000..b6a52d01
--- /dev/null
+++ b/libpthread/tests/test-16.c
@@ -0,0 +1,71 @@
+/* Test pthread_kill.c. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <hurd/signal.h>
+
+pthread_t testthread;
+
+int i;
+
+void *
+test (void *arg)
+{
+ error_t err;
+
+ printf ("test: %d\n", pthread_self ());
+
+ err = pthread_kill (pthread_self (), SIGINFO);
+ if (err)
+ error (1, err, "pthread_kill");
+
+ /* To avoid using condition variables in a signal handler. */
+ while (i == 0)
+ sched_yield ();
+
+ return 0;
+}
+
+static void
+handler (int sig, siginfo_t *info, void *context)
+{
+ assert (pthread_equal (pthread_self (), testthread));
+ printf ("handler: %d\n", pthread_self ());
+ i = 1;
+}
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ struct sigaction sa;
+ void *ret;
+
+ printf ("main: %d\n", pthread_self ());
+
+ sa.sa_handler = handler;
+ sa.sa_mask = 0;
+ sa.sa_flags = 0;
+
+ err = sigaction (SIGINFO, &sa, 0);
+ if (err)
+ error (1, err, "sigaction");
+
+ err = pthread_create (&testthread, 0, test, 0);
+ if (err)
+ error (1, err, "pthread_create");
+
+ err = pthread_join (testthread, &ret);
+ if (err)
+ error (1, err, "pthread_join");
+
+ assert (ret == 0);
+
+ return 0;
+}
diff --git a/libpthread/tests/test-2.c b/libpthread/tests/test-2.c
new file mode 100644
index 00000000..701462e8
--- /dev/null
+++ b/libpthread/tests/test-2.c
@@ -0,0 +1,39 @@
+/* Test detachability. */
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+#include <unistd.h>
+
+void *
+thread (void *arg)
+{
+ while (1)
+ sched_yield ();
+}
+
+int
+main (int argc, char **argv)
+{
+ int err;
+ pthread_t tid;
+ void *ret;
+
+ err = pthread_create (&tid, 0, thread, 0);
+ if (err)
+ error (1, err, "pthread_create");
+
+ err = pthread_detach (tid);
+ if (err)
+ error (1, err, "pthread_detach");
+
+ err = pthread_detach (tid);
+ assert (err == EINVAL);
+
+ err = pthread_join (tid, &ret);
+ assert (err == EINVAL);
+
+ return 0;
+}
diff --git a/libpthread/tests/test-3.c b/libpthread/tests/test-3.c
new file mode 100644
index 00000000..7db2e43f
--- /dev/null
+++ b/libpthread/tests/test-3.c
@@ -0,0 +1,55 @@
+/* Test the thread attribute get and set methods. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <sched.h>
+#include <assert.h>
+#include <errno.h>
+
+int
+main (int argc, char *argv[])
+{
+ error_t err;
+ pthread_attr_t attr;
+
+ int i;
+ struct sched_param sp;
+ void *p;
+ size_t sz;
+
+ err = pthread_attr_init (&attr);
+ assert_perror (err);
+
+ err = pthread_attr_destroy (&attr);
+ assert_perror (err);
+
+ err = pthread_attr_init (&attr);
+ assert_perror (err);
+
+#define TEST1(foo, rv, v) \
+ err = pthread_attr_get##foo (&attr, rv); \
+ assert_perror (err); \
+ \
+ err = pthread_attr_set##foo (&attr, v); \
+ assert_perror (err);
+
+#define TEST(foo, rv, v) TEST1(foo, rv, v)
+
+ TEST(inheritsched, &i, i);
+ TEST(schedparam, &sp, &sp);
+ TEST(schedpolicy, &i, i);
+ TEST(scope, &i, i);
+ TEST(stackaddr, &p, p);
+ TEST(detachstate, &i, i);
+ TEST(guardsize, &sz, sz);
+ TEST(stacksize, &sz, sz);
+
+ err = pthread_attr_getstack (&attr, &p, &sz);
+ assert_perror (err);
+
+ err = pthread_attr_setstack (&attr, p, sz);
+ assert_perror (err);
+
+ return 0;
+}
diff --git a/libpthread/tests/test-4.c b/libpthread/tests/test-4.c
new file mode 100644
index 00000000..de9c8fe4
--- /dev/null
+++ b/libpthread/tests/test-4.c
@@ -0,0 +1,86 @@
+/* Test the stack guard. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+size_t stacksize;
+
+void *
+thr (void *arg)
+{
+ int i;
+ char *foo;
+
+ foo = alloca (3 * stacksize / 4);
+ for (i = 0; i < sizeof foo; i ++)
+ foo[i] = -1;
+
+ return (void *) 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+ error_t err;
+ pid_t child;
+
+ child = fork ();
+ switch (child)
+ {
+ case -1:
+ error (1, errno, "fork");
+ break;
+
+ case 0:
+ {
+ pthread_attr_t attr;
+ pthread_t tid;
+ void *ret;
+
+ err = pthread_attr_init (&attr);
+ assert_perror (err);
+
+ err = pthread_attr_getstacksize (&attr, &stacksize);
+ assert_perror (err);
+
+ err = pthread_attr_setguardsize (&attr, stacksize / 2);
+ if (err == ENOTSUP)
+ {
+ printf ("Stack guard attribute not supported.\n");
+ return 1;
+ }
+ assert_perror (err);
+
+ err = pthread_create (&tid, &attr, thr, 0);
+ assert_perror (err);
+
+ err = pthread_attr_destroy (&attr);
+ assert_perror (err);
+
+ err = pthread_join (tid, &ret);
+ /* Should never be successful. */
+ printf ("Thread did not segfault!?!\n");
+ assert_perror (err);
+ return 0;
+ }
+
+ default:
+ {
+ pid_t pid;
+ int status;
+
+ pid = waitpid (child, &status, 0);
+ printf ("pid = %d; child = %d; status = %d\n", pid, child, status);
+ assert (pid == child);
+ assert (status != 0);
+ }
+ }
+
+ return 0;
+}
diff --git a/libpthread/tests/test-5.c b/libpthread/tests/test-5.c
new file mode 100644
index 00000000..0f5000b2
--- /dev/null
+++ b/libpthread/tests/test-5.c
@@ -0,0 +1,75 @@
+/* Test signals. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <assert.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+void *
+thr (void *arg)
+{
+ * (int *)0 = 0;
+ return 0;
+}
+
+int foobar;
+
+int
+main (int argc, char *argv[])
+{
+ error_t err;
+ pid_t child;
+
+ struct rlimit limit;
+
+ limit.rlim_cur = 0;
+ limit.rlim_max = 0;
+
+ err = setrlimit (RLIMIT_CORE, &limit);
+ if (err)
+ error (1, err, "setrlimit");
+
+ child = fork ();
+ switch (child)
+ {
+ case -1:
+ error (1, errno, "fork");
+ break;
+
+ case 0:
+ {
+ pthread_t tid;
+ void *ret;
+
+ err = pthread_create (&tid, 0, thr, 0);
+ if (err)
+ error (1, err, "pthread_create");
+
+ err = pthread_join (tid, &ret);
+ assert_perror (err);
+
+ /* Should have never returned. Our parent expects us to fail
+ thus we succeed and indicate the error. */
+ return 0;
+ }
+
+ default:
+ {
+ pid_t pid;
+ int status;
+
+ pid = waitpid (child, &status, 0);
+ printf ("pid = %d; child = %d; status = %d\n", pid, child, status);
+ assert (pid == child);
+ assert (status != 0);
+ }
+ }
+
+ return 0;
+}
diff --git a/libpthread/tests/test-6.c b/libpthread/tests/test-6.c
new file mode 100644
index 00000000..98aa8ba7
--- /dev/null
+++ b/libpthread/tests/test-6.c
@@ -0,0 +1,95 @@
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 500
+#define WAITS 3
+
+void *
+dowait (void *arg)
+{
+ pthread_barrier_t *barrier = arg;
+ int ret;
+
+ ret = pthread_barrier_wait (barrier);
+ printf ("%d ", pthread_self ());
+ return (void *) ret;
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_barrierattr_t attr;
+ pthread_barrier_t barrier;
+
+ int i, j;
+ error_t err;
+ pthread_t tid[THREADS];
+
+ int havesyncs;
+
+ err = pthread_barrierattr_init (&attr);
+ if (err)
+ error (1, err, "pthread_barrierattr_init");
+
+ err = pthread_barrierattr_getpshared (&attr, &i);
+ if (err)
+ error (1, err, "pthread_barrierattr_getpshared");
+ assert (i == PTHREAD_PROCESS_PRIVATE || i == PTHREAD_PROCESS_SHARED);
+
+ err = pthread_barrierattr_setpshared (&attr, PTHREAD_PROCESS_PRIVATE);
+ if (err)
+ error (1, err, "pthread_barrierattr_setpshared");
+
+ err = pthread_barrier_init (&barrier, &attr, THREADS + 1);
+ if (err)
+ error (1, err, "pthread_barrier_init");
+
+ for (j = 0; j < WAITS; j ++)
+ {
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ err = pthread_create (&tid[i], 0, dowait, &barrier);
+ if (err)
+ error (1, err, "pthread_create (%d)", i);
+ }
+
+ printf ("Manager will now call pthread_barrier_wait.\n");
+
+ havesyncs
+ = pthread_barrier_wait (&barrier) == PTHREAD_BARRIER_SERIAL_THREAD
+ ? 1 : 0;
+
+ for (i = THREADS - 1; i >= 0; i --)
+ {
+ void *ret;
+ err = pthread_join (tid[i], &ret);
+ if (err)
+ error (1, err, "pthread_join");
+
+ switch ((int) ret)
+ {
+ case 0:
+ break;
+
+ case PTHREAD_BARRIER_SERIAL_THREAD:
+ havesyncs ++;
+ break;
+
+ default:
+ assert (! "Unknown value returned from pthread_barrier_wait.");
+ break;
+ }
+ }
+
+ printf ("\n");
+
+ assert (havesyncs == 1);
+ }
+
+ return 0;
+}
diff --git a/libpthread/tests/test-7.c b/libpthread/tests/test-7.c
new file mode 100644
index 00000000..bd97acfa
--- /dev/null
+++ b/libpthread/tests/test-7.c
@@ -0,0 +1,66 @@
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 10
+#define KEYS 400
+
+pthread_key_t key[KEYS];
+
+void *
+thr (void *arg)
+{
+ error_t err;
+ int i;
+
+ for (i = 0; i < KEYS; i ++)
+ {
+ printf ("pthread_getspecific(%d).\n", key[i]);
+ assert (pthread_getspecific (key[i]) == NULL);
+ printf ("pthread_setspecific(%d, %d).\n", key[i], pthread_self ());
+ err = pthread_setspecific (key[i], (void *) pthread_self ());
+ printf ("pthread_setspecific(%d, %d) => %d.\n", key[i], pthread_self (), err);
+ assert_perror (err);
+ }
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ int i;
+ pthread_t tid[THREADS];
+
+ void des (void *val)
+ {
+ assert ((pthread_t) val == pthread_self ());
+ }
+
+ for (i = 0; i < KEYS; i ++)
+ err = pthread_key_create (&key[i], des);
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ err = pthread_create (&tid[i], 0, thr, 0);
+ if (err)
+ error (1, err, "pthread_create (%d)", i);
+ }
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ void *ret;
+
+ err = pthread_join (tid[i], &ret);
+ if (err)
+ error (1, err, "pthread_join");
+
+ assert (ret == 0);
+ }
+
+ return 0;
+}
diff --git a/libpthread/tests/test-8.c b/libpthread/tests/test-8.c
new file mode 100644
index 00000000..85a7f8f6
--- /dev/null
+++ b/libpthread/tests/test-8.c
@@ -0,0 +1,60 @@
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 10
+
+pthread_once_t inc_var_once = PTHREAD_ONCE_INIT;
+int var;
+
+void
+inc_var (void)
+{
+ var ++;
+}
+
+void *
+thr (void *arg)
+{
+ int i;
+
+ for (i = 0; i < 500; i ++)
+ pthread_once (&inc_var_once, inc_var);
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ int i;
+ pthread_t tid[THREADS];
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ err = pthread_create (&tid[i], 0, thr, 0);
+ if (err)
+ error (1, err, "pthread_create (%d)", i);
+ }
+
+ assert (thr (0) == 0);
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ void *ret;
+
+ err = pthread_join (tid[i], &ret);
+ if (err)
+ error (1, err, "pthread_join");
+
+ assert (ret == 0);
+ }
+
+ assert (var == 1);
+
+ return 0;
+}
diff --git a/libpthread/tests/test-9.c b/libpthread/tests/test-9.c
new file mode 100644
index 00000000..82051570
--- /dev/null
+++ b/libpthread/tests/test-9.c
@@ -0,0 +1,88 @@
+/* Test recursive mutexes. */
+
+#define _GNU_SOURCE
+
+#include <pthread.h>
+#include <assert.h>
+#include <error.h>
+#include <errno.h>
+
+#define THREADS 10
+
+int foo;
+
+void *
+thr (void *arg)
+{
+ int i;
+
+ pthread_mutex_lock (arg);
+
+ foo = pthread_self ();
+
+ for (i = 0; i < 500; i ++)
+ pthread_mutex_lock (arg);
+ for (i = 0; i < 500; i ++)
+ pthread_mutex_unlock (arg);
+
+ assert (foo == pthread_self ());
+
+ pthread_mutex_unlock (arg);
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ int i;
+ pthread_t tid[THREADS];
+ pthread_mutexattr_t mattr;
+ pthread_mutex_t mutex;
+
+ err = pthread_mutexattr_init (&mattr);
+ if (err)
+ error (1, err, "pthread_mutexattr_init");
+
+ err = pthread_mutexattr_settype (&mattr, PTHREAD_MUTEX_RECURSIVE);
+ if (err)
+ error (1, err, "pthread_mutexattr_settype");
+
+ err = pthread_mutex_init (&mutex, &mattr);
+ if (err)
+ error (1, err, "pthread_mutex_init");
+
+ err = pthread_mutexattr_destroy (&mattr);
+ if (err)
+ error (1, err, "pthread_mutexattr_destroy");
+
+ pthread_mutex_lock (&mutex);
+ pthread_mutex_lock (&mutex);
+ pthread_mutex_unlock (&mutex);
+ pthread_mutex_unlock (&mutex);
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ err = pthread_create (&tid[i], 0, thr, &mutex);
+ if (err)
+ error (1, err, "pthread_create (%d)", i);
+ }
+
+ for (i = 0; i < THREADS; i ++)
+ {
+ void *ret;
+
+ err = pthread_join (tid[i], &ret);
+ if (err)
+ error (1, err, "pthread_join");
+
+ assert (ret == 0);
+ }
+
+ err = pthread_mutex_destroy (&mutex);
+ if (err)
+ error (1, err, "pthread_mutex_destroy");
+
+ return 0;
+}