Add DRD suppression patterns for races triggered by std::ostream
[valgrind.git] / drd / tests / unit_bitmap.c
blob5778753a6520da063df4644da50a92c0c403fa1d
1 /** @brief Unit-test for DRD's bitmap implementation. */
4 #include <assert.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
10 #include "coregrind/m_xarray.c"
11 #include "coregrind/m_poolalloc.c"
12 #include "coregrind/m_oset.c"
13 #include "drd/drd_bitmap.c"
14 #include "drd/pub_drd_bitmap.h"
17 #ifndef MIN
18 #define MIN(x, y) ((x) < (y) ? (x) : (y))
19 #endif
20 #ifndef MAX
21 #define MAX(x, y) ((x) > (y) ? (x) : (y))
22 #endif
25 /* Replacements for Valgrind core functionality. */
27 void* VG_(malloc)(const HChar* cc, SizeT nbytes)
28 { return malloc(nbytes); }
29 void VG_(free)(void* p)
30 { return free(p); }
31 void VG_(assert_fail)(Bool isCore, const HChar* assertion, const HChar* file,
32 Int line, const HChar* function, const HChar* format,
33 ...)
35 fprintf(stderr,
36 "%s:%u: %s%sAssertion `%s' failed.\n",
37 file,
38 line,
39 function ? (char*)function : "",
40 function ? ": " : "",
41 assertion);
42 fflush(stdout);
43 fflush(stderr);
44 abort();
47 Int VG_(strcmp)( const HChar* s1, const HChar* s2 )
48 { return strcmp(s1, s2); }
49 void* VG_(memset)(void *s, Int c, SizeT sz)
50 { return memset(s, c, sz); }
51 void* VG_(memcpy)(void *d, const void *s, SizeT sz)
52 { return memcpy(d, s, sz); }
53 void* VG_(memmove)(void *d, const void *s, SizeT sz)
54 { return memmove(d, s, sz); }
55 Int VG_(memcmp)(const void* s1, const void* s2, SizeT n)
56 { return memcmp(s1, s2, n); }
57 UInt VG_(printf)(const HChar *format, ...)
58 { UInt ret; va_list vargs; va_start(vargs, format); ret = vprintf(format, vargs); va_end(vargs); return ret; }
59 UInt VG_(message)(VgMsgKind kind, const HChar* format, ...)
60 { UInt ret; va_list vargs; va_start(vargs, format); ret = vprintf(format, vargs); va_end(vargs); printf("\n"); return ret; }
61 Bool DRD_(is_suppressed)(const Addr a1, const Addr a2)
62 { assert(0); }
63 void VG_(vcbprintf)(void(*char_sink)(HChar, void* opaque),
64 void* opaque,
65 const HChar* format, va_list vargs)
66 { assert(0); }
67 void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
68 Int (*compar)(const void*, const void*) )
69 { assert(0); }
71 /* Actual unit test */
73 static int s_verbose = 1;
75 static
76 struct { Addr address; SizeT size; BmAccessTypeT access_type; }
77 s_test1_args[] = {
78 { 0, 0, eLoad },
79 { 0, 1, eLoad },
80 { 666, 4, eLoad },
81 { 667, 2, eStore },
82 { 1024, 1, eStore },
83 { 0xffffULL, 1, eStore },
84 { 0x0001ffffULL, 1, eLoad },
85 { 0x00ffffffULL, 1, eLoad },
86 { 0xffffffffULL - (((1 << ADDR_LSB_BITS) + 1) << ADDR_IGNORED_BITS),
87 1, eStore },
88 #if defined(VGP_amd64_linux) || defined(VGP_ppc64be_linux) \
89 || defined(VGP_ppc64le_linux)
90 { 0xffffffffULL - (1 << ADDR_LSB_BITS << ADDR_IGNORED_BITS),
91 1, eStore },
92 { 0xffffffffULL, 1, eStore },
93 { 0x100000000ULL, 1, eStore },
94 { -2ULL - (1 << ADDR_LSB_BITS << ADDR_IGNORED_BITS),
95 1, eStore },
96 #endif
99 /**
100 * Compare two bitmaps and if different, print the differences.
102 int bm_equal_print_diffs(struct bitmap* bm1, struct bitmap* bm2)
104 int equal;
106 equal = DRD_(bm_equal)(bm1, bm2);
107 if (s_verbose && ! equal)
109 unsigned i;
111 VG_(printf)("Bitmaps are different.\n");
112 for (i = 0; i < 0x10000; i++)
114 if (DRD_(bm_has_1)(bm1, i, eLoad) != DRD_(bm_has_1)(bm2, i, eLoad)
115 || DRD_(bm_has_1)(bm1, i, eStore) != DRD_(bm_has_1)(bm2, i, eStore))
117 printf("0x%x %c %c %c %c\n",
119 DRD_(bm_has_1)(bm1, i, eLoad) ? 'R' : ' ',
120 DRD_(bm_has_1)(bm1, i, eStore) ? 'W' : ' ',
121 DRD_(bm_has_1)(bm2, i, eLoad) ? 'R' : ' ',
122 DRD_(bm_has_1)(bm2, i, eStore) ? 'W' : ' '
126 fflush(stdout);
129 return equal;
132 void bm_test1(void)
134 struct bitmap* bm;
135 struct bitmap* bm2;
136 unsigned i, j;
138 bm = DRD_(bm_new)();
140 for (i = 0; i < sizeof(s_test1_args)/sizeof(s_test1_args[0]); i++)
142 DRD_(bm_access_range)(bm,
143 s_test1_args[i].address,
144 s_test1_args[i].address + s_test1_args[i].size,
145 s_test1_args[i].access_type);
148 for (i = 0; i < sizeof(s_test1_args)/sizeof(s_test1_args[0]); i++)
150 for (j = 0;
151 first_address_with_higher_lsb(j) <= s_test1_args[i].size;
152 j = first_address_with_higher_lsb(j))
154 tl_assert(DRD_(bm_has_1)(bm,
155 s_test1_args[i].address + j,
156 s_test1_args[i].access_type));
160 bm2 = DRD_(bm_new)();
161 DRD_(bm_merge2)(bm2, bm);
162 DRD_(bm_merge2)(bm2, bm);
163 assert(bm_equal_print_diffs(bm2, bm));
165 if (s_verbose)
166 VG_(printf)("Deleting bitmap bm\n");
167 DRD_(bm_delete)(bm);
168 if (s_verbose)
169 VG_(printf)("Deleting bitmap bm2\n");
170 DRD_(bm_delete)(bm2);
173 /** Test whether bm_equal() works correctly. */
174 void bm_test2()
176 struct bitmap* bm1;
177 struct bitmap* bm2;
179 bm1 = DRD_(bm_new)();
180 bm2 = DRD_(bm_new)();
181 DRD_(bm_access_load_1)(bm1, 7);
182 DRD_(bm_access_load_1)(bm2, make_address(1, 0) + 7);
183 assert(! DRD_(bm_equal)(bm1, bm2));
184 assert(! DRD_(bm_equal)(bm2, bm1));
185 DRD_(bm_access_load_1)(bm2, 7);
186 assert(! DRD_(bm_equal)(bm1, bm2));
187 assert(! DRD_(bm_equal)(bm2, bm1));
188 DRD_(bm_access_store_1)(bm1, make_address(1, 0) + 7);
189 assert(! DRD_(bm_equal)(bm1, bm2));
190 assert(! DRD_(bm_equal)(bm2, bm1));
191 DRD_(bm_delete)(bm2);
192 DRD_(bm_delete)(bm1);
195 /** Torture test of the functions that set or clear a range of bits. */
196 void bm_test3(const int outer_loop_step, const int inner_loop_step)
198 unsigned i, j;
199 struct bitmap* bm1;
200 struct bitmap* bm2;
202 const Addr lb = make_address(2, 0) - 2 * BITS_PER_UWORD;
203 const Addr ub = make_address(2, 0) + 2 * BITS_PER_UWORD;
205 assert(outer_loop_step >= 1);
206 assert((outer_loop_step % ADDR_GRANULARITY) == 0);
207 assert(inner_loop_step >= 1);
208 assert((inner_loop_step % ADDR_GRANULARITY) == 0);
210 bm1 = DRD_(bm_new)();
211 bm2 = DRD_(bm_new)();
212 for (i = lb; i < ub; i += outer_loop_step)
214 for (j = i + ADDR_GRANULARITY; j < ub; j += inner_loop_step)
216 DRD_(bm_access_range_load)(bm1, i, j);
217 DRD_(bm_clear_load)(bm1, i, j);
218 assert(bm_equal_print_diffs(bm1, bm2));
219 DRD_(bm_access_load_1)(bm1, i);
220 DRD_(bm_clear_load)(bm1, i, i + MAX(1, ADDR_GRANULARITY));
221 assert(bm_equal_print_diffs(bm1, bm2));
222 DRD_(bm_access_load_2)(bm1, i);
223 DRD_(bm_clear_load)(bm1, i, i + MAX(2, ADDR_GRANULARITY));
224 assert(bm_equal_print_diffs(bm1, bm2));
225 DRD_(bm_access_load_4)(bm1, i);
226 DRD_(bm_clear_load)(bm1, i, i + MAX(4, ADDR_GRANULARITY));
227 assert(bm_equal_print_diffs(bm1, bm2));
228 DRD_(bm_access_load_8)(bm1, i);
229 DRD_(bm_clear_load)(bm1, i, i + MAX(8, ADDR_GRANULARITY));
230 assert(bm_equal_print_diffs(bm1, bm2));
232 DRD_(bm_access_range_store)(bm1, i, j);
233 DRD_(bm_clear_store)(bm1, i, j);
234 assert(bm_equal_print_diffs(bm1, bm2));
235 DRD_(bm_access_store_1)(bm1, i);
236 DRD_(bm_clear_store)(bm1, i, i + MAX(1, ADDR_GRANULARITY));
237 assert(bm_equal_print_diffs(bm1, bm2));
238 DRD_(bm_access_store_2)(bm1, i);
239 DRD_(bm_clear_store)(bm1, i, i + MAX(2, ADDR_GRANULARITY));
240 assert(bm_equal_print_diffs(bm1, bm2));
241 DRD_(bm_access_store_4)(bm1, i);
242 DRD_(bm_clear_store)(bm1, i, i + MAX(4, ADDR_GRANULARITY));
243 assert(bm_equal_print_diffs(bm1, bm2));
244 DRD_(bm_access_store_8)(bm1, i);
245 DRD_(bm_clear_store)(bm1, i, i + MAX(8, ADDR_GRANULARITY));
246 assert(bm_equal_print_diffs(bm1, bm2));
248 DRD_(bm_access_range_load)(bm1, i, j);
249 DRD_(bm_access_range_store)(bm1, i, j);
250 DRD_(bm_clear)(bm1, i, j);
251 assert(bm_equal_print_diffs(bm1, bm2));
252 DRD_(bm_access_load_1)(bm1, i);
253 DRD_(bm_access_store_1)(bm1, i);
254 DRD_(bm_clear)(bm1, i, i + MAX(1, ADDR_GRANULARITY));
255 assert(bm_equal_print_diffs(bm1, bm2));
256 DRD_(bm_access_load_2)(bm1, i);
257 DRD_(bm_access_store_2)(bm1, i);
258 DRD_(bm_clear)(bm1, i, i + MAX(2, ADDR_GRANULARITY));
259 assert(bm_equal_print_diffs(bm1, bm2));
260 DRD_(bm_access_load_4)(bm1, i);
261 DRD_(bm_access_store_4)(bm1, i);
262 DRD_(bm_clear)(bm1, i, i + MAX(4, ADDR_GRANULARITY));
263 assert(bm_equal_print_diffs(bm1, bm2));
264 DRD_(bm_access_load_8)(bm1, i);
265 DRD_(bm_access_store_8)(bm1, i);
266 DRD_(bm_clear)(bm1, i, i + MAX(8, ADDR_GRANULARITY));
267 assert(bm_equal_print_diffs(bm1, bm2));
270 DRD_(bm_access_range_load)(bm1, 0, make_address(2, 0) + 2 * BITS_PER_UWORD);
271 DRD_(bm_access_range_store)(bm1, 0, make_address(2, 0) + 2 * BITS_PER_UWORD);
272 DRD_(bm_access_range_load)(bm2, 0, make_address(2, 0) + 2 * BITS_PER_UWORD);
273 DRD_(bm_access_range_store)(bm2, 0, make_address(2, 0) + 2 * BITS_PER_UWORD);
274 for (i = make_address(1, 0) - 2 * BITS_PER_UWORD;
275 i < make_address(1, 0) + 2 * BITS_PER_UWORD;
276 i += outer_loop_step)
278 for (j = i + 1; j < ub; j += inner_loop_step)
280 DRD_(bm_clear_load)(bm1, i, j);
281 DRD_(bm_access_range_load)(bm1, i, j);
282 assert(bm_equal_print_diffs(bm1, bm2));
283 DRD_(bm_clear_load)(bm1, i, i+1);
284 DRD_(bm_access_load_1)(bm1, i);
285 assert(bm_equal_print_diffs(bm1, bm2));
286 DRD_(bm_clear_load)(bm1, i, i+2);
287 DRD_(bm_access_load_2)(bm1, i);
288 assert(bm_equal_print_diffs(bm1, bm2));
289 DRD_(bm_clear_load)(bm1, i, i+4);
290 DRD_(bm_access_load_4)(bm1, i);
291 assert(bm_equal_print_diffs(bm1, bm2));
292 DRD_(bm_clear_load)(bm1, i, i+8);
293 DRD_(bm_access_load_8)(bm1, i);
294 assert(bm_equal_print_diffs(bm1, bm2));
296 DRD_(bm_clear_store)(bm1, i, j);
297 DRD_(bm_access_range_store)(bm1, i, j);
298 assert(bm_equal_print_diffs(bm1, bm2));
299 DRD_(bm_clear_store)(bm1, i, i+1);
300 DRD_(bm_access_store_1)(bm1, i);
301 assert(bm_equal_print_diffs(bm1, bm2));
302 DRD_(bm_clear_store)(bm1, i, i+2);
303 DRD_(bm_access_store_2)(bm1, i);
304 assert(bm_equal_print_diffs(bm1, bm2));
305 DRD_(bm_clear_store)(bm1, i, i+4);
306 DRD_(bm_access_store_4)(bm1, i);
307 assert(bm_equal_print_diffs(bm1, bm2));
308 DRD_(bm_clear_store)(bm1, i, i+8);
309 DRD_(bm_access_store_8)(bm1, i);
310 assert(bm_equal_print_diffs(bm1, bm2));
312 DRD_(bm_clear)(bm1, i, j);
313 DRD_(bm_access_range_load)(bm1, i, j);
314 DRD_(bm_access_range_store)(bm1, i, j);
315 assert(bm_equal_print_diffs(bm1, bm2));
318 DRD_(bm_delete)(bm2);
319 DRD_(bm_delete)(bm1);
322 int main(int argc, char** argv)
324 int outer_loop_step = ADDR_GRANULARITY;
325 int inner_loop_step = ADDR_GRANULARITY;
326 int optchar;
328 while ((optchar = getopt(argc, argv, "s:t:q")) != EOF)
330 switch (optchar)
332 case 's':
333 outer_loop_step = atoi(optarg);
334 break;
335 case 't':
336 inner_loop_step = atoi(optarg);
337 break;
338 case 'q':
339 s_verbose = 0;
340 break;
341 default:
342 fprintf(stderr,
343 "Usage: %s [-s<outer_loop_step>] [-t<inner_loop_step>] [-q].\n",
344 argv[0]);
345 break;
349 fprintf(stderr, "Start of DRD BM unit test.\n");
351 DRD_(bm_module_init)();
352 bm_test1();
353 bm_test2();
354 bm_test3(outer_loop_step, inner_loop_step);
355 DRD_(bm_module_cleanup)();
357 fprintf(stderr, "End of DRD BM unit test.\n");
359 return 0;