This is xnu-10002.1.13. See this file in:
#include "test_fault_helper.h"
#include "fail.h"
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <TargetConditionals.h>
#if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
#define MEMSIZE (1L<<28)
#else
#define MEMSIZE (1L<<30)
#endif
static char* memblock;
int
test_fault_setup()
{
char *ptr;
int pgsz = getpagesize();
int retval;
memblock = (char *)mmap(NULL, MEMSIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
VERIFY(memblock != MAP_FAILED, "mmap failed");
/* make sure memory is paged */
for (ptr = memblock; ptr < memblock + MEMSIZE; ptr += pgsz) {
*ptr = 1;
}
/* set to read only, then back to read write so it faults on first write */
retval = mprotect(memblock, MEMSIZE, PROT_READ);
VERIFY(retval == 0, "mprotect failed");
retval = mprotect(memblock, MEMSIZE, PROT_READ | PROT_WRITE);
VERIFY(retval == 0, "mprotect failed");
return PERFINDEX_SUCCESS;
}
int
test_fault_helper(int thread_id, int num_threads, long long length, testtype_t testtype)
{
char *ptr;
int pgsz = getpagesize();
int retval;
long long num_pages = MEMSIZE / pgsz;
long long region_len = num_pages / num_threads;
long long region_start = region_len * thread_id;
long long region_end;
if (thread_id < num_pages % num_threads) {
region_start += thread_id;
region_len++;
} else {
region_start += num_pages % num_threads;
}
region_start *= pgsz;
region_len *= pgsz;
region_end = region_start + region_len;
long long left = length;
while (1) {
for (ptr = memblock + region_start; ptr < memblock + region_end; ptr += pgsz) {
*ptr = 1;
left--;
if (left == 0) {
break;
}
}
if (left == 0) {
break;
}
if (testtype == TESTFAULT) {
retval = mprotect(memblock + region_start, region_len, PROT_READ) == 0;
VERIFY(retval == 0, "mprotect failed");
retval = mprotect(memblock + region_start, region_len, PROT_READ | PROT_WRITE) == 0;
VERIFY(retval == 0, "mprotect failed");
} else if (testtype == TESTZFOD) {
retval = munmap(memblock + region_start, region_len) == 0;
VERIFY(retval == 0, "munmap failed");
ptr = mmap(memblock + region_start, region_len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
VERIFY(ptr != 0, "mmap failed");
}
}
return PERFINDEX_SUCCESS;
}