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