summaryrefslogtreecommitdiff
path: root/regress/sys/kern/mmap2/mmaptest.c
blob: 94cc19c414a8ec0dd302f2cd075c95330a62eb18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*	$OpenBSD: mmaptest.c,v 1.4 2002/09/11 23:41:23 mickey Exp $	*/
/*
 *	Written by Artur Grabowski <art@openbsd.org>, 2001 Public Domain
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <string.h>

#include <sys/types.h>
#include <sys/mman.h>

/*
 * Map the same physical page in two places in memory.
 * Should cause a cache alias on sparc and other VAC architectures.
 */

#define MAGIC "The voices in my head are trying to ignore me."

int
main()
{
	char fname[25] = "/tmp/mmaptestXXXXXXXXXX";
	int page_size;
	int fd;
	char *v1, *v2;

	if ((fd = mkstemp(fname)) < 0)
		err(1, "mkstemp");

	if (remove(fname) < 0)
		err(1, "remove");

	if ((page_size = sysconf(_SC_PAGESIZE)) < 0)
		err(1, "sysconf");

	if (ftruncate(fd, 2 * page_size) < 0)
		err(1, "ftruncate");

	/* map two pages, then map the first page over the second */

	v1 = mmap(NULL, 2 * page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if (v1 == MAP_FAILED)
		err(1, "mmap 1");

	/* No need to unmap, mmap is supposed to do that for us if MAP_FIXED */

	v2 = mmap(v1 + page_size, page_size, PROT_READ|PROT_WRITE,
	    MAP_SHARED|MAP_FIXED, fd, 0);
	if (v2 == MAP_FAILED)
		err(1, "mmap 2");

	memcpy(v1, MAGIC, sizeof(MAGIC));

	if (memcmp(v2, MAGIC, sizeof(MAGIC)) != 0)
		errx(1, "comparsion 1 failed");

	if (memcmp(v1, v2, sizeof(MAGIC)) != 0)
		errx(1, "comparsion 2 failed");

	if (munmap(v1, 2 * page_size) < 0)
		errx(1, "munmap");

	close(fd);

	return 0;
}