aboutsummaryrefslogtreecommitdiff
path: root/tools/test/stress2/misc/mprotect5.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tools/test/stress2/misc/mprotect5.sh')
-rwxr-xr-xtools/test/stress2/misc/mprotect5.sh118
1 files changed, 118 insertions, 0 deletions
diff --git a/tools/test/stress2/misc/mprotect5.sh b/tools/test/stress2/misc/mprotect5.sh
new file mode 100755
index 000000000000..ab4d2eeee118
--- /dev/null
+++ b/tools/test/stress2/misc/mprotect5.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+/* N writers threaded test scenario */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <err.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static pthread_mutex_t write_mutex;
+static int go, n, ps;
+static char *cp, *wp;
+
+void *
+wr(void *arg __unused)
+{
+ while (go == 0)
+ usleep(100);
+ while (go == 1) {
+ pthread_mutex_lock(&write_mutex);
+ if (wp != NULL)
+ *wp += 1;
+ pthread_mutex_unlock(&write_mutex);
+ }
+ return(NULL);
+}
+
+void
+usage(char *prog) {
+ fprintf(stderr, "Usage: %s <number of threads>\n", prog);
+ _exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t *tid;
+ time_t start;
+ int e, i, nb;
+
+ if (argc != 2)
+ usage(argv[0]);
+ if (sscanf(argv[1], "%d", &n) != 1)
+ usage(argv[0]);
+ if (n > 1)
+ n--;
+ if ((tid = calloc(n, sizeof(pthread_t *))) == NULL)
+ err(1, "calloc()");
+
+ ps = getpagesize();
+ cp = mmap(NULL, n * ps, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
+ pthread_mutex_init(&write_mutex, NULL);
+ pthread_mutex_lock(&write_mutex);
+ go = 0;
+ for (i = 0; i < n; i++) {
+ if ((e = pthread_create(&tid[i], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create()");
+ }
+ go = 1;
+
+ nb = 0;
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
+ for (i = 0; i < n; i += ps) {
+ pthread_mutex_lock(&write_mutex);
+ if (mprotect(&cp[i], ps, PROT_READ|PROT_WRITE) == -1)
+ err(1, "mprotect(PROT_READ)");
+ cp[i] = 0;
+ wp = &cp[i];
+ pthread_mutex_unlock(&write_mutex);
+
+ usleep(100);
+
+ pthread_mutex_lock(&write_mutex);
+ if (mprotect(&cp[i], ps, PROT_READ) == -1)
+ err(1, "mprotect(PROT_READ)");
+ wp = NULL;
+ pthread_mutex_unlock(&write_mutex);
+ nb++;
+ }
+ }
+ go = 0;
+ for (i = 0; i < n; i++) {
+ if ((e = pthread_join(tid[i], NULL)) != 0)
+ errc(1, e, "pthread_join() in loop %d", i);
+ }
+ if (nb >= 0) {
+#if defined(DEBUG)
+ fprintf(stderr, "%d loops\n", nb);
+#endif
+ ;
+ }
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+/tmp/$prog `sysctl -n hw.ncpu`; s=$?
+
+rm -d /tmp/$prog /tmp/$prog.c
+exit $s