xref: /freebsd/tools/test/stress2/misc/mprotect4.sh (revision ef777be98543f7daae90bd123d4fc1ec4a54efc2)
1#!/bin/sh
2
3#
4# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
5#
6# SPDX-License-Identifier: BSD-2-Clause
7#
8
9. ../default.cfg
10set -u
11prog=$(basename "$0" .sh)
12cat > /tmp/$prog.c <<EOF
13/* N readers and 1 writer threaded test scenario */
14
15#include <sys/types.h>
16#include <sys/mman.h>
17
18#include <assert.h>
19#include <err.h>
20#include <pthread.h>
21#include <signal.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <time.h>
26#include <unistd.h>
27
28static int go, n, ps;
29static char *cp;
30static volatile char v;
31
32void *
33rd(void *arg __unused)
34{
35	int i;
36
37	while (go == 0)
38		usleep(100);
39	while (go == 1) {
40		for (i = 0; i < n; i += ps) {
41			v = cp[i];
42		}
43		pthread_yield();
44	}
45	return(NULL);
46}
47
48void
49usage(char *prog) {
50	fprintf(stderr, "Usage: %s <number of threads>\n", prog);
51	_exit(1);
52}
53
54int
55main(int argc, char *argv[])
56{
57	pthread_t *tid;
58	time_t start;
59	int e, i, nb;
60
61	if (argc != 2)
62		usage(argv[0]);
63	if (sscanf(argv[1], "%d", &n) != 1)
64		usage(argv[0]);
65	if (n > 1)
66		n--;
67	if ((tid = calloc(n, sizeof(pthread_t *))) == NULL)
68		err(1, "calloc()");
69
70	ps = getpagesize();
71	cp = mmap(NULL, n * ps, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
72	go = 0;
73	for (i = 0; i < n; i++) {
74		if ((e = pthread_create(&tid[i], NULL, rd, NULL)) != 0)
75			errc(1, e, "pthread_create()");
76	}
77	go = 1;
78
79	nb = 0;
80	start = time(NULL);
81	while (time(NULL) - start < 120) {
82		for (i = 0; i < n; i += ps) {
83			if (mprotect(&cp[i], ps, PROT_READ|PROT_WRITE) == -1)
84				err(1, "mprotect(PROT_READ)");
85			cp[i] = 1;
86			if (mprotect(&cp[i], ps, PROT_READ) == -1)
87				err(1, "mprotect(PROT_READ)");
88			nb++;
89		}
90	}
91	go = 0;
92	for (i = 0; i < n; i++) {
93		if ((e = pthread_join(tid[i], NULL)) != 0)
94			errc(1, e, "pthread_join() in loop %d", i);
95	}
96	if (nb >= 0) {
97#if defined(DEBUG)
98		fprintf(stderr, "%d loops\n", nb);
99#endif
100		;
101	}
102}
103EOF
104mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
105
106/tmp/$prog `sysctl -n hw.ncpu`; s=$?
107
108rm -d /tmp/$prog /tmp/$prog.c
109exit $s
110