]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/perf_index/stress_memory.c
0d6c4cad954da9bbbc95a0909e5630e15ba63bbc
[apple/xnu.git] / tools / tests / perf_index / stress_memory.c
1 #include "perf_index.h"
2 #include <sys/sysctl.h>
3 #include <TargetConditionals.h>
4
5 static char *memblock;
6 static size_t memsize;
7
8 const stress_test_t memory_test = {"memory", &stress_memory_init, &stress_memory, &stress_general_cleanup, &no_validate};
9
10 size_t hw_memsize(void) {
11 int mib[2];
12 size_t len;
13 size_t my_memsize;
14 mib[0] = CTL_HW;
15 mib[1] = HW_MEMSIZE;
16 len = sizeof(my_memsize);
17 sysctl(mib, 2, &my_memsize, &len, NULL, 0);
18 return my_memsize;
19 }
20
21 DECL_INIT(stress_memory_init) {
22 char *memblockfiller;
23 long long i;
24 int pgsz = getpagesize();
25
26 /* Heuristic: use half the physical memory, hopefully this should work on all
27 * devices. We use the amount of physical memory, rather than some softer
28 * metric, like amount of free memory, so that the memory allocated is always
29 * consistent for a given device.
30 */
31 memsize = hw_memsize()/2;
32 memblock = (char*)malloc(memsize);
33 memblockfiller = memblock;
34
35 /* Do this manually, to make sure everything is paged in */
36 for(i=0; i<memsize; i+=pgsz) {
37 memblockfiller[i] = 1;
38 }
39 }
40
41 /* figures out what region of memory to copy, so it does interfere with other
42 threads, */
43 DECL_TEST(stress_memory) {
44 long long left = length;
45 long long region_len = memsize / num_threads / 2;
46 long long region_start = memsize / num_threads * thread_id / 2;
47 long long copy_len;
48
49 if(thread_id < memsize / 2 % num_threads) {
50 region_start += thread_id;
51 region_len++;
52 }
53 else {
54 region_start += memsize / 2 % num_threads;
55 }
56
57 while(left>0) {
58 copy_len = region_len < left ? region_len : left;
59 memcpy(memblock+region_start+memsize/2, memblock+region_start, copy_len);
60 left -= copy_len;
61 }
62 }