xref: /dragonfly/test/stress/stress2/misc/mmap3.sh (revision c37c9ab3)
1#!/bin/sh
2
3#
4# Copyright (c) 2009 Peter Holm <pho@FreeBSD.org>
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28# $FreeBSD$
29#
30
31# Variation of mmap2.sh with focus on random arguments for mprotect()
32
33odir=`pwd`
34cd /tmp
35sed '1,/^EOF/d' < $odir/$0 > mmap3.c
36cc -o mmap3 -Wall mmap3.c -lpthread
37rm -f mmap3.c
38
39for i in `jot 20`; do
40	./mmap3
41done
42for i in `jot 100`; do
43	./mmap3 random
44done
45rm -f mmap3 mmap3.core /tmp/mmap.0*
46exit
47
48EOF
49/*
50   Stress mmap by having max 18 threads mapping random areas within
51   a 100 Mb range.
52 */
53#include <sys/types.h>
54#include <err.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include <unistd.h>
58#include <fcntl.h>
59#include <pthread.h>
60#include <sys/mman.h>
61#include <sys/param.h>
62#include <string.h>
63#include <unistd.h>
64#include <errno.h>
65
66#define THREADS 100
67#define STARTADDR 0x50000000U
68#define ADRSPACE  0x06400000U /* 100 Mb */
69
70static int
71ra;
72
73void
74trash(void *p)
75{
76	mprotect(p, 0x570e3d38, 0x2c8fd54f);
77
78	if (ra) {
79		madvise((void *)arc4random(), arc4random(), arc4random());
80		mprotect((void *)arc4random(), arc4random(), arc4random());
81		msync((void *)arc4random(), arc4random(), arc4random());
82	}
83
84}
85
86void
87work(int nr)
88{
89	int fd, m;
90	void *p;
91	size_t len;
92	char path[128];
93
94	p = (void *)STARTADDR;
95	len = ADRSPACE;
96
97	sprintf(path, "/tmp/mmap.%06d.%04d", getpid(), nr);
98	if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1)
99		err(1,"open()");
100	if (ftruncate(fd, len) == -1)
101		err(1, "ftruncate");
102	if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) ==
103			MAP_FAILED) {
104		if (errno == ENOMEM)
105			return;
106		err(1, "mmap()");
107	}
108	if (unlink(path) == -1)
109		err(1, "unlink(%s)", path);
110
111	trash(p);
112
113	m = arc4random() % 10;
114	if (madvise(p, len, m) == -1)
115		warn("madvise(%p, %d, %d)", p, len, m);
116	if (mprotect(p, trunc_page(arc4random() % len), PROT_READ) == -1 )
117		err(1, "mprotect failed with error:");
118	if (msync(p, 0, MS_SYNC) == -1)
119		err(1, "msync(%p)", p);
120	if (munmap(p, len) == -1)
121		err(1, "munmap(%p)", p);
122	close(fd);
123}
124
125void *
126thr(void *arg)
127{
128	int i;
129
130	for (i = 0; i < 512; i++) {
131		work(*(int *)arg);
132	}
133	return (0);
134}
135
136int
137main(int argc, char **argv)
138{
139	pthread_t threads[THREADS];
140	int nr[THREADS];
141	int i, n, r;
142
143	n  = arc4random() % 14 + 5;
144	ra = argc != 1;
145//	printf("Address start 0x%x, address end 0x%x, pages %d, n %d\n",
146//		STARTADDR, STARTADDR + ADRSPACE, ADRSPACE>>PAGE_SHIFT, n);
147	for (i = 0; i < n; i++) {
148		nr[i] = i;
149		if ((r = pthread_create(&threads[i], NULL, thr, (void *)&nr[i])) != 0)
150			err(1, "pthread_create(): %s\n", strerror(r));
151	}
152
153	for (i = 0; i < n; i++) {
154		if (pthread_join(threads[i], NULL) != 0)
155			err(1, "pthread_join(%d)", i);
156	}
157
158	return (0);
159}
160