diff options
Diffstat (limited to 'libpthread/tests')
-rw-r--r-- | libpthread/tests/.cvsignore | 1 | ||||
-rw-r--r-- | libpthread/tests/Makefile | 29 | ||||
-rw-r--r-- | libpthread/tests/test-1.c | 49 | ||||
-rw-r--r-- | libpthread/tests/test-10.c | 46 | ||||
-rw-r--r-- | libpthread/tests/test-11.c | 143 | ||||
-rw-r--r-- | libpthread/tests/test-12.c | 29 | ||||
-rw-r--r-- | libpthread/tests/test-13.c | 66 | ||||
-rw-r--r-- | libpthread/tests/test-14.c | 44 | ||||
-rw-r--r-- | libpthread/tests/test-15.c | 87 | ||||
-rw-r--r-- | libpthread/tests/test-16.c | 71 | ||||
-rw-r--r-- | libpthread/tests/test-2.c | 39 | ||||
-rw-r--r-- | libpthread/tests/test-3.c | 55 | ||||
-rw-r--r-- | libpthread/tests/test-4.c | 86 | ||||
-rw-r--r-- | libpthread/tests/test-5.c | 75 | ||||
-rw-r--r-- | libpthread/tests/test-6.c | 95 | ||||
-rw-r--r-- | libpthread/tests/test-7.c | 66 | ||||
-rw-r--r-- | libpthread/tests/test-8.c | 60 | ||||
-rw-r--r-- | libpthread/tests/test-9.c | 88 |
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; +} |