diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2012-02-21 13:02:29 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2012-02-21 13:02:29 +0000 |
commit | f1c78082272506eab8d00ca115290ca09b91c557 (patch) | |
tree | d9cae64e2975bc8c730af0b3a6acf66e558a71e1 /regress/lib | |
parent | 75af4f7077e00a3d4154887b6dcc7ff4155f0dfa (diff) |
Add pthread_suspend_np regress test. okay guenther@
Diffstat (limited to 'regress/lib')
-rw-r--r-- | regress/lib/libpthread/Makefile | 4 | ||||
-rw-r--r-- | regress/lib/libpthread/suspend_np1/Makefile | 5 | ||||
-rw-r--r-- | regress/lib/libpthread/suspend_np1/suspend_np1.c | 110 |
3 files changed, 117 insertions, 2 deletions
diff --git a/regress/lib/libpthread/Makefile b/regress/lib/libpthread/Makefile index 6de410e5d46..6d53ca8d929 100644 --- a/regress/lib/libpthread/Makefile +++ b/regress/lib/libpthread/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.34 2012/02/20 17:06:11 kurt Exp $ +# $OpenBSD: Makefile,v 1.35 2012/02/21 13:02:28 kurt Exp $ # disabled because it requires a buggy behavior that uthread had: # dup2_race @@ -11,7 +11,7 @@ SUBDIR= blocked_close blocked_dup2 blocked_shutdown cancel cancel2 \ pthread_rwlock pthread_specific \ readdir restart select semaphore setjmp setsockopt sigdeliver siginfo \ siginterrupt signal signals signodefer sigsuspend sigwait sleep \ - socket stack stdarg stdio switch system + socket stack stdarg stdio suspend_np1 switch system # Not available or disabled: fcntl, getaddrinfo, pause, pw, sigmask, stdfiles diff --git a/regress/lib/libpthread/suspend_np1/Makefile b/regress/lib/libpthread/suspend_np1/Makefile new file mode 100644 index 00000000000..af404aa7f7d --- /dev/null +++ b/regress/lib/libpthread/suspend_np1/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2012/02/21 13:02:28 kurt Exp $ + +PROG= suspend_np1 + +.include <bsd.regress.mk> diff --git a/regress/lib/libpthread/suspend_np1/suspend_np1.c b/regress/lib/libpthread/suspend_np1/suspend_np1.c new file mode 100644 index 00000000000..2b5e1704d95 --- /dev/null +++ b/regress/lib/libpthread/suspend_np1/suspend_np1.c @@ -0,0 +1,110 @@ +/* $OpenBSD: suspend_np1.c,v 1.1 2012/02/21 13:02:28 kurt Exp $ */ +/* + * Copyright (c) 2012 Kurt Miller <kurt@intricatesoftware.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Test pthread_suspend_np(). + */ + +#include <pthread.h> +#include <unistd.h> +#include <fcntl.h> +#include <time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "test.h" + +#define BUSY_THREADS 5 + +volatile int done = 0; +volatile int counter[BUSY_THREADS] = { 0, 0, 0, 0, 0 }; + +static void * +deadlock_detector(void *arg) +{ + struct timespec rqtp; + rqtp.tv_sec = 15; + rqtp.tv_nsec = 0; + + while (nanosleep(&rqtp, &rqtp) == -1 && errno == EINTR); + PANIC("deadlock detected"); +} + +static void * +busy_thread(void *arg) +{ + int i = (int)arg; + struct timespec rqtp; + rqtp.tv_sec = 0; + rqtp.tv_nsec = 1000000; + + while (!done) { + counter[i]++; + nanosleep(&rqtp, NULL); + } + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + pthread_t busy_threads[BUSY_THREADS]; + int saved_counter[BUSY_THREADS]; + pthread_t deadlock_thread; + int i; + void *value_ptr; + struct timespec rqtp; + + rqtp.tv_sec = 0; + rqtp.tv_nsec = 100 * 1000000; + + CHECKr(pthread_create(&deadlock_thread, NULL, + deadlock_detector, NULL)); + + for (i = 0; i < BUSY_THREADS; i++) + CHECKr(pthread_create(&busy_threads[i], NULL, + busy_thread, (void *)i)); + + /* sleep to ensure threads have time to start and run */ + nanosleep(&rqtp, NULL); + + /* stop and save counters */ + pthread_suspend_all_np(); + for (i = 0; i < BUSY_THREADS; i++) + saved_counter[i] = counter[i]; + + /* sleep and check counters have not moved */ + nanosleep(&rqtp, NULL); + for (i = 0; i < BUSY_THREADS; i++) + ASSERT(saved_counter[i] == counter[i]); + + /* resume all and check counters are moving again */ + pthread_resume_all_np(); + nanosleep(&rqtp, NULL); + for (i = 0; i < BUSY_THREADS; i++) + ASSERT(saved_counter[i] != counter[i]); + + done = 1; + + for (i = 0; i < BUSY_THREADS; i++) { + CHECKr(pthread_join(busy_threads[i], &value_ptr)); + ASSERT(value_ptr == NULL); + } + + SUCCEED; +} |