1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/mman.h>
4#include <unistd.h>
5#include <fcntl.h>
6
7/* This program allocates memory with multiple calls to remap. This
8 * can be used to verify if the remap api is working correctly. */
9
10#define PAGE_SHIFT 12
11
12#define ROUND_PAGES(memsize) ((memsize >> (PAGE_SHIFT)) << PAGE_SHIFT)
13
14int main(int argc, char *argv[]) {
15	unsigned int memsize;
16	char *mem;
17	int i, numpages, fd;
18
19	if (argc != 2) {
20		printf("Usage: %s <memory_size>\n", argv[0]);
21		exit(EXIT_FAILURE);
22	}
23
24	memsize = strtoul(argv[1], NULL, 10);
25
26	memsize = ROUND_PAGES(memsize);
27
28	/* We should be limited to < 4G so any size other than 0 is ok */
29	if (memsize == 0) {
30		printf("Invalid memsize\n");
31		exit(EXIT_FAILURE);
32	}
33
34	numpages = memsize >> PAGE_SHIFT;
35
36	mem =  mmap(0, memsize, PROT_READ | PROT_WRITE,
37			MAP_PRIVATE | MAP_ANONYMOUS,
38			-1, 0);
39
40	if (mem == (void*) -1) {
41		perror("Failed to allocate anon private memory using mmap\n");
42		exit(EXIT_FAILURE);
43	}
44
45	for (i = 2; i <= 16; i <<= 1) {
46		mem = mremap(mem , memsize * (i >> 1),
47					memsize * i,
48					1 /* MREMAP_MAYMOVE */);
49
50		if (mem == MAP_FAILED) {
51			perror("Failed to remap expand anon private memory\n");
52			exit(EXIT_FAILURE);
53		}
54
55		printf("Successfully remapped %d bytes @%p\n",
56				memsize * i, mem);
57	}
58
59	if (munmap(mem, memsize * 16)) {
60		perror("Could not unmap and free memory\n");
61		exit(EXIT_FAILURE);
62	}
63
64	mem =  mmap(0, memsize, PROT_READ | PROT_WRITE,
65			MAP_PRIVATE | MAP_ANONYMOUS,
66			-1, 0);
67
68	if (mem == (void*) -1) {
69		perror("Failed to allocate anon private memory using mmap\n");
70		exit(EXIT_FAILURE);
71	}
72
73	exit(EXIT_SUCCESS);
74}
75