xref: /freebsd/tools/test/stress2/misc/mprotect6.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#include <sys/types.h>
14*ef777be9SPeter Holm#include <sys/mman.h>
15*ef777be9SPeter Holm
16*ef777be9SPeter Holm#include <assert.h>
17*ef777be9SPeter Holm#include <err.h>
18*ef777be9SPeter Holm#include <pthread.h>
19*ef777be9SPeter Holm#include <signal.h>
20*ef777be9SPeter Holm#include <stdio.h>
21*ef777be9SPeter Holm#include <stdlib.h>
22*ef777be9SPeter Holm#include <string.h>
23*ef777be9SPeter Holm#include <time.h>
24*ef777be9SPeter Holm#include <unistd.h>
25*ef777be9SPeter Holm
26*ef777be9SPeter Holmstatic pthread_mutex_t write_mutex;
27*ef777be9SPeter Holmstatic volatile int done;
28*ef777be9SPeter Holmstatic int go, n, *once, *p, ps;
29*ef777be9SPeter Holm
30*ef777be9SPeter Holmstatic void *
31*ef777be9SPeter Holmwr(void *arg)
32*ef777be9SPeter Holm{
33*ef777be9SPeter Holm	int idx;
34*ef777be9SPeter Holm
35*ef777be9SPeter Holm	alarm(180);
36*ef777be9SPeter Holm	idx = *(int *)arg;
37*ef777be9SPeter Holm	while (go == 0)
38*ef777be9SPeter Holm		usleep(100);
39*ef777be9SPeter Holm	while (go == 1) {
40*ef777be9SPeter Holm		while (go == 1 && once[idx] == 0)
41*ef777be9SPeter Holm			usleep(100);
42*ef777be9SPeter Holm		if (go == 0)
43*ef777be9SPeter Holm			break;
44*ef777be9SPeter Holm		p[idx]++;
45*ef777be9SPeter Holm		once[idx] = 0;
46*ef777be9SPeter Holm		pthread_mutex_lock(&write_mutex);
47*ef777be9SPeter Holm		done++;
48*ef777be9SPeter Holm		pthread_mutex_unlock(&write_mutex);
49*ef777be9SPeter Holm	}
50*ef777be9SPeter Holm	return(NULL);
51*ef777be9SPeter Holm}
52*ef777be9SPeter Holm
53*ef777be9SPeter Holmstatic void
54*ef777be9SPeter Holmsetonce(int val)
55*ef777be9SPeter Holm{
56*ef777be9SPeter Holm	int i;
57*ef777be9SPeter Holm
58*ef777be9SPeter Holm	for (i = 0; i < n; i++)
59*ef777be9SPeter Holm		once[i] = val;
60*ef777be9SPeter Holm}
61*ef777be9SPeter Holm
62*ef777be9SPeter Holmstatic void
63*ef777be9SPeter Holmusage(char *prog) {
64*ef777be9SPeter Holm	fprintf(stderr, "Usage: %s <number of threads>\n", prog);
65*ef777be9SPeter Holm	_exit(1);
66*ef777be9SPeter Holm}
67*ef777be9SPeter Holm
68*ef777be9SPeter Holmint
69*ef777be9SPeter Holmmain(int argc, char *argv[])
70*ef777be9SPeter Holm{
71*ef777be9SPeter Holm	pthread_t *tid;
72*ef777be9SPeter Holm	time_t start;
73*ef777be9SPeter Holm	int *arg;
74*ef777be9SPeter Holm	int e, i, nb, r;
75*ef777be9SPeter Holm
76*ef777be9SPeter Holm	if (argc != 2)
77*ef777be9SPeter Holm		usage(argv[0]);
78*ef777be9SPeter Holm	if (sscanf(argv[1], "%d", &n) != 1)
79*ef777be9SPeter Holm		usage(argv[0]);
80*ef777be9SPeter Holm	if (n > 1)
81*ef777be9SPeter Holm		n--;
82*ef777be9SPeter Holm	if ((tid = calloc(n, sizeof(pthread_t *))) == NULL)
83*ef777be9SPeter Holm		err(1, "calloc()");
84*ef777be9SPeter Holm	if ((once = calloc(n, sizeof(int *))) == NULL)
85*ef777be9SPeter Holm		err(1, "calloc()");
86*ef777be9SPeter Holm	setonce(0);
87*ef777be9SPeter Holm
88*ef777be9SPeter Holm	ps = getpagesize();
89*ef777be9SPeter Holm	p = mmap(NULL, n * ps, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
90*ef777be9SPeter Holm	go = 0;
91*ef777be9SPeter Holm	pthread_mutex_init(&write_mutex, NULL);
92*ef777be9SPeter Holm	for (i = 0; i < n; i++) {
93*ef777be9SPeter Holm		arg = malloc(sizeof(int));
94*ef777be9SPeter Holm		*arg = i;
95*ef777be9SPeter Holm		if ((e = pthread_create(&tid[i], NULL, wr, (void *)arg)) != 0)
96*ef777be9SPeter Holm			errc(1, e, "pthread_create()");
97*ef777be9SPeter Holm	}
98*ef777be9SPeter Holm	go = 1;
99*ef777be9SPeter Holm
100*ef777be9SPeter Holm	nb = 0;
101*ef777be9SPeter Holm	start = time(NULL);
102*ef777be9SPeter Holm	while (time(NULL) - start < 120) {
103*ef777be9SPeter Holm		if (mprotect(p, n * ps, PROT_READ|PROT_WRITE) == -1)
104*ef777be9SPeter Holm			err(1, "mprotect(PROT_READ)");
105*ef777be9SPeter Holm		done = 0;
106*ef777be9SPeter Holm		setonce(1);
107*ef777be9SPeter Holm		while (done != n)
108*ef777be9SPeter Holm			usleep(100);
109*ef777be9SPeter Holm		if (mprotect(p, n * ps, PROT_READ) == -1)
110*ef777be9SPeter Holm			err(1, "mprotect(PROT_READ)");
111*ef777be9SPeter Holm		nb++;
112*ef777be9SPeter Holm		usleep(100);
113*ef777be9SPeter Holm	}
114*ef777be9SPeter Holm	go = 0;
115*ef777be9SPeter Holm	for (i = 0; i < n; i++) {
116*ef777be9SPeter Holm		if ((e = pthread_join(tid[i], NULL)) != 0)
117*ef777be9SPeter Holm			errc(1, e, "pthread_join() in loop %d", i);
118*ef777be9SPeter Holm	}
119*ef777be9SPeter Holm	r = 0;
120*ef777be9SPeter Holm	for (i = 1; i < n; i++) {
121*ef777be9SPeter Holm		if (p[0] != p[i])
122*ef777be9SPeter Holm			r++;
123*ef777be9SPeter Holm	}
124*ef777be9SPeter Holm	if (r != 0) {
125*ef777be9SPeter Holm		fprintf(stderr, "%d loops.\n", nb);
126*ef777be9SPeter Holm		for (i = 0; i < n; i++)
127*ef777be9SPeter Holm			fprintf(stderr, "p[%3d] = %d\n", i, p[i]);
128*ef777be9SPeter Holm	}
129*ef777be9SPeter Holm
130*ef777be9SPeter Holm	return (r);
131*ef777be9SPeter Holm}
132*ef777be9SPeter HolmEOF
133*ef777be9SPeter Holmmycc -o /tmp/$prog -Wall -Wextra -O0 -g /tmp/$prog.c -lpthread || exit 1
134*ef777be9SPeter Holm
135*ef777be9SPeter Holmn=`sysctl -n hw.ncpu`
136*ef777be9SPeter Holmif [ $# -eq 1 ]; then
137*ef777be9SPeter Holm	echo $1 | grep -Eq '^[0-9]+$' && n=$1
138*ef777be9SPeter Holmfi
139*ef777be9SPeter Holm../testcases/swap/swap -t 2m > /dev/null &
140*ef777be9SPeter Holmsleep 10
141*ef777be9SPeter Holm/tmp/$prog $n; s=$?
142*ef777be9SPeter Holmpkill -9 swap
143*ef777be9SPeter Holmwait
144*ef777be9SPeter Holm
145*ef777be9SPeter Holmrm -d /tmp/$prog /tmp/$prog.c
146*ef777be9SPeter Holmexit $s
147