9 // memrw provides a simulation of an application
10 // reading and writing memory, for the sake of tuning helgrind.
11 // It is a very simple (simplistic) model:
13 // * only one exe context reading or writing the memory
14 // * the working set of the application is unrealistically
15 // concentrated on a consecutive nr of MB.
16 // At this moment, it was just used to tune the EvM data structure
18 // It would be nice to enhance this program to cope with a richer
19 // model e.g. multiple threads, many different stack traces touching
20 // the memory, better working set distribution, ...
22 static int sz_b
; // size of a block
23 static int nr_b
; // total nr of blocks used by the program
24 static int nr_b_ws
; // nr_b in program working set
25 static int nr_loops
; // nr of loops reading or writing the ws
26 static int nr_thr
; // nr of threads (hardcoded to 1 currently)
27 static int nr_repeat
; // nr of times we will allocate, use, then free total+ws
29 // Note: the total nr of MB is what is explicitly allocated.
30 // On top of that, we have the stacks, local vars, lib vars, ...
31 // The working set is just the first nr_b_ws blocks of nr_b.
33 static int verbose
= 0;
34 static unsigned char **t_b
; // Pointers to all blocks
36 static void *memrw_fn(void *v
)
41 unsigned char prev
= 0;
43 for (loops
= 0; loops
< nr_loops
; loops
++) {
44 // printf("loop %d dowrite %d\n", loops, dowrite);
45 // Note: in case of multiple threads, we will have
46 // to add lock/unlock somewhere in the below, maybe to lock
47 // the MB we are reading or writing.
48 for (m
= 0; m
< nr_b_ws
; m
++) {
49 for (b
= 0; b
< sz_b
; b
++) {
51 // Do some write or read operations.
58 differs
= t_b
[m
][b
] != prev
;
67 int main (int argc
, char *argv
[])
75 // usage: memrw [-b blocksize default 1MB ]
76 // [-t nr_b default 10] [-w nr_b_ws default 10]
77 // [-l nr_loops_on_ws default 3]
78 // [-r nr_repeat default 1]
79 // [-f fan_out default 0]
80 // [-v verbosity default 0]
87 for (a
= 1; a
< argc
; a
+=2) {
88 if (strcmp(argv
[a
], "-b") == 0) {
89 sz_b
= atoi(argv
[a
+1]);
90 } else if (strcmp(argv
[a
], "-t") == 0) {
91 nr_b
= atoi(argv
[a
+1]);
92 } else if (strcmp(argv
[a
], "-w") == 0) {
93 nr_b_ws
= atoi(argv
[a
+1]);
94 } else if (strcmp(argv
[a
], "-l") == 0) {
95 nr_loops
= atoi(argv
[a
+1]);
96 } else if (strcmp(argv
[a
], "-r") == 0) {
97 nr_repeat
= atoi(argv
[a
+1]);
98 } else if (strcmp(argv
[a
], "-v") == 0) {
99 verbose
= atoi(argv
[a
+1]);
101 printf("unknown arg %s\n", argv
[a
]);
105 nr_b_ws
= nr_b
; // to make it easy to do loops combining values
109 printf ("total program memory -t %llu MB"
110 " working set -w %llu MB\n",
111 ((unsigned long long)nr_b
* sz_b
)
112 / (unsigned long long) (1024*1024),
113 ((unsigned long long)nr_b_ws
* sz_b
)
114 / (unsigned long long)(1024*1024));
115 printf (" working set R or W -l %d times"
116 " repeat the whole stuff -r %d times\n",
120 for (r
= 0; r
< nr_repeat
; r
++) {
121 printf ("creating and initialising the total program memory\n");
122 t_b
= malloc(nr_b
* sizeof(char*));
124 perror("malloc t_b");
125 for (i
= 0; i
< nr_b
; i
++) {
126 t_b
[i
] = calloc(sz_b
, 1);
128 perror("malloc t_b[i]");
131 printf("starting thread that will read or write the working set\n");
132 ret
= pthread_create(&thr
, NULL
, memrw_fn
, &nr_thr
);
134 perror("pthread_create");
135 printf("waiting for thread termination\n");
137 ret
= pthread_join(thr
, NULL
);
139 perror("pthread_join");
140 printf("thread terminated\n");
142 /* Now, free the memory used, for the next repeat */
143 for (i
= 0; i
< nr_b
; i
++)
146 printf("memory freed\n");