summaryrefslogtreecommitdiff
path: root/regress/lib
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2012-02-21 13:02:29 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2012-02-21 13:02:29 +0000
commitf1c78082272506eab8d00ca115290ca09b91c557 (patch)
treed9cae64e2975bc8c730af0b3a6acf66e558a71e1 /regress/lib
parent75af4f7077e00a3d4154887b6dcc7ff4155f0dfa (diff)
Add pthread_suspend_np regress test. okay guenther@
Diffstat (limited to 'regress/lib')
-rw-r--r--regress/lib/libpthread/Makefile4
-rw-r--r--regress/lib/libpthread/suspend_np1/Makefile5
-rw-r--r--regress/lib/libpthread/suspend_np1/suspend_np1.c110
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;
+}