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