1#include <stdio.h>
2#include "tests/sys_mman.h"
3#include <stdlib.h>
4#include <unistd.h>
5
6static unsigned int pagesize;
7
8#define PAGES	1024u
9#define LEN	(PAGES*pagesize)
10
11static void *domap(void)
12{
13	void *ret = mmap(0, LEN, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
14
15	if (ret == (void *)-1) {
16		perror("mmap");
17		exit(1);
18	}
19
20	return ret;
21}
22
23/* unmap in pieces to exercise munmap more */
24static void nibblemap(void *p)
25{
26	int off;
27	int i;
28
29	off = (random() % LEN) & ~(pagesize-1);
30
31	for(i = 0; i < PAGES; i++) {
32		/* printf("unmapping off=%d\n", off/pagesize); */
33		munmap((char *)p + off, pagesize);
34		off += 619*pagesize;
35		off %= LEN;
36	}
37}
38
39static void prmaps()
40{
41	char buf[100];
42	sprintf(buf, "/bin/cat /proc/%d/maps", getpid());
43	system(buf);
44	exit(1);
45}
46
47int main()
48{
49	int i;
50	void *expect1, *expect2;
51
52	pagesize = getpagesize();
53
54	expect1 = domap();
55	expect2 = domap();
56	munmap(expect1, LEN);
57	munmap(expect2, LEN);
58
59	for(i = 0; i < 5; i++) {
60		void *m1, *m2;
61
62		m1 = domap();
63		if (m1 != expect1) {
64			printf("FAIL i=%d: m1=%p expect1=%p\n",
65			       i, m1, expect1);
66			prmaps();
67			return 1;
68		}
69		m2 = domap();
70		if (m2 != expect2) {
71			printf("FAIL i=%d: m2=%p expect2=%p\n",
72			       i, m2, expect2);
73			prmaps();
74			return 1;
75		}
76		nibblemap(m2);
77		munmap(m1, LEN);
78	}
79
80	printf("PASS\n");
81	return 0;
82}
83