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 readers and 1 writer 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 int go, n, ps; 29*ef777be9SPeter Holmstatic char *cp; 30*ef777be9SPeter Holmstatic volatile char v; 31*ef777be9SPeter Holm 32*ef777be9SPeter Holmvoid * 33*ef777be9SPeter Holmrd(void *arg __unused) 34*ef777be9SPeter Holm{ 35*ef777be9SPeter Holm int i; 36*ef777be9SPeter Holm 37*ef777be9SPeter Holm while (go == 0) 38*ef777be9SPeter Holm usleep(100); 39*ef777be9SPeter Holm while (go == 1) { 40*ef777be9SPeter Holm for (i = 0; i < n; i += ps) { 41*ef777be9SPeter Holm v = cp[i]; 42*ef777be9SPeter Holm } 43*ef777be9SPeter Holm pthread_yield(); 44*ef777be9SPeter Holm } 45*ef777be9SPeter Holm return(NULL); 46*ef777be9SPeter Holm} 47*ef777be9SPeter Holm 48*ef777be9SPeter Holmvoid 49*ef777be9SPeter Holmusage(char *prog) { 50*ef777be9SPeter Holm fprintf(stderr, "Usage: %s <number of threads>\n", prog); 51*ef777be9SPeter Holm _exit(1); 52*ef777be9SPeter Holm} 53*ef777be9SPeter Holm 54*ef777be9SPeter Holmint 55*ef777be9SPeter Holmmain(int argc, char *argv[]) 56*ef777be9SPeter Holm{ 57*ef777be9SPeter Holm pthread_t *tid; 58*ef777be9SPeter Holm time_t start; 59*ef777be9SPeter Holm int e, i, nb; 60*ef777be9SPeter Holm 61*ef777be9SPeter Holm if (argc != 2) 62*ef777be9SPeter Holm usage(argv[0]); 63*ef777be9SPeter Holm if (sscanf(argv[1], "%d", &n) != 1) 64*ef777be9SPeter Holm usage(argv[0]); 65*ef777be9SPeter Holm if (n > 1) 66*ef777be9SPeter Holm n--; 67*ef777be9SPeter Holm if ((tid = calloc(n, sizeof(pthread_t *))) == NULL) 68*ef777be9SPeter Holm err(1, "calloc()"); 69*ef777be9SPeter Holm 70*ef777be9SPeter Holm ps = getpagesize(); 71*ef777be9SPeter Holm cp = mmap(NULL, n * ps, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0); 72*ef777be9SPeter Holm go = 0; 73*ef777be9SPeter Holm for (i = 0; i < n; i++) { 74*ef777be9SPeter Holm if ((e = pthread_create(&tid[i], NULL, rd, 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 if (mprotect(&cp[i], ps, PROT_READ|PROT_WRITE) == -1) 84*ef777be9SPeter Holm err(1, "mprotect(PROT_READ)"); 85*ef777be9SPeter Holm cp[i] = 1; 86*ef777be9SPeter Holm if (mprotect(&cp[i], ps, PROT_READ) == -1) 87*ef777be9SPeter Holm err(1, "mprotect(PROT_READ)"); 88*ef777be9SPeter Holm nb++; 89*ef777be9SPeter Holm } 90*ef777be9SPeter Holm } 91*ef777be9SPeter Holm go = 0; 92*ef777be9SPeter Holm for (i = 0; i < n; i++) { 93*ef777be9SPeter Holm if ((e = pthread_join(tid[i], NULL)) != 0) 94*ef777be9SPeter Holm errc(1, e, "pthread_join() in loop %d", i); 95*ef777be9SPeter Holm } 96*ef777be9SPeter Holm if (nb >= 0) { 97*ef777be9SPeter Holm#if defined(DEBUG) 98*ef777be9SPeter Holm fprintf(stderr, "%d loops\n", nb); 99*ef777be9SPeter Holm#endif 100*ef777be9SPeter Holm ; 101*ef777be9SPeter Holm } 102*ef777be9SPeter Holm} 103*ef777be9SPeter HolmEOF 104*ef777be9SPeter Holmmycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1 105*ef777be9SPeter Holm 106*ef777be9SPeter Holm/tmp/$prog `sysctl -n hw.ncpu`; s=$? 107*ef777be9SPeter Holm 108*ef777be9SPeter Holmrm -d /tmp/$prog /tmp/$prog.c 109*ef777be9SPeter Holmexit $s 110