]> git.saurik.com Git - apple/xnu.git/blobdiff - tools/tests/perf_index/perfindex-memory.c
xnu-2782.1.97.tar.gz
[apple/xnu.git] / tools / tests / perf_index / perfindex-memory.c
diff --git a/tools/tests/perf_index/perfindex-memory.c b/tools/tests/perf_index/perfindex-memory.c
new file mode 100644 (file)
index 0000000..759468e
--- /dev/null
@@ -0,0 +1,84 @@
+#include "perf_index.h"
+#include "fail.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/sysctl.h>
+
+static char *memblock;
+static size_t memsize;
+
+size_t hw_memsize(void) {
+  int mib[2];
+  size_t len;
+  size_t my_memsize;
+  int retval;
+
+  mib[0] = CTL_HW;
+  mib[1] = HW_MEMSIZE;
+  len = sizeof(my_memsize);
+
+  retval = sysctl(mib, 2, &my_memsize, &len, NULL, 0);
+
+  if(retval != 0)
+      return 0;
+
+  return my_memsize;
+}
+
+DECL_SETUP {
+  char *memblockfiller;
+  long long i;
+  int pgsz = getpagesize();
+
+  /* Heuristic: use half the physical memory, hopefully this should work on all
+   * devices. We use the amount of physical memory, rather than some softer
+   * metric, like amount of free memory, so that the memory allocated is always
+   * consistent for a given device.
+   */
+  memsize = hw_memsize();
+  VERIFY(memsize > 0, "hw_memsize failed");
+  memsize = memsize/2;
+
+  memblock = (char*)malloc(memsize);
+  VERIFY(memblock != NULL, "malloc failed");
+
+  memblockfiller = memblock;
+
+  /* Do this manually, to make sure everything is paged in */
+  for(i=0; i<memsize; i+=pgsz) {
+    memblockfiller[i] = 1;
+  }
+
+  return PERFINDEX_SUCCESS;
+}
+
+/* figures out what region of memory to copy, so it does interfere with other
+threads,  */
+DECL_TEST {
+  long long left = length;
+  long long region_len = memsize / num_threads / 2;
+  long long region_start = memsize / num_threads * thread_id / 2;
+  long long copy_len;
+
+  if(thread_id < memsize / 2 % num_threads) {
+    region_start += thread_id;
+    region_len++;
+  }
+  else {
+    region_start += memsize / 2 % num_threads;
+  }
+
+  while(left>0) {
+    copy_len = region_len < left ? region_len : left;
+    memcpy(memblock+region_start+memsize/2, memblock+region_start, copy_len);
+    left -= copy_len;
+  }
+
+  return PERFINDEX_SUCCESS;
+}
+
+DECL_CLEANUP {
+    free(memblock);
+    return PERFINDEX_SUCCESS;
+}