Home | History | Annotate | Download | only in memory_api
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <sys/mman.h>
      4 #include <unistd.h>
      5 #include <fcntl.h>
      6 
      7 /* This file includes a simple set of memory allocation calls that
      8  * a user space program can use to allocate/free or move memory mappings.
      9  * The intent of this program is to make it easier to verify if the kernel
     10  * internal mappings are correct.
     11  */
     12 
     13 #define PAGE_SHIFT 12
     14 
     15 #define ROUND_PAGES(memsize) ((memsize >> (PAGE_SHIFT)) << PAGE_SHIFT)
     16 
     17 /* approximately half of memsize, page aligned */
     18 #define HALF_MEM(memsize) ((memsize >> (PAGE_SHIFT))<<(PAGE_SHIFT - 1))
     19 
     20 inline void waitnext() {
     21 	fflush(NULL);
     22 	getchar();
     23 }
     24 
     25 int main(int argc, char *argv[]) {
     26 	unsigned int memsize;
     27 	char *mem;
     28 	int i, numpages, fd;
     29 
     30 	if (argc != 2) {
     31 		printf("Usage: %s <memory_size>\n", argv[0]);
     32 		exit(EXIT_FAILURE);
     33 	}
     34 
     35 	memsize = strtoul(argv[1], NULL, 10);
     36 
     37 	memsize = ROUND_PAGES(memsize);
     38 
     39 	/* We should be limited to < 4G so any size other than 0 is ok */
     40 	if (memsize == 0) {
     41 		printf("Invalid memsize\n");
     42 		exit(EXIT_FAILURE);
     43 	}
     44 
     45 
     46 	numpages = memsize >> PAGE_SHIFT;
     47 
     48 	mlockall(MCL_FUTURE);
     49 
     50 	mem = sbrk(memsize);
     51 
     52 	if (mem == (void*) -1) {
     53 		perror("Failed to allocate memory using sbrk\n");
     54 		exit(EXIT_FAILURE);
     55 	}
     56 
     57 	printf("Successfully allocated sbrk memory %d bytes @%p\n",
     58 				memsize,  mem);
     59 
     60 	waitnext();
     61 
     62 	sbrk(-(memsize));
     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 	printf("Successfully allocated anon mmap memory %d bytes @%p\n",
     74 				memsize,  mem);
     75 
     76 	waitnext();
     77 
     78 	if (-1 == mprotect(mem, HALF_MEM(memsize), PROT_READ)) {
     79 		perror("Failed to W protect memory using mprotect\n");
     80 		exit(EXIT_FAILURE);
     81 	}
     82 
     83 	printf("Successfully write protected %d bytes @%p\n",
     84 			HALF_MEM(memsize), mem);
     85 
     86 	waitnext();
     87 
     88 	if (-1 == mprotect(mem, HALF_MEM(memsize),
     89 					 PROT_READ | PROT_WRITE)) {
     90 		perror("Failed to RW protect memory using mprotect\n");
     91 		exit(EXIT_FAILURE);
     92 	}
     93 
     94 	printf("Successfully cleared write protected %d bytes @%p\n",
     95 			memsize, mem);
     96 	waitnext();
     97 
     98 	/* Mark all pages with a specific pattern */
     99 	for (i = 0; i < numpages; i++) {
    100 		int *ptr = (int *)(mem + i*4096);
    101 		*ptr = i;
    102 	}
    103 
    104 	mem = mremap(mem , memsize,
    105 				memsize + HALF_MEM(memsize),
    106 				1 /* MREMAP_MAYMOVE */);
    107 
    108 	if (mem == MAP_FAILED) {
    109 		perror("Failed to remap expand anon private memory\n");
    110 		exit(EXIT_FAILURE);
    111 	}
    112 
    113 	printf("Successfully remapped %d bytes @%p\n",
    114 			memsize + HALF_MEM(memsize), mem);
    115 
    116 	waitnext();
    117 
    118 	/* Mark all pages with a specific pattern */
    119 	for (i = 0; i < numpages; i++) {
    120 		int value = *(int*)(mem + i*4096);
    121 		if (value != i) {
    122 			printf("remap error expected %d got %d\n",
    123 					i, value);
    124 			exit(EXIT_FAILURE);
    125 		}
    126 	}
    127 
    128 	if (munmap(mem, memsize + HALF_MEM(memsize))) {
    129 		perror("Could not unmap and free memory\n");
    130 		exit(EXIT_FAILURE);
    131 	}
    132 
    133 
    134 	fd = open("/dev/zero", O_RDONLY);
    135 
    136 	mem =  mmap(0, memsize, PROT_READ | PROT_WRITE,
    137 			MAP_PRIVATE,
    138 			fd, 0);
    139 
    140 	if (mem == (void*) -1) {
    141 		perror("Failed to allocate file backed memory using mmap\n");
    142 		exit(EXIT_FAILURE);
    143 	}
    144 
    145 	printf("Successfully allocated file backed mmap memory %d bytes @%p\n",
    146 					 memsize, mem);
    147 	waitnext();
    148 
    149 	if (munmap(mem, memsize)) {
    150 		perror("Could not unmap and free file backed memory\n");
    151 		exit(EXIT_FAILURE);
    152 	}
    153 
    154 	exit(EXIT_SUCCESS);
    155 }
    156