aboutsummaryrefslogtreecommitdiff
path: root/tools/test/stress2/misc/umtx_suspend.sh
diff options
context:
space:
mode:
authorPeter Holm <pho@FreeBSD.org>2021-03-03 12:56:56 +0000
committerPeter Holm <pho@FreeBSD.org>2021-03-03 14:11:40 +0000
commit8a272653d9fbd9fc37691c9aad6a05089b4ecb4d (patch)
tree2463ed22a342700cb7ba2b05c3d5370f75090899 /tools/test/stress2/misc/umtx_suspend.sh
parent3adf72a36b9b151eef57e3d83f71a3a9fbacb78d (diff)
downloadsrc-8a272653d9fbd9fc37691c9aad6a05089b4ecb4d.tar.gz
src-8a272653d9fbd9fc37691c9aad6a05089b4ecb4d.zip
Diffstat (limited to 'tools/test/stress2/misc/umtx_suspend.sh')
-rwxr-xr-xtools/test/stress2/misc/umtx_suspend.sh88
1 files changed, 88 insertions, 0 deletions
diff --git a/tools/test/stress2/misc/umtx_suspend.sh b/tools/test/stress2/misc/umtx_suspend.sh
new file mode 100755
index 000000000000..aacc17b2d097
--- /dev/null
+++ b/tools/test/stress2/misc/umtx_suspend.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+# Test scenario from
+# Bug 192918 - [patch] A thread will spin if a signal interrupts umtxq_sleep_pi.
+# by eric@vangyzen.net
+
+. ../default.cfg
+
+here=`pwd`
+cd /tmp
+sed '1,/^EOF/d' < $here/$0 > umtx_suspend.c
+mycc -o umtx_suspend -Wall -Wextra -O0 -g umtx_suspend.c \
+ -lpthread || exit 1
+rm -f umtx_suspend.c
+
+/tmp/umtx_suspend
+
+rm -f /tmp/umtx_suspend
+exit 0
+EOF
+// cc -lpthread -o umtx_suspend umtx_suspend.c
+//
+// failure: a thread spins around "umtxpi" the kernel, ignoring signals
+// success: the process exits
+
+#include <sys/cdefs.h>
+
+#include <err.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include <stdio.h>
+#include <unistd.h>
+
+pthread_mutex_t the_mutex;
+
+void *
+spinning_thread_func(void *arg __unused)
+{
+ int error;
+
+ error = pthread_mutex_lock(&the_mutex);
+ if (error)
+ errc(1, error, "%s: pthread_mutex_lock", __func__);
+
+ return (NULL);
+}
+
+int
+main(int argc __unused, char *argv[] __unused)
+{
+ int error;
+ pthread_t spinning_thread;
+ pthread_mutexattr_t the_mutex_attr;
+
+ error = pthread_mutexattr_init(&the_mutex_attr);
+ if (error)
+ errc(1, error, "pthread_mutexattr_init");
+
+ error = pthread_mutexattr_setprotocol(&the_mutex_attr, PTHREAD_PRIO_INHERIT);
+ if (error)
+ errc(1, error, "pthread_mutexattr_setprotocol");
+
+ error = pthread_mutex_init(&the_mutex, &the_mutex_attr);
+ if (error)
+ errc(1, error, "pthread_mutex_init");
+
+ error = pthread_mutex_lock(&the_mutex);
+ if (error)
+ errc(1, error, "pthread_mutex_lock");
+
+ error = pthread_create(&spinning_thread, NULL, spinning_thread_func, NULL);
+ if (error)
+ errc(1, error, "pthread_create");
+
+ // Wait for the spinning_thread to call pthread_mutex_lock(3)
+ // and enter the kernel.
+ (void) sleep(1);
+
+ error = pthread_suspend_np(spinning_thread);
+ if (error)
+ errc(1, error, "pthread_suspend_np");
+
+ // The spinning_thread should be spinning in the kernel.
+ // This thread should be blocked in pthread_suspend_np(3).
+ fputs("This test failed to reproduce the bug.\n", stderr);
+
+ return (0);
+}