blob: 280943c6cba7064784cc2284427a99dd6d8a5e03 [file] [log] [blame]
bart8f822af2009-06-08 18:20:42 +00001/** @brief Unit-test for DRD's bitmap implementation. */
2
3
bart34eff982008-05-01 13:50:20 +00004#include <assert.h>
bartf28b7d12008-05-01 15:00:16 +00005#include <stdio.h>
bart34eff982008-05-01 13:50:20 +00006#include <stdlib.h>
7#include <string.h>
bartfb088fd2008-05-04 07:47:21 +00008#include <unistd.h>
bart34eff982008-05-01 13:50:20 +00009#include "coregrind/m_oset.c"
bartccf17de2008-07-04 15:14:35 +000010#include "drd/drd_bitmap.c"
bart6584b692009-06-21 10:11:15 +000011#include "drd/drd_bitmap2_node.c"
bartccf17de2008-07-04 15:14:35 +000012#include "drd/pub_drd_bitmap.h"
bart34eff982008-05-01 13:50:20 +000013
14
bart7b706b32009-05-10 06:55:39 +000015#ifndef MIN
16#define MIN(x, y) ((x) < (y) ? (x) : (y))
17#endif
18#ifndef MAX
19#define MAX(x, y) ((x) > (y) ? (x) : (y))
20#endif
21
22
bart8f822af2009-06-08 18:20:42 +000023/* Replacements for Valgrind core functionality. */
bart34eff982008-05-01 13:50:20 +000024
sewardj9c606bd2008-09-18 18:12:50 +000025void* VG_(malloc)(HChar* cc, SizeT nbytes)
bart34eff982008-05-01 13:50:20 +000026{ return malloc(nbytes); }
27void VG_(free)(void* p)
28{ return free(p); }
barta9eba352008-05-10 05:49:58 +000029void VG_(assert_fail)(Bool isCore, const Char* assertion, const Char* file,
30 Int line, const Char* function, const HChar* format,
31 ...)
32{
33 fprintf(stderr,
34 "%s:%u: %s%sAssertion `%s' failed.\n",
35 file,
36 line,
37 function ? (char*)function : "",
38 function ? ": " : "",
39 assertion);
bart7b706b32009-05-10 06:55:39 +000040 fflush(stdout);
barta9eba352008-05-10 05:49:58 +000041 fflush(stderr);
42 abort();
sewardj8be88602008-05-06 23:01:05 +000043}
44
bart34eff982008-05-01 13:50:20 +000045void* VG_(memset)(void *s, Int c, SizeT sz)
46{ return memset(s, c, sz); }
47void* VG_(memcpy)(void *d, const void *s, SizeT sz)
48{ return memcpy(d, s, sz); }
49Int VG_(memcmp)(const void* s1, const void* s2, SizeT n)
50{ return memcmp(s1, s2, n); }
51UInt VG_(printf)(const HChar *format, ...)
52{ UInt ret; va_list vargs; va_start(vargs, format); ret = vprintf(format, vargs); va_end(vargs); return ret; }
bartfb088fd2008-05-04 07:47:21 +000053UInt VG_(message)(VgMsgKind kind, const HChar* format, ...)
54{ UInt ret; va_list vargs; va_start(vargs, format); ret = vprintf(format, vargs); va_end(vargs); printf("\n"); return ret; }
bart1335ecc2009-02-14 16:10:53 +000055Bool DRD_(is_suppressed)(const Addr a1, const Addr a2)
bart34eff982008-05-01 13:50:20 +000056{ assert(0); }
57
58
bartfb088fd2008-05-04 07:47:21 +000059/* Actual unit test */
60
61static int s_verbose = 1;
62
bart34eff982008-05-01 13:50:20 +000063static
64struct { Addr address; SizeT size; BmAccessTypeT access_type; }
bartfb088fd2008-05-04 07:47:21 +000065 s_test1_args[] = {
66 { 0, 1, eLoad },
67 { 666, 4, eLoad },
68 { 667, 2, eStore },
69 { 1024, 1, eStore },
70 { 0xffffULL, 1, eStore },
71 { 0x0001ffffULL, 1, eLoad },
72 { 0x00ffffffULL, 1, eLoad },
bart7b706b32009-05-10 06:55:39 +000073 { 0xffffffffULL - (((1 << ADDR_LSB_BITS) + 1) << ADDR_IGNORED_BITS),
74 1, eStore },
sewardj8be88602008-05-06 23:01:05 +000075#if defined(VGP_amd64_linux) || defined(VGP_ppc64_linux) || defined(VGP_ppc64_aix5)
bart7b706b32009-05-10 06:55:39 +000076 { 0xffffffffULL - (1 << ADDR_LSB_BITS << ADDR_IGNORED_BITS),
77 1, eStore },
bartfb088fd2008-05-04 07:47:21 +000078 { 0xffffffffULL, 1, eStore },
79 { 0x100000000ULL, 1, eStore },
bart7b706b32009-05-10 06:55:39 +000080 { -2ULL - (1 << ADDR_LSB_BITS << ADDR_IGNORED_BITS),
81 1, eStore },
bartfb088fd2008-05-04 07:47:21 +000082#endif
bart34eff982008-05-01 13:50:20 +000083 };
84
bartc67d1532009-04-23 15:39:46 +000085/**
86 * Compare two bitmaps and if different, print the differences.
87 */
88int bm_equal_print_diffs(struct bitmap* bm1, struct bitmap* bm2)
89{
90 int equal;
91
92 equal = DRD_(bm_equal)(bm1, bm2);
bart0605e5a2009-05-03 18:07:07 +000093 if (s_verbose && ! equal)
bartc67d1532009-04-23 15:39:46 +000094 {
bart7b706b32009-05-10 06:55:39 +000095 unsigned i;
96
bartc67d1532009-04-23 15:39:46 +000097 VG_(printf)("Bitmaps are different.\n");
bart7b706b32009-05-10 06:55:39 +000098 for (i = 0; i < 0x10000; i++)
99 {
100 if (DRD_(bm_has_1)(bm1, i, eLoad) != DRD_(bm_has_1)(bm2, i, eLoad)
101 || DRD_(bm_has_1)(bm1, i, eStore) != DRD_(bm_has_1)(bm2, i, eStore))
102 {
103 printf("0x%x %c %c %c %c\n",
104 i,
105 DRD_(bm_has_1)(bm1, i, eLoad) ? 'R' : ' ',
106 DRD_(bm_has_1)(bm1, i, eStore) ? 'W' : ' ',
107 DRD_(bm_has_1)(bm2, i, eLoad) ? 'R' : ' ',
108 DRD_(bm_has_1)(bm2, i, eStore) ? 'W' : ' '
109 );
110 }
111 }
112 fflush(stdout);
bartc67d1532009-04-23 15:39:46 +0000113 }
114
115 return equal;
116}
117
bartfb088fd2008-05-04 07:47:21 +0000118void bm_test1(void)
bart34eff982008-05-01 13:50:20 +0000119{
120 struct bitmap* bm;
121 struct bitmap* bm2;
122 unsigned i, j;
123
bart39934d62009-02-15 16:18:03 +0000124 bm = DRD_(bm_new)();
bart34eff982008-05-01 13:50:20 +0000125
bartfb088fd2008-05-04 07:47:21 +0000126 for (i = 0; i < sizeof(s_test1_args)/sizeof(s_test1_args[0]); i++)
bart34eff982008-05-01 13:50:20 +0000127 {
bart39934d62009-02-15 16:18:03 +0000128 DRD_(bm_access_range)(bm,
129 s_test1_args[i].address,
130 s_test1_args[i].address + s_test1_args[i].size,
131 s_test1_args[i].access_type);
bart34eff982008-05-01 13:50:20 +0000132 }
133
bartfb088fd2008-05-04 07:47:21 +0000134 for (i = 0; i < sizeof(s_test1_args)/sizeof(s_test1_args[0]); i++)
135 {
bart7b706b32009-05-10 06:55:39 +0000136 for (j = 0;
137 first_address_with_higher_lsb(j) <= s_test1_args[i].size;
138 j = first_address_with_higher_lsb(j))
bart34eff982008-05-01 13:50:20 +0000139 {
bart39934d62009-02-15 16:18:03 +0000140 tl_assert(DRD_(bm_has_1)(bm,
141 s_test1_args[i].address + j,
142 s_test1_args[i].access_type));
bart34eff982008-05-01 13:50:20 +0000143 }
144 }
145
bart39934d62009-02-15 16:18:03 +0000146 bm2 = DRD_(bm_new)();
147 DRD_(bm_merge2)(bm2, bm);
148 DRD_(bm_merge2)(bm2, bm);
bartc67d1532009-04-23 15:39:46 +0000149 assert(bm_equal_print_diffs(bm2, bm));
bart34eff982008-05-01 13:50:20 +0000150
bartfb088fd2008-05-04 07:47:21 +0000151 if (s_verbose)
152 VG_(printf)("Deleting bitmap bm\n");
bart39934d62009-02-15 16:18:03 +0000153 DRD_(bm_delete)(bm);
bartfb088fd2008-05-04 07:47:21 +0000154 if (s_verbose)
155 VG_(printf)("Deleting bitmap bm2\n");
bart39934d62009-02-15 16:18:03 +0000156 DRD_(bm_delete)(bm2);
bartfb088fd2008-05-04 07:47:21 +0000157}
bart34eff982008-05-01 13:50:20 +0000158
bart214493b2008-05-10 08:21:07 +0000159/** Test whether bm_equal() works correctly. */
bartfb088fd2008-05-04 07:47:21 +0000160void bm_test2()
161{
162 struct bitmap* bm1;
163 struct bitmap* bm2;
164
bart39934d62009-02-15 16:18:03 +0000165 bm1 = DRD_(bm_new)();
166 bm2 = DRD_(bm_new)();
167 DRD_(bm_access_load_1)(bm1, 7);
bart7b706b32009-05-10 06:55:39 +0000168 DRD_(bm_access_load_1)(bm2, make_address(1, 0) + 7);
bart39934d62009-02-15 16:18:03 +0000169 assert(! DRD_(bm_equal)(bm1, bm2));
170 assert(! DRD_(bm_equal)(bm2, bm1));
171 DRD_(bm_access_load_1)(bm2, 7);
172 assert(! DRD_(bm_equal)(bm1, bm2));
173 assert(! DRD_(bm_equal)(bm2, bm1));
bart7b706b32009-05-10 06:55:39 +0000174 DRD_(bm_access_store_1)(bm1, make_address(1, 0) + 7);
bart39934d62009-02-15 16:18:03 +0000175 assert(! DRD_(bm_equal)(bm1, bm2));
176 assert(! DRD_(bm_equal)(bm2, bm1));
177 DRD_(bm_delete)(bm2);
178 DRD_(bm_delete)(bm1);
bart214493b2008-05-10 08:21:07 +0000179}
180
181/** Torture test of the functions that set or clear a range of bits. */
bart2dbdbab2008-05-13 16:17:05 +0000182void bm_test3(const int outer_loop_step, const int inner_loop_step)
bart214493b2008-05-10 08:21:07 +0000183{
184 unsigned i, j;
185 struct bitmap* bm1;
186 struct bitmap* bm2;
187
bart7b706b32009-05-10 06:55:39 +0000188 const Addr lb = make_address(2, 0) - 2 * BITS_PER_UWORD;
189 const Addr ub = make_address(2, 0) + 2 * BITS_PER_UWORD;
bart0605e5a2009-05-03 18:07:07 +0000190
bart2dbdbab2008-05-13 16:17:05 +0000191 assert(outer_loop_step >= 1);
bart7b706b32009-05-10 06:55:39 +0000192 assert((outer_loop_step % ADDR_GRANULARITY) == 0);
bart2dbdbab2008-05-13 16:17:05 +0000193 assert(inner_loop_step >= 1);
bart7b706b32009-05-10 06:55:39 +0000194 assert((inner_loop_step % ADDR_GRANULARITY) == 0);
bart2dbdbab2008-05-13 16:17:05 +0000195
bart39934d62009-02-15 16:18:03 +0000196 bm1 = DRD_(bm_new)();
197 bm2 = DRD_(bm_new)();
bart0605e5a2009-05-03 18:07:07 +0000198 for (i = lb; i < ub; i += outer_loop_step)
bart214493b2008-05-10 08:21:07 +0000199 {
bart7b706b32009-05-10 06:55:39 +0000200 for (j = i + ADDR_GRANULARITY; j < ub; j += inner_loop_step)
bart214493b2008-05-10 08:21:07 +0000201 {
bart39934d62009-02-15 16:18:03 +0000202 DRD_(bm_access_range_load)(bm1, i, j);
203 DRD_(bm_clear_load)(bm1, i, j);
bartc67d1532009-04-23 15:39:46 +0000204 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000205 DRD_(bm_access_load_1)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000206 DRD_(bm_clear_load)(bm1, i, i + MAX(1, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000207 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000208 DRD_(bm_access_load_2)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000209 DRD_(bm_clear_load)(bm1, i, i + MAX(2, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000210 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000211 DRD_(bm_access_load_4)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000212 DRD_(bm_clear_load)(bm1, i, i + MAX(4, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000213 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000214 DRD_(bm_access_load_8)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000215 DRD_(bm_clear_load)(bm1, i, i + MAX(8, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000216 assert(bm_equal_print_diffs(bm1, bm2));
217
bart39934d62009-02-15 16:18:03 +0000218 DRD_(bm_access_range_store)(bm1, i, j);
219 DRD_(bm_clear_store)(bm1, i, j);
bartc67d1532009-04-23 15:39:46 +0000220 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000221 DRD_(bm_access_store_1)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000222 DRD_(bm_clear_store)(bm1, i, i + MAX(1, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000223 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000224 DRD_(bm_access_store_2)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000225 DRD_(bm_clear_store)(bm1, i, i + MAX(2, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000226 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000227 DRD_(bm_access_store_4)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000228 DRD_(bm_clear_store)(bm1, i, i + MAX(4, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000229 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000230 DRD_(bm_access_store_8)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000231 DRD_(bm_clear_store)(bm1, i, i + MAX(8, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000232 assert(bm_equal_print_diffs(bm1, bm2));
233
234 DRD_(bm_access_range_load)(bm1, i, j);
235 DRD_(bm_access_range_store)(bm1, i, j);
236 DRD_(bm_clear)(bm1, i, j);
237 assert(bm_equal_print_diffs(bm1, bm2));
238 DRD_(bm_access_load_1)(bm1, i);
239 DRD_(bm_access_store_1)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000240 DRD_(bm_clear)(bm1, i, i + MAX(1, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000241 assert(bm_equal_print_diffs(bm1, bm2));
242 DRD_(bm_access_load_2)(bm1, i);
243 DRD_(bm_access_store_2)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000244 DRD_(bm_clear)(bm1, i, i + MAX(2, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000245 assert(bm_equal_print_diffs(bm1, bm2));
246 DRD_(bm_access_load_4)(bm1, i);
247 DRD_(bm_access_store_4)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000248 DRD_(bm_clear)(bm1, i, i + MAX(4, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000249 assert(bm_equal_print_diffs(bm1, bm2));
250 DRD_(bm_access_load_8)(bm1, i);
251 DRD_(bm_access_store_8)(bm1, i);
bart7b706b32009-05-10 06:55:39 +0000252 DRD_(bm_clear)(bm1, i, i + MAX(8, ADDR_GRANULARITY));
bartc67d1532009-04-23 15:39:46 +0000253 assert(bm_equal_print_diffs(bm1, bm2));
bart214493b2008-05-10 08:21:07 +0000254 }
255 }
bart7b706b32009-05-10 06:55:39 +0000256 DRD_(bm_access_range_load)(bm1, 0, make_address(2, 0) + 2 * BITS_PER_UWORD);
257 DRD_(bm_access_range_store)(bm1, 0, make_address(2, 0) + 2 * BITS_PER_UWORD);
258 DRD_(bm_access_range_load)(bm2, 0, make_address(2, 0) + 2 * BITS_PER_UWORD);
259 DRD_(bm_access_range_store)(bm2, 0, make_address(2, 0) + 2 * BITS_PER_UWORD);
260 for (i = make_address(1, 0) - 2 * BITS_PER_UWORD;
261 i < make_address(1, 0) + 2 * BITS_PER_UWORD;
bart2dbdbab2008-05-13 16:17:05 +0000262 i += outer_loop_step)
bart214493b2008-05-10 08:21:07 +0000263 {
bart0605e5a2009-05-03 18:07:07 +0000264 for (j = i + 1; j < ub; j += inner_loop_step)
bart214493b2008-05-10 08:21:07 +0000265 {
bart39934d62009-02-15 16:18:03 +0000266 DRD_(bm_clear_load)(bm1, i, j);
267 DRD_(bm_access_range_load)(bm1, i, j);
bartc67d1532009-04-23 15:39:46 +0000268 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000269 DRD_(bm_clear_load)(bm1, i, i+1);
270 DRD_(bm_access_load_1)(bm1, i);
bartc67d1532009-04-23 15:39:46 +0000271 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000272 DRD_(bm_clear_load)(bm1, i, i+2);
273 DRD_(bm_access_load_2)(bm1, i);
bartc67d1532009-04-23 15:39:46 +0000274 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000275 DRD_(bm_clear_load)(bm1, i, i+4);
276 DRD_(bm_access_load_4)(bm1, i);
bartc67d1532009-04-23 15:39:46 +0000277 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000278 DRD_(bm_clear_load)(bm1, i, i+8);
279 DRD_(bm_access_load_8)(bm1, i);
bartc67d1532009-04-23 15:39:46 +0000280 assert(bm_equal_print_diffs(bm1, bm2));
bart0605e5a2009-05-03 18:07:07 +0000281
bart39934d62009-02-15 16:18:03 +0000282 DRD_(bm_clear_store)(bm1, i, j);
283 DRD_(bm_access_range_store)(bm1, i, j);
bartc67d1532009-04-23 15:39:46 +0000284 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000285 DRD_(bm_clear_store)(bm1, i, i+1);
286 DRD_(bm_access_store_1)(bm1, i);
bartc67d1532009-04-23 15:39:46 +0000287 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000288 DRD_(bm_clear_store)(bm1, i, i+2);
289 DRD_(bm_access_store_2)(bm1, i);
bartc67d1532009-04-23 15:39:46 +0000290 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000291 DRD_(bm_clear_store)(bm1, i, i+4);
292 DRD_(bm_access_store_4)(bm1, i);
bartc67d1532009-04-23 15:39:46 +0000293 assert(bm_equal_print_diffs(bm1, bm2));
bart39934d62009-02-15 16:18:03 +0000294 DRD_(bm_clear_store)(bm1, i, i+8);
295 DRD_(bm_access_store_8)(bm1, i);
bartc67d1532009-04-23 15:39:46 +0000296 assert(bm_equal_print_diffs(bm1, bm2));
bart0605e5a2009-05-03 18:07:07 +0000297
298 DRD_(bm_clear)(bm1, i, j);
299 DRD_(bm_access_range_load)(bm1, i, j);
300 DRD_(bm_access_range_store)(bm1, i, j);
301 assert(bm_equal_print_diffs(bm1, bm2));
bart214493b2008-05-10 08:21:07 +0000302 }
303 }
bart39934d62009-02-15 16:18:03 +0000304 DRD_(bm_delete)(bm2);
305 DRD_(bm_delete)(bm1);
bart34eff982008-05-01 13:50:20 +0000306}
307
308int main(int argc, char** argv)
309{
bart7b706b32009-05-10 06:55:39 +0000310 int outer_loop_step = ADDR_GRANULARITY;
311 int inner_loop_step = ADDR_GRANULARITY;
bartfb088fd2008-05-04 07:47:21 +0000312 int optchar;
313
bart2dbdbab2008-05-13 16:17:05 +0000314 while ((optchar = getopt(argc, argv, "s:t:q")) != EOF)
bartfb088fd2008-05-04 07:47:21 +0000315 {
316 switch (optchar)
317 {
bart2dbdbab2008-05-13 16:17:05 +0000318 case 's':
319 outer_loop_step = atoi(optarg);
320 break;
321 case 't':
322 inner_loop_step = atoi(optarg);
323 break;
bartfb088fd2008-05-04 07:47:21 +0000324 case 'q':
325 s_verbose = 0;
326 break;
327 default:
bart2dbdbab2008-05-13 16:17:05 +0000328 fprintf(stderr,
329 "Usage: %s [-s<outer_loop_step>] [-t<inner_loop_step>] [-q].\n",
330 argv[0]);
bartfb088fd2008-05-04 07:47:21 +0000331 break;
332 }
333 }
334
bart8f822af2009-06-08 18:20:42 +0000335 fprintf(stderr, "Start of DRD BM unit test.\n");
bartfb088fd2008-05-04 07:47:21 +0000336
337 bm_test1();
338 bm_test2();
bart2dbdbab2008-05-13 16:17:05 +0000339 bm_test3(outer_loop_step, inner_loop_step);
bartfb088fd2008-05-04 07:47:21 +0000340
bart8f822af2009-06-08 18:20:42 +0000341 fprintf(stderr, "End of DRD BM unit test.\n");
bartfb088fd2008-05-04 07:47:21 +0000342
bart34eff982008-05-01 13:50:20 +0000343 return 0;
344}