]>
Commit | Line | Data |
---|---|---|
39236c6e | 1 | #include "perf_index.h" |
fe8ab488 A |
2 | #include "fail.h" |
3 | #include <stdlib.h> | |
4 | #include <unistd.h> | |
5 | #include <string.h> | |
39236c6e | 6 | #include <sys/sysctl.h> |
39236c6e A |
7 | |
8 | static char *memblock; | |
9 | static size_t memsize; | |
10 | ||
0a7de745 A |
11 | size_t |
12 | hw_memsize(void) | |
13 | { | |
14 | int mib[2]; | |
15 | size_t len; | |
16 | size_t my_memsize; | |
17 | int retval; | |
fe8ab488 | 18 | |
0a7de745 A |
19 | mib[0] = CTL_HW; |
20 | mib[1] = HW_MEMSIZE; | |
21 | len = sizeof(my_memsize); | |
fe8ab488 | 22 | |
0a7de745 | 23 | retval = sysctl(mib, 2, &my_memsize, &len, NULL, 0); |
fe8ab488 | 24 | |
0a7de745 A |
25 | if (retval != 0) { |
26 | return 0; | |
27 | } | |
fe8ab488 | 28 | |
0a7de745 | 29 | return my_memsize; |
39236c6e A |
30 | } |
31 | ||
fe8ab488 | 32 | DECL_SETUP { |
0a7de745 A |
33 | char *memblockfiller; |
34 | long long i; | |
35 | int pgsz = getpagesize(); | |
36 | ||
37 | /* Heuristic: use half the physical memory, hopefully this should work on all | |
38 | * devices. We use the amount of physical memory, rather than some softer | |
39 | * metric, like amount of free memory, so that the memory allocated is always | |
40 | * consistent for a given device. | |
41 | */ | |
42 | memsize = hw_memsize(); | |
43 | VERIFY(memsize > 0, "hw_memsize failed"); | |
44 | memsize = memsize / 2; | |
45 | ||
46 | memblock = (char*)malloc(memsize); | |
47 | VERIFY(memblock != NULL, "malloc failed"); | |
48 | ||
49 | memblockfiller = memblock; | |
50 | ||
51 | /* Do this manually, to make sure everything is paged in */ | |
52 | for (i = 0; i < memsize; i += pgsz) { | |
53 | memblockfiller[i] = 1; | |
54 | } | |
55 | ||
56 | return PERFINDEX_SUCCESS; | |
39236c6e A |
57 | } |
58 | ||
59 | /* figures out what region of memory to copy, so it does interfere with other | |
0a7de745 | 60 | * threads, */ |
fe8ab488 | 61 | DECL_TEST { |
0a7de745 A |
62 | long long left = length; |
63 | long long region_len = memsize / num_threads / 2; | |
64 | long long region_start = memsize / num_threads * thread_id / 2; | |
65 | long long copy_len; | |
66 | ||
67 | if (thread_id < memsize / 2 % num_threads) { | |
68 | region_start += thread_id; | |
69 | region_len++; | |
70 | } else { | |
71 | region_start += memsize / 2 % num_threads; | |
72 | } | |
73 | ||
74 | while (left > 0) { | |
75 | copy_len = region_len < left ? region_len : left; | |
76 | memcpy(memblock + region_start + memsize / 2, memblock + region_start, copy_len); | |
77 | left -= copy_len; | |
78 | } | |
79 | ||
80 | return PERFINDEX_SUCCESS; | |
fe8ab488 A |
81 | } |
82 | ||
83 | DECL_CLEANUP { | |
0a7de745 A |
84 | free(memblock); |
85 | return PERFINDEX_SUCCESS; | |
39236c6e | 86 | } |