1 /** @brief Unit-test for DRD's bitmap implementation. */
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"
18 #define MIN(x, y) ((x) < (y) ? (x) : (y))
21 #define MAX(x, y) ((x) > (y) ? (x) : (y))
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
)
31 void VG_(assert_fail
)(Bool isCore
, const HChar
* assertion
, const HChar
* file
,
32 Int line
, const HChar
* function
, const HChar
* format
,
36 "%s:%u: %s%sAssertion `%s' failed.\n",
39 function
? (char*)function
: "",
47 void* VG_(memset
)(void *s
, Int c
, SizeT sz
)
48 { return memset(s
, c
, sz
); }
49 void* VG_(memcpy
)(void *d
, const void *s
, SizeT sz
)
50 { return memcpy(d
, s
, sz
); }
51 void* VG_(memmove
)(void *d
, const void *s
, SizeT sz
)
52 { return memmove(d
, s
, sz
); }
53 Int
VG_(memcmp
)(const void* s1
, const void* s2
, SizeT n
)
54 { return memcmp(s1
, s2
, n
); }
55 UInt
VG_(printf
)(const HChar
*format
, ...)
56 { UInt ret
; va_list vargs
; va_start(vargs
, format
); ret
= vprintf(format
, vargs
); va_end(vargs
); return ret
; }
57 UInt
VG_(message
)(VgMsgKind kind
, const HChar
* format
, ...)
58 { UInt ret
; va_list vargs
; va_start(vargs
, format
); ret
= vprintf(format
, vargs
); va_end(vargs
); printf("\n"); return ret
; }
59 Bool
DRD_(is_suppressed
)(const Addr a1
, const Addr a2
)
61 void VG_(vcbprintf
)(void(*char_sink
)(HChar
, void* opaque
),
63 const HChar
* format
, va_list vargs
)
65 void VG_(ssort
)( void* base
, SizeT nmemb
, SizeT size
,
66 Int (*compar
)(const void*, const void*) )
69 /* Actual unit test */
71 static int s_verbose
= 1;
74 struct { Addr address
; SizeT size
; BmAccessTypeT access_type
; }
81 { 0xffffULL
, 1, eStore
},
82 { 0x0001ffffULL
, 1, eLoad
},
83 { 0x00ffffffULL
, 1, eLoad
},
84 { 0xffffffffULL
- (((1 << ADDR_LSB_BITS
) + 1) << ADDR_IGNORED_BITS
),
86 #if defined(VGP_amd64_linux) || defined(VGP_ppc64be_linux) \
87 || defined(VGP_ppc64le_linux)
88 { 0xffffffffULL
- (1 << ADDR_LSB_BITS
<< ADDR_IGNORED_BITS
),
90 { 0xffffffffULL
, 1, eStore
},
91 { 0x100000000ULL
, 1, eStore
},
92 { -2ULL - (1 << ADDR_LSB_BITS
<< ADDR_IGNORED_BITS
),
98 * Compare two bitmaps and if different, print the differences.
100 int bm_equal_print_diffs(struct bitmap
* bm1
, struct bitmap
* bm2
)
104 equal
= DRD_(bm_equal
)(bm1
, bm2
);
105 if (s_verbose
&& ! equal
)
109 VG_(printf
)("Bitmaps are different.\n");
110 for (i
= 0; i
< 0x10000; i
++)
112 if (DRD_(bm_has_1
)(bm1
, i
, eLoad
) != DRD_(bm_has_1
)(bm2
, i
, eLoad
)
113 || DRD_(bm_has_1
)(bm1
, i
, eStore
) != DRD_(bm_has_1
)(bm2
, i
, eStore
))
115 printf("0x%x %c %c %c %c\n",
117 DRD_(bm_has_1
)(bm1
, i
, eLoad
) ? 'R' : ' ',
118 DRD_(bm_has_1
)(bm1
, i
, eStore
) ? 'W' : ' ',
119 DRD_(bm_has_1
)(bm2
, i
, eLoad
) ? 'R' : ' ',
120 DRD_(bm_has_1
)(bm2
, i
, eStore
) ? 'W' : ' '
138 for (i
= 0; i
< sizeof(s_test1_args
)/sizeof(s_test1_args
[0]); i
++)
140 DRD_(bm_access_range
)(bm
,
141 s_test1_args
[i
].address
,
142 s_test1_args
[i
].address
+ s_test1_args
[i
].size
,
143 s_test1_args
[i
].access_type
);
146 for (i
= 0; i
< sizeof(s_test1_args
)/sizeof(s_test1_args
[0]); i
++)
149 first_address_with_higher_lsb(j
) <= s_test1_args
[i
].size
;
150 j
= first_address_with_higher_lsb(j
))
152 tl_assert(DRD_(bm_has_1
)(bm
,
153 s_test1_args
[i
].address
+ j
,
154 s_test1_args
[i
].access_type
));
158 bm2
= DRD_(bm_new
)();
159 DRD_(bm_merge2
)(bm2
, bm
);
160 DRD_(bm_merge2
)(bm2
, bm
);
161 assert(bm_equal_print_diffs(bm2
, bm
));
164 VG_(printf
)("Deleting bitmap bm\n");
167 VG_(printf
)("Deleting bitmap bm2\n");
168 DRD_(bm_delete
)(bm2
);
171 /** Test whether bm_equal() works correctly. */
177 bm1
= DRD_(bm_new
)();
178 bm2
= DRD_(bm_new
)();
179 DRD_(bm_access_load_1
)(bm1
, 7);
180 DRD_(bm_access_load_1
)(bm2
, make_address(1, 0) + 7);
181 assert(! DRD_(bm_equal
)(bm1
, bm2
));
182 assert(! DRD_(bm_equal
)(bm2
, bm1
));
183 DRD_(bm_access_load_1
)(bm2
, 7);
184 assert(! DRD_(bm_equal
)(bm1
, bm2
));
185 assert(! DRD_(bm_equal
)(bm2
, bm1
));
186 DRD_(bm_access_store_1
)(bm1
, make_address(1, 0) + 7);
187 assert(! DRD_(bm_equal
)(bm1
, bm2
));
188 assert(! DRD_(bm_equal
)(bm2
, bm1
));
189 DRD_(bm_delete
)(bm2
);
190 DRD_(bm_delete
)(bm1
);
193 /** Torture test of the functions that set or clear a range of bits. */
194 void bm_test3(const int outer_loop_step
, const int inner_loop_step
)
200 const Addr lb
= make_address(2, 0) - 2 * BITS_PER_UWORD
;
201 const Addr ub
= make_address(2, 0) + 2 * BITS_PER_UWORD
;
203 assert(outer_loop_step
>= 1);
204 assert((outer_loop_step
% ADDR_GRANULARITY
) == 0);
205 assert(inner_loop_step
>= 1);
206 assert((inner_loop_step
% ADDR_GRANULARITY
) == 0);
208 bm1
= DRD_(bm_new
)();
209 bm2
= DRD_(bm_new
)();
210 for (i
= lb
; i
< ub
; i
+= outer_loop_step
)
212 for (j
= i
+ ADDR_GRANULARITY
; j
< ub
; j
+= inner_loop_step
)
214 DRD_(bm_access_range_load
)(bm1
, i
, j
);
215 DRD_(bm_clear_load
)(bm1
, i
, j
);
216 assert(bm_equal_print_diffs(bm1
, bm2
));
217 DRD_(bm_access_load_1
)(bm1
, i
);
218 DRD_(bm_clear_load
)(bm1
, i
, i
+ MAX(1, ADDR_GRANULARITY
));
219 assert(bm_equal_print_diffs(bm1
, bm2
));
220 DRD_(bm_access_load_2
)(bm1
, i
);
221 DRD_(bm_clear_load
)(bm1
, i
, i
+ MAX(2, ADDR_GRANULARITY
));
222 assert(bm_equal_print_diffs(bm1
, bm2
));
223 DRD_(bm_access_load_4
)(bm1
, i
);
224 DRD_(bm_clear_load
)(bm1
, i
, i
+ MAX(4, ADDR_GRANULARITY
));
225 assert(bm_equal_print_diffs(bm1
, bm2
));
226 DRD_(bm_access_load_8
)(bm1
, i
);
227 DRD_(bm_clear_load
)(bm1
, i
, i
+ MAX(8, ADDR_GRANULARITY
));
228 assert(bm_equal_print_diffs(bm1
, bm2
));
230 DRD_(bm_access_range_store
)(bm1
, i
, j
);
231 DRD_(bm_clear_store
)(bm1
, i
, j
);
232 assert(bm_equal_print_diffs(bm1
, bm2
));
233 DRD_(bm_access_store_1
)(bm1
, i
);
234 DRD_(bm_clear_store
)(bm1
, i
, i
+ MAX(1, ADDR_GRANULARITY
));
235 assert(bm_equal_print_diffs(bm1
, bm2
));
236 DRD_(bm_access_store_2
)(bm1
, i
);
237 DRD_(bm_clear_store
)(bm1
, i
, i
+ MAX(2, ADDR_GRANULARITY
));
238 assert(bm_equal_print_diffs(bm1
, bm2
));
239 DRD_(bm_access_store_4
)(bm1
, i
);
240 DRD_(bm_clear_store
)(bm1
, i
, i
+ MAX(4, ADDR_GRANULARITY
));
241 assert(bm_equal_print_diffs(bm1
, bm2
));
242 DRD_(bm_access_store_8
)(bm1
, i
);
243 DRD_(bm_clear_store
)(bm1
, i
, i
+ MAX(8, ADDR_GRANULARITY
));
244 assert(bm_equal_print_diffs(bm1
, bm2
));
246 DRD_(bm_access_range_load
)(bm1
, i
, j
);
247 DRD_(bm_access_range_store
)(bm1
, i
, j
);
248 DRD_(bm_clear
)(bm1
, i
, j
);
249 assert(bm_equal_print_diffs(bm1
, bm2
));
250 DRD_(bm_access_load_1
)(bm1
, i
);
251 DRD_(bm_access_store_1
)(bm1
, i
);
252 DRD_(bm_clear
)(bm1
, i
, i
+ MAX(1, ADDR_GRANULARITY
));
253 assert(bm_equal_print_diffs(bm1
, bm2
));
254 DRD_(bm_access_load_2
)(bm1
, i
);
255 DRD_(bm_access_store_2
)(bm1
, i
);
256 DRD_(bm_clear
)(bm1
, i
, i
+ MAX(2, ADDR_GRANULARITY
));
257 assert(bm_equal_print_diffs(bm1
, bm2
));
258 DRD_(bm_access_load_4
)(bm1
, i
);
259 DRD_(bm_access_store_4
)(bm1
, i
);
260 DRD_(bm_clear
)(bm1
, i
, i
+ MAX(4, ADDR_GRANULARITY
));
261 assert(bm_equal_print_diffs(bm1
, bm2
));
262 DRD_(bm_access_load_8
)(bm1
, i
);
263 DRD_(bm_access_store_8
)(bm1
, i
);
264 DRD_(bm_clear
)(bm1
, i
, i
+ MAX(8, ADDR_GRANULARITY
));
265 assert(bm_equal_print_diffs(bm1
, bm2
));
268 DRD_(bm_access_range_load
)(bm1
, 0, make_address(2, 0) + 2 * BITS_PER_UWORD
);
269 DRD_(bm_access_range_store
)(bm1
, 0, make_address(2, 0) + 2 * BITS_PER_UWORD
);
270 DRD_(bm_access_range_load
)(bm2
, 0, make_address(2, 0) + 2 * BITS_PER_UWORD
);
271 DRD_(bm_access_range_store
)(bm2
, 0, make_address(2, 0) + 2 * BITS_PER_UWORD
);
272 for (i
= make_address(1, 0) - 2 * BITS_PER_UWORD
;
273 i
< make_address(1, 0) + 2 * BITS_PER_UWORD
;
274 i
+= outer_loop_step
)
276 for (j
= i
+ 1; j
< ub
; j
+= inner_loop_step
)
278 DRD_(bm_clear_load
)(bm1
, i
, j
);
279 DRD_(bm_access_range_load
)(bm1
, i
, j
);
280 assert(bm_equal_print_diffs(bm1
, bm2
));
281 DRD_(bm_clear_load
)(bm1
, i
, i
+1);
282 DRD_(bm_access_load_1
)(bm1
, i
);
283 assert(bm_equal_print_diffs(bm1
, bm2
));
284 DRD_(bm_clear_load
)(bm1
, i
, i
+2);
285 DRD_(bm_access_load_2
)(bm1
, i
);
286 assert(bm_equal_print_diffs(bm1
, bm2
));
287 DRD_(bm_clear_load
)(bm1
, i
, i
+4);
288 DRD_(bm_access_load_4
)(bm1
, i
);
289 assert(bm_equal_print_diffs(bm1
, bm2
));
290 DRD_(bm_clear_load
)(bm1
, i
, i
+8);
291 DRD_(bm_access_load_8
)(bm1
, i
);
292 assert(bm_equal_print_diffs(bm1
, bm2
));
294 DRD_(bm_clear_store
)(bm1
, i
, j
);
295 DRD_(bm_access_range_store
)(bm1
, i
, j
);
296 assert(bm_equal_print_diffs(bm1
, bm2
));
297 DRD_(bm_clear_store
)(bm1
, i
, i
+1);
298 DRD_(bm_access_store_1
)(bm1
, i
);
299 assert(bm_equal_print_diffs(bm1
, bm2
));
300 DRD_(bm_clear_store
)(bm1
, i
, i
+2);
301 DRD_(bm_access_store_2
)(bm1
, i
);
302 assert(bm_equal_print_diffs(bm1
, bm2
));
303 DRD_(bm_clear_store
)(bm1
, i
, i
+4);
304 DRD_(bm_access_store_4
)(bm1
, i
);
305 assert(bm_equal_print_diffs(bm1
, bm2
));
306 DRD_(bm_clear_store
)(bm1
, i
, i
+8);
307 DRD_(bm_access_store_8
)(bm1
, i
);
308 assert(bm_equal_print_diffs(bm1
, bm2
));
310 DRD_(bm_clear
)(bm1
, i
, j
);
311 DRD_(bm_access_range_load
)(bm1
, i
, j
);
312 DRD_(bm_access_range_store
)(bm1
, i
, j
);
313 assert(bm_equal_print_diffs(bm1
, bm2
));
316 DRD_(bm_delete
)(bm2
);
317 DRD_(bm_delete
)(bm1
);
320 int main(int argc
, char** argv
)
322 int outer_loop_step
= ADDR_GRANULARITY
;
323 int inner_loop_step
= ADDR_GRANULARITY
;
326 while ((optchar
= getopt(argc
, argv
, "s:t:q")) != EOF
)
331 outer_loop_step
= atoi(optarg
);
334 inner_loop_step
= atoi(optarg
);
341 "Usage: %s [-s<outer_loop_step>] [-t<inner_loop_step>] [-q].\n",
347 fprintf(stderr
, "Start of DRD BM unit test.\n");
349 DRD_(bm_module_init
)();
352 bm_test3(outer_loop_step
, inner_loop_step
);
353 DRD_(bm_module_cleanup
)();
355 fprintf(stderr
, "End of DRD BM unit test.\n");