1#include "test_fault_helper.h" 2#include "fail.h" 3#include <sys/mman.h> 4#include <stdlib.h> 5#include <unistd.h> 6#include <assert.h> 7#include <TargetConditionals.h> 8 9#define MEMSIZE (1L<<30) 10 11static char* memblock; 12 13int test_fault_setup() { 14 char *ptr; 15 int pgsz = getpagesize(); 16 int retval; 17 18 memblock = (char *)mmap(NULL, MEMSIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 19 VERIFY(memblock != MAP_FAILED, "mmap failed"); 20 21 /* make sure memory is paged */ 22 for(ptr = memblock; ptr<memblock+MEMSIZE; ptr+= pgsz) { 23 *ptr = 1; 24 } 25 26 /* set to read only, then back to read write so it faults on first write */ 27 retval = mprotect(memblock, MEMSIZE, PROT_READ); 28 VERIFY(retval == 0, "mprotect failed"); 29 30 retval = mprotect(memblock, MEMSIZE, PROT_READ | PROT_WRITE); 31 VERIFY(retval == 0, "mprotect failed"); 32 33 return PERFINDEX_SUCCESS; 34} 35 36int test_fault_helper(int thread_id, int num_threads, long long length, testtype_t testtype) { 37 char *ptr; 38 int pgsz = getpagesize(); 39 int retval; 40 41 long long num_pages = MEMSIZE / pgsz; 42 long long region_len = num_pages/num_threads; 43 long long region_start = region_len * thread_id; 44 long long region_end; 45 46 if(thread_id < num_pages % num_threads) { 47 region_start += thread_id; 48 region_len++; 49 } 50 else { 51 region_start += num_pages % num_threads; 52 } 53 54 region_start *= pgsz; 55 region_len *= pgsz; 56 region_end = region_start + region_len; 57 58 long long left = length; 59 60 while(1) { 61 for(ptr = memblock+region_start; ptr<memblock+region_end; ptr+= pgsz) { 62 *ptr = 1; 63 left--; 64 if(left==0) 65 break; 66 } 67 68 if(left==0) 69 break; 70 71 if(testtype == TESTFAULT) { 72 retval = mprotect(memblock+region_start, region_len, PROT_READ) == 0; 73 VERIFY(retval == 0, "mprotect failed"); 74 retval = mprotect(memblock+region_start, region_len, PROT_READ | PROT_WRITE) == 0; 75 VERIFY(retval == 0, "mprotect failed"); 76 } 77 78 else if(testtype == TESTZFOD) { 79 retval = munmap(memblock+region_start, region_len) == 0; 80 VERIFY(retval == 0, "munmap failed"); 81 ptr = mmap(memblock+region_start, region_len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); 82 VERIFY(ptr != 0, "mmap failed"); 83 } 84 } 85 return PERFINDEX_SUCCESS; 86} 87