]> git.saurik.com Git - apple/xnu.git/blobdiff - tools/tests/perf_index/test_fault_helper.c
xnu-2782.1.97.tar.gz
[apple/xnu.git] / tools / tests / perf_index / test_fault_helper.c
diff --git a/tools/tests/perf_index/test_fault_helper.c b/tools/tests/perf_index/test_fault_helper.c
new file mode 100644 (file)
index 0000000..9412797
--- /dev/null
@@ -0,0 +1,86 @@
+#include "test_fault_helper.h"
+#include "fail.h"
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <TargetConditionals.h>
+
+#define MEMSIZE (1L<<30)
+
+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;
+}