1570af302Sopenharmony_ci#include <stdint.h> 2570af302Sopenharmony_ci#include <sys/mman.h> 3570af302Sopenharmony_ci#include <fcntl.h> 4570af302Sopenharmony_ci#include <unistd.h> 5570af302Sopenharmony_ci#include <limits.h> 6570af302Sopenharmony_ci#include "test.h" 7570af302Sopenharmony_ci#ifndef PAGE_SIZE 8570af302Sopenharmony_ci #define PAGE_SIZE sysconf(_SC_PAGE_SIZE) 9570af302Sopenharmony_ci#endif 10570af302Sopenharmony_ci#ifndef MAP_ANONYMOUS 11570af302Sopenharmony_ci #define MAP_ANONYMOUS 0 12570af302Sopenharmony_ci#endif 13570af302Sopenharmony_ci 14570af302Sopenharmony_ci/* max mmap size, *start is the largest power-of-2 size considered */ 15570af302Sopenharmony_cistatic size_t mmax(int fd, size_t *start) 16570af302Sopenharmony_ci{ 17570af302Sopenharmony_ci size_t i, n; 18570af302Sopenharmony_ci void *p; 19570af302Sopenharmony_ci 20570af302Sopenharmony_ci for (i=n=*start; i>=PAGE_SIZE; i/=2) { 21570af302Sopenharmony_ci if ((p=mmap(0, n, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, fd, 0)) == MAP_FAILED) { 22570af302Sopenharmony_ci n -= i/2; 23570af302Sopenharmony_ci } else { 24570af302Sopenharmony_ci munmap(p, n); 25570af302Sopenharmony_ci if (n == i) 26570af302Sopenharmony_ci *start = n; 27570af302Sopenharmony_ci n += i/2; 28570af302Sopenharmony_ci } 29570af302Sopenharmony_ci } 30570af302Sopenharmony_ci return n & -PAGE_SIZE; 31570af302Sopenharmony_ci} 32570af302Sopenharmony_ci 33570af302Sopenharmony_ci/* 34570af302Sopenharmony_cifills the virtual memory with anonymous PROT_NONE mmaps, 35570af302Sopenharmony_cireturns the mappings in *p and *n in decreasing size order, 36570af302Sopenharmony_cithe return value is the number of mappings or -1 on failure. 37570af302Sopenharmony_ci*/ 38570af302Sopenharmony_ciint t_vmfill(void **p, size_t *n, int len) 39570af302Sopenharmony_ci{ 40570af302Sopenharmony_ci int fd = MAP_ANONYMOUS ? -1 : open("/dev/zero", O_RDWR); 41570af302Sopenharmony_ci size_t start = SIZE_MAX/2 + 1; 42570af302Sopenharmony_ci size_t m; 43570af302Sopenharmony_ci void *q; 44570af302Sopenharmony_ci int i; 45570af302Sopenharmony_ci 46570af302Sopenharmony_ci for (i=0;;i++) { 47570af302Sopenharmony_ci m = mmax(fd, &start); 48570af302Sopenharmony_ci if (!m) 49570af302Sopenharmony_ci break; 50570af302Sopenharmony_ci q = mmap(0, m, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, fd, 0); 51570af302Sopenharmony_ci if (q == MAP_FAILED) 52570af302Sopenharmony_ci return -1; 53570af302Sopenharmony_ci if (i < len) { 54570af302Sopenharmony_ci p[i] = q; 55570af302Sopenharmony_ci n[i] = m; 56570af302Sopenharmony_ci } 57570af302Sopenharmony_ci } 58570af302Sopenharmony_ci return i; 59570af302Sopenharmony_ci} 60