xref: /freebsd/tools/test/stress2/misc/mprotect5.sh (revision ee3960cba1068e12fb032a68c46d74841d9edab3)
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 writers 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 pthread_mutex_t write_mutex;
29static int go, n, ps;
30static char *cp, *wp;
31
32void *
33wr(void *arg __unused)
34{
35	while (go == 0)
36		usleep(100);
37	while (go == 1) {
38		pthread_mutex_lock(&write_mutex);
39		if (wp != NULL)
40			*wp += 1;
41		pthread_mutex_unlock(&write_mutex);
42	}
43	return(NULL);
44}
45
46void
47usage(char *prog) {
48	fprintf(stderr, "Usage: %s <number of threads>\n", prog);
49	_exit(1);
50}
51
52int
53main(int argc, char *argv[])
54{
55	pthread_t *tid;
56	time_t start;
57	int e, i, nb;
58
59	if (argc != 2)
60		usage(argv[0]);
61	if (sscanf(argv[1], "%d", &n) != 1)
62		usage(argv[0]);
63	if (n > 1)
64		n--;
65	if ((tid = calloc(n, sizeof(pthread_t *))) == NULL)
66		err(1, "calloc()");
67
68	ps = getpagesize();
69	cp = mmap(NULL, n * ps, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
70	pthread_mutex_init(&write_mutex, NULL);
71	pthread_mutex_lock(&write_mutex);
72	go = 0;
73	for (i = 0; i < n; i++) {
74		if ((e = pthread_create(&tid[i], NULL, wr, 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			pthread_mutex_lock(&write_mutex);
84			if (mprotect(&cp[i], ps, PROT_READ|PROT_WRITE) == -1)
85				err(1, "mprotect(PROT_READ)");
86			cp[i] = 0;
87			wp = &cp[i];
88			pthread_mutex_unlock(&write_mutex);
89
90			usleep(100);
91
92			pthread_mutex_lock(&write_mutex);
93			if (mprotect(&cp[i], ps, PROT_READ) == -1)
94				err(1, "mprotect(PROT_READ)");
95			wp = NULL;
96			pthread_mutex_unlock(&write_mutex);
97			nb++;
98		}
99	}
100	go = 0;
101	for (i = 0; i < n; i++) {
102		if ((e = pthread_join(tid[i], NULL)) != 0)
103			errc(1, e, "pthread_join() in loop %d", i);
104	}
105	if (nb >= 0) {
106#if defined(DEBUG)
107		fprintf(stderr, "%d loops\n", nb);
108#endif
109		;
110	}
111}
112EOF
113mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
114
115/tmp/$prog `sysctl -n hw.ncpu`; s=$?
116
117rm -d /tmp/$prog /tmp/$prog.c
118exit $s
119