2 This file is part of drd, a thread error detector.
4 Copyright (C) 2006-2017 Bart Van Assche <bvanassche@acm.org>.
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 The GNU General Public License is contained in the file COPYING.
25 #include "drd_basics.h" /* DRD_() */
26 #include "drd_bitmap.h"
27 #include "drd_error.h"
28 #include "drd_suppression.h"
29 #include "pub_drd_bitmap.h"
30 #include "pub_tool_basics.h" /* Addr, SizeT */
31 #include "pub_tool_libcassert.h" /* tl_assert() */
32 #include "pub_tool_libcbase.h" /* VG_(memset) */
33 #include "pub_tool_libcprint.h" /* VG_(printf) */
34 #include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
37 /* Local function declarations. */
39 static void bm2_merge(struct bitmap2
* const bm2l
,
40 const struct bitmap2
* const bm2r
);
41 static void bm2_print(const struct bitmap2
* const bm2
);
44 /* Local variables. */
46 static OSet
* s_bm2_set_template
;
47 static ULong s_bitmap_creation_count
;
48 static ULong s_bitmap_merge_count
;
49 static ULong s_bitmap2_merge_count
;
52 /* Function definitions. */
54 void DRD_(bm_module_init
)(void)
56 tl_assert(!s_bm2_set_template
);
58 = VG_(OSetGen_Create_With_Pool
)(0, 0, VG_(malloc
), "drd.bitmap.bn.2",
59 VG_(free
), 512, sizeof(struct bitmap2
));
62 void DRD_(bm_module_cleanup
)(void)
64 tl_assert(s_bm2_set_template
);
65 VG_(OSetGen_Destroy
)(s_bm2_set_template
);
66 s_bm2_set_template
= NULL
;
69 struct bitmap
* DRD_(bm_new
)()
73 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
74 /* in drd_bitmap.h. */
75 tl_assert((1 << BITS_PER_BITS_PER_UWORD
) == BITS_PER_UWORD
);
77 bm
= VG_(malloc
)("drd.bitmap.bn.1", sizeof(*bm
));
83 void DRD_(bm_delete
)(struct bitmap
* const bm
)
91 /** Initialize *bm. */
92 void DRD_(bm_init
)(struct bitmap
* const bm
)
98 * Cache initialization. a1 is initialized with a value that never can
99 * match any valid address: the upper (ADDR_LSB_BITS + ADDR_IGNORED_BITS)
100 * bits of a1 are always zero for a valid cache entry.
102 for (i
= 0; i
< DRD_BITMAP_N_CACHE_ELEM
; i
++)
104 bm
->cache
[i
].a1
= ~(UWord
)1;
105 bm
->cache
[i
].bm2
= 0;
107 bm
->oset
= VG_(OSetGen_EmptyClone
)(s_bm2_set_template
);
109 s_bitmap_creation_count
++;
112 /** Free the memory allocated by DRD_(bm_init)(). */
113 void DRD_(bm_cleanup
)(struct bitmap
* const bm
)
115 VG_(OSetGen_Destroy
)(bm
->oset
);
119 * Record an access of type access_type at addresses a .. a + size - 1 in
122 * @note The current implementation of bm_access_range does not work for the
123 * highest addresses in the address range. At least on Linux this is
124 * not a problem since the upper part of the address space is reserved
127 void DRD_(bm_access_range
)(struct bitmap
* const bm
,
128 const Addr a1
, const Addr a2
,
129 const BmAccessTypeT access_type
)
131 tl_assert(access_type
== eLoad
|| access_type
== eStore
);
133 if (access_type
== eLoad
)
134 return DRD_(bm_access_range_load
)(bm
, a1
, a2
);
136 return DRD_(bm_access_range_store
)(bm
, a1
, a2
);
139 void DRD_(bm_access_range_load
)(struct bitmap
* const bm
, Addr a1
, Addr a2
)
145 tl_assert(a2
< first_address_with_higher_msb(a2
));
146 tl_assert(a1
== first_address_with_same_lsb(a1
));
147 tl_assert(a2
== first_address_with_same_lsb(a2
));
149 for (b
= a1
; b
< a2
; b
= b_next
)
156 b_next
= first_address_with_higher_msb(b
);
162 bm2
= bm2_lookup_or_insert_exclusive(bm
, address_msb(b
));
165 if (make_address(bm2
->addr
, 0) < a1
)
168 if (make_address(bm2
->addr
, 0) < a2
)
169 b_start
= make_address(bm2
->addr
, 0);
173 if (make_address(bm2
->addr
+ 1, 0) < a2
)
174 b_end
= make_address(bm2
->addr
+ 1, 0);
178 tl_assert(a1
<= b_start
&& b_start
< b_end
&& b_end
&& b_end
<= a2
);
179 tl_assert(address_msb(b_start
) == address_msb(b_end
- 1));
180 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
182 if (address_lsb(b_start
) == 0 && address_lsb(b_end
) == 0)
186 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
188 bm2
->bm1
.bm0_r
[k
] = ~(UWord
)0;
193 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
195 bm0_set(bm2
->bm1
.bm0_r
, b0
);
201 void DRD_(bm_access_load_1
)(struct bitmap
* const bm
, const Addr a1
)
203 bm_access_aligned_load(bm
, a1
, 1);
206 void DRD_(bm_access_load_2
)(struct bitmap
* const bm
, const Addr a1
)
209 bm_access_aligned_load(bm
, a1
, 2);
211 DRD_(bm_access_range
)(bm
, a1
, a1
+ 2, eLoad
);
214 void DRD_(bm_access_load_4
)(struct bitmap
* const bm
, const Addr a1
)
217 bm_access_aligned_load(bm
, a1
, 4);
219 DRD_(bm_access_range
)(bm
, a1
, a1
+ 4, eLoad
);
222 void DRD_(bm_access_load_8
)(struct bitmap
* const bm
, const Addr a1
)
225 bm_access_aligned_load(bm
, a1
, 8);
226 else if ((a1
& 3) == 0)
228 bm_access_aligned_load(bm
, a1
+ 0, 4);
229 bm_access_aligned_load(bm
, a1
+ 4, 4);
232 DRD_(bm_access_range
)(bm
, a1
, a1
+ 8, eLoad
);
235 void DRD_(bm_access_range_store
)(struct bitmap
* const bm
,
236 const Addr a1
, const Addr a2
)
242 tl_assert(a2
< first_address_with_higher_msb(a2
));
243 tl_assert(a1
== first_address_with_same_lsb(a1
));
244 tl_assert(a2
== first_address_with_same_lsb(a2
));
246 for (b
= a1
; b
< a2
; b
= b_next
)
253 b_next
= first_address_with_higher_msb(b
);
259 bm2
= bm2_lookup_or_insert_exclusive(bm
, address_msb(b
));
262 if (make_address(bm2
->addr
, 0) < a1
)
265 if (make_address(bm2
->addr
, 0) < a2
)
266 b_start
= make_address(bm2
->addr
, 0);
270 if (make_address(bm2
->addr
+ 1, 0) < a2
)
271 b_end
= make_address(bm2
->addr
+ 1, 0);
275 tl_assert(a1
<= b_start
&& b_start
< b_end
&& b_end
&& b_end
<= a2
);
276 tl_assert(address_msb(b_start
) == address_msb(b_end
- 1));
277 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
279 if (address_lsb(b_start
) == 0 && address_lsb(b_end
) == 0)
283 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
285 bm2
->bm1
.bm0_w
[k
] = ~(UWord
)0;
290 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
292 bm0_set(bm2
->bm1
.bm0_w
, b0
);
298 void DRD_(bm_access_store_1
)(struct bitmap
* const bm
, const Addr a1
)
300 bm_access_aligned_store(bm
, a1
, 1);
303 void DRD_(bm_access_store_2
)(struct bitmap
* const bm
, const Addr a1
)
306 bm_access_aligned_store(bm
, a1
, 2);
308 DRD_(bm_access_range
)(bm
, a1
, a1
+ 2, eStore
);
311 void DRD_(bm_access_store_4
)(struct bitmap
* const bm
, const Addr a1
)
314 bm_access_aligned_store(bm
, a1
, 4);
316 DRD_(bm_access_range
)(bm
, a1
, a1
+ 4, eStore
);
319 void DRD_(bm_access_store_8
)(struct bitmap
* const bm
, const Addr a1
)
322 bm_access_aligned_store(bm
, a1
, 8);
323 else if ((a1
& 3) == 0)
325 bm_access_aligned_store(bm
, a1
+ 0, 4);
326 bm_access_aligned_store(bm
, a1
+ 4, 4);
329 DRD_(bm_access_range
)(bm
, a1
, a1
+ 8, eStore
);
332 Bool
DRD_(bm_has
)(struct bitmap
* const bm
, const Addr a1
, const Addr a2
,
333 const BmAccessTypeT access_type
)
335 tl_assert(access_type
== eLoad
|| access_type
== eStore
);
337 if (access_type
== eLoad
)
338 return DRD_(bm_has_any_load
)(bm
, a1
, a2
);
340 return DRD_(bm_has_any_store
)(bm
, a1
, a2
);
343 Bool
DRD_(bm_has_any_load_g
)(struct bitmap
* const bm
)
349 VG_(OSetGen_ResetIter
)(bm
->oset
);
350 for ( ; (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != NULL
; ) {
354 const struct bitmap1
* const p1
= &bm2
->bm1
;
356 b_start
= make_address(bm2
->addr
, 0);
357 b_end
= make_address(bm2
->addr
+ 1, 0);
359 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
360 if (bm0_is_set(p1
->bm0_r
, b0
))
367 DRD_(bm_has_any_load
)(struct bitmap
* const bm
, const Addr a1
, const Addr a2
)
373 for (b
= a1
; b
< a2
; b
= b_next
)
375 const struct bitmap2
* bm2
= bm2_lookup(bm
, address_msb(b
));
377 b_next
= first_address_with_higher_msb(b
);
388 const struct bitmap1
* const p1
= &bm2
->bm1
;
390 if (make_address(bm2
->addr
, 0) < a1
)
393 if (make_address(bm2
->addr
, 0) < a2
)
394 b_start
= make_address(bm2
->addr
, 0);
397 tl_assert(a1
<= b_start
&& b_start
<= a2
);
399 if (make_address(bm2
->addr
+ 1, 0) < a2
)
400 b_end
= make_address(bm2
->addr
+ 1, 0);
403 tl_assert(a1
<= b_end
&& b_end
<= a2
);
404 tl_assert(b_start
< b_end
);
405 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
407 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
409 if (bm0_is_set(p1
->bm0_r
, b0
))
419 Bool
DRD_(bm_has_any_store
)(struct bitmap
* const bm
,
420 const Addr a1
, const Addr a2
)
426 for (b
= a1
; b
< a2
; b
= b_next
)
428 const struct bitmap2
* bm2
= bm2_lookup(bm
, address_msb(b
));
430 b_next
= first_address_with_higher_msb(b
);
441 const struct bitmap1
* const p1
= &bm2
->bm1
;
443 if (make_address(bm2
->addr
, 0) < a1
)
446 if (make_address(bm2
->addr
, 0) < a2
)
447 b_start
= make_address(bm2
->addr
, 0);
450 tl_assert(a1
<= b_start
&& b_start
<= a2
);
452 if (make_address(bm2
->addr
+ 1, 0) < a2
)
453 b_end
= make_address(bm2
->addr
+ 1, 0);
456 tl_assert(a1
<= b_end
&& b_end
<= a2
);
457 tl_assert(b_start
< b_end
);
458 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
460 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
462 if (bm0_is_set(p1
->bm0_w
, b0
))
472 /* Return True if there is a read access, write access or both */
473 /* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
474 Bool
DRD_(bm_has_any_access
)(struct bitmap
* const bm
,
475 const Addr a1
, const Addr a2
)
481 for (b
= a1
; b
< a2
; b
= b_next
)
483 const struct bitmap2
* bm2
= bm2_lookup(bm
, address_msb(b
));
485 b_next
= first_address_with_higher_msb(b
);
496 const struct bitmap1
* const p1
= &bm2
->bm1
;
498 if (make_address(bm2
->addr
, 0) < a1
)
501 if (make_address(bm2
->addr
, 0) < a2
)
502 b_start
= make_address(bm2
->addr
, 0);
505 tl_assert(a1
<= b_start
&& b_start
<= a2
);
507 if (make_address(bm2
->addr
+ 1, 0) < a2
)
508 b_end
= make_address(bm2
->addr
+ 1, 0);
511 tl_assert(a1
<= b_end
&& b_end
<= a2
);
512 tl_assert(b_start
< b_end
);
513 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
515 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
518 * Note: the statement below uses a binary or instead of a logical
521 if (bm0_is_set(p1
->bm0_r
, b0
) | bm0_is_set(p1
->bm0_w
, b0
))
532 * Report whether an access of type access_type at address a is recorded in
535 Bool
DRD_(bm_has_1
)(struct bitmap
* const bm
,
536 const Addr a
, const BmAccessTypeT access_type
)
538 const struct bitmap2
* p2
;
539 const struct bitmap1
* p1
;
541 const UWord a0
= address_lsb(a
);
545 p2
= bm2_lookup(bm
, address_msb(a
));
549 p0
= (access_type
== eLoad
) ? p1
->bm0_r
: p1
->bm0_w
;
550 return bm0_is_set(p0
, a0
) ? True
: False
;
555 void DRD_(bm_clear
)(struct bitmap
* const bm
, Addr a1
, Addr a2
)
562 tl_assert(a1
== first_address_with_same_lsb(a1
));
563 tl_assert(a2
== first_address_with_same_lsb(a2
));
565 for (b
= a1
; b
< a2
; b
= b_next
)
570 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
571 tl_assert(a1
<= b
&& b
< a2
);
574 p2
= bm2_lookup_exclusive(bm
, address_msb(b
));
576 b_next
= first_address_with_higher_msb(b
);
586 /* If the first address in the bitmap that must be cleared does not */
587 /* start on an UWord boundary, start clearing the first addresses. */
588 if (uword_lsb(address_lsb(c
)))
590 Addr c_next
= first_address_with_higher_uword_msb(c
);
593 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
594 tl_assert(a1
<= b
&& b
<= c
&& c
<= c_next
&& c_next
<= b_next
597 bm0_clear_range(p2
->bm1
.bm0_r
, address_lsb(c
), SCALED_SIZE(c_next
- c
));
598 bm0_clear_range(p2
->bm1
.bm0_w
, address_lsb(c
), SCALED_SIZE(c_next
- c
));
601 /* If some UWords have to be cleared entirely, do this now. */
602 if (uword_lsb(address_lsb(c
)) == 0)
604 Addr c_next
= first_address_with_same_uword_lsb(b_next
);
605 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
606 tl_assert(uword_lsb(address_lsb(c
)) == 0);
607 tl_assert(uword_lsb(address_lsb(c_next
)) == 0);
608 tl_assert(c_next
<= b_next
);
612 UWord idx
= uword_msb(address_lsb(c
));
613 VG_(memset
)(&p2
->bm1
.bm0_r
[idx
], 0, SCALED_SIZE((c_next
- c
) / 8));
614 VG_(memset
)(&p2
->bm1
.bm0_w
[idx
], 0, SCALED_SIZE((c_next
- c
) / 8));
618 /* If the last address in the bitmap that must be cleared does not */
619 /* fall on an UWord boundary, clear the last addresses. */
620 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
621 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
623 bm0_clear_range(p2
->bm1
.bm0_r
, address_lsb(c
), SCALED_SIZE(b_next
- c
));
624 bm0_clear_range(p2
->bm1
.bm0_w
, address_lsb(c
), SCALED_SIZE(b_next
- c
));
629 * Clear all references to loads in bitmap bm starting at address a1 and
630 * up to but not including address a2.
632 void DRD_(bm_clear_load
)(struct bitmap
* const bm
, Addr a1
, Addr a2
)
639 tl_assert(a1
== first_address_with_same_lsb(a1
));
640 tl_assert(a2
== first_address_with_same_lsb(a2
));
642 for (b
= a1
; b
< a2
; b
= b_next
)
647 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
648 tl_assert(a1
<= b
&& b
< a2
);
651 p2
= bm2_lookup_exclusive(bm
, address_msb(b
));
653 b_next
= first_address_with_higher_msb(b
);
663 /* If the first address in the bitmap that must be cleared does not */
664 /* start on an UWord boundary, start clearing the first addresses. */
665 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
666 tl_assert(a1
<= b
&& b
<= c
&& c
< b_next
&& b_next
<= a2
);
668 if (uword_lsb(address_lsb(c
)))
670 Addr c_next
= first_address_with_higher_uword_msb(c
);
673 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
674 tl_assert(a1
<= b
&& b
<= c
&& c
< c_next
&& c_next
<= b_next
677 bm0_clear_range(p2
->bm1
.bm0_r
, address_lsb(c
), SCALED_SIZE(c_next
- c
));
680 /* If some UWords have to be cleared entirely, do this now. */
681 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
682 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
684 if (uword_lsb(address_lsb(c
)) == 0)
686 Addr c_next
= first_address_with_same_uword_lsb(b_next
);
687 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
688 tl_assert(uword_lsb(address_lsb(c
)) == 0);
689 tl_assert(uword_lsb(address_lsb(c_next
)) == 0);
690 tl_assert(a1
<= b
&& b
<= c
&& c
<= c_next
&& c_next
<= b_next
695 UWord idx
= uword_msb(address_lsb(c
));
696 VG_(memset
)(&p2
->bm1
.bm0_r
[idx
], 0, SCALED_SIZE((c_next
- c
) / 8));
700 /* If the last address in the bitmap that must be cleared does not */
701 /* fall on an UWord boundary, clear the last addresses. */
702 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
703 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
705 bm0_clear_range(p2
->bm1
.bm0_r
, address_lsb(c
), SCALED_SIZE(b_next
- c
));
710 * Clear all references to stores in bitmap bm starting at address a1 and
711 * up to but not including address a2.
713 void DRD_(bm_clear_store
)(struct bitmap
* const bm
,
714 const Addr a1
, const Addr a2
)
721 tl_assert(a1
== first_address_with_same_lsb(a1
));
722 tl_assert(a2
== first_address_with_same_lsb(a2
));
724 for (b
= a1
; b
< a2
; b
= b_next
)
729 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
730 tl_assert(a1
<= b
&& b
< a2
);
733 p2
= bm2_lookup_exclusive(bm
, address_msb(b
));
735 b_next
= first_address_with_higher_msb(b
);
745 /* If the first address in the bitmap that must be cleared does not */
746 /* start on an UWord boundary, start clearing the first addresses. */
747 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
748 tl_assert(a1
<= b
&& b
<= c
&& c
< b_next
&& b_next
<= a2
);
750 if (uword_lsb(address_lsb(c
)))
752 Addr c_next
= first_address_with_higher_uword_msb(c
);
755 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
756 tl_assert(a1
<= b
&& b
<= c
&& c
< c_next
&& c_next
<= b_next
759 bm0_clear_range(p2
->bm1
.bm0_w
, address_lsb(c
), SCALED_SIZE(c_next
- c
));
762 /* If some UWords have to be cleared entirely, do this now. */
763 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
764 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
766 if (uword_lsb(address_lsb(c
)) == 0)
768 Addr c_next
= first_address_with_same_uword_lsb(b_next
);
769 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
770 tl_assert(uword_lsb(address_lsb(c
)) == 0);
771 tl_assert(uword_lsb(address_lsb(c_next
)) == 0);
772 tl_assert(a1
<= b
&& b
<= c
&& c
<= c_next
&& c_next
<= b_next
777 UWord idx
= uword_msb(address_lsb(c
));
778 VG_(memset
)(&p2
->bm1
.bm0_w
[idx
], 0, SCALED_SIZE((c_next
- c
) / 8));
782 /* If the last address in the bitmap that must be cleared does not */
783 /* fall on an UWord boundary, clear the last addresses. */
784 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
785 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
787 bm0_clear_range(p2
->bm1
.bm0_w
, address_lsb(c
), SCALED_SIZE(b_next
- c
));
792 * Clear bitmap bm starting at address a1 and up to but not including address
793 * a2. Return True if and only if any of the addresses was set before
796 Bool
DRD_(bm_test_and_clear
)(struct bitmap
* const bm
,
797 const Addr a1
, const Addr a2
)
801 result
= DRD_(bm_has_any_access
)(bm
, a1
, a2
) != 0;
802 DRD_(bm_clear
)(bm
, a1
, a2
);
806 Bool
DRD_(bm_has_conflict_with
)(struct bitmap
* const bm
,
807 const Addr a1
, const Addr a2
,
808 const BmAccessTypeT access_type
)
814 for (b
= a1
; b
< a2
; b
= b_next
)
816 const struct bitmap2
* bm2
= bm2_lookup(bm
, address_msb(b
));
818 b_next
= first_address_with_higher_msb(b
);
829 const struct bitmap1
* const p1
= &bm2
->bm1
;
831 if (make_address(bm2
->addr
, 0) < a1
)
834 if (make_address(bm2
->addr
, 0) < a2
)
835 b_start
= make_address(bm2
->addr
, 0);
838 tl_assert(a1
<= b_start
&& b_start
<= a2
);
840 if (make_address(bm2
->addr
+ 1, 0) < a2
)
841 b_end
= make_address(bm2
->addr
+ 1, 0);
844 tl_assert(a1
<= b_end
&& b_end
<= a2
);
845 tl_assert(b_start
< b_end
);
846 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
848 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
850 if (access_type
== eLoad
)
852 if (bm0_is_set(p1
->bm0_w
, b0
))
859 tl_assert(access_type
== eStore
);
860 if (bm0_is_set(p1
->bm0_r
, b0
)
861 | bm0_is_set(p1
->bm0_w
, b0
))
872 Bool
DRD_(bm_load_has_conflict_with
)(struct bitmap
* const bm
,
873 const Addr a1
, const Addr a2
)
875 return DRD_(bm_has_conflict_with
)(bm
, a1
, a2
, eLoad
);
878 Bool
DRD_(bm_load_1_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
880 return bm_aligned_load_has_conflict_with(bm
, a1
, 1);
883 Bool
DRD_(bm_load_2_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
886 return bm_aligned_load_has_conflict_with(bm
, a1
, 2);
888 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 2, eLoad
);
891 Bool
DRD_(bm_load_4_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
894 return bm_aligned_load_has_conflict_with(bm
, a1
, 4);
896 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 4, eLoad
);
899 Bool
DRD_(bm_load_8_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
902 return bm_aligned_load_has_conflict_with(bm
, a1
, 8);
904 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 8, eLoad
);
907 Bool
DRD_(bm_store_1_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
909 return bm_aligned_store_has_conflict_with(bm
, a1
, 1);
912 Bool
DRD_(bm_store_2_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
915 return bm_aligned_store_has_conflict_with(bm
, a1
, 2);
917 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 2, eStore
);
920 Bool
DRD_(bm_store_4_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
923 return bm_aligned_store_has_conflict_with(bm
, a1
, 4);
925 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 4, eStore
);
928 Bool
DRD_(bm_store_8_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
931 return bm_aligned_store_has_conflict_with(bm
, a1
, 8);
933 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 8, eStore
);
936 Bool
DRD_(bm_store_has_conflict_with
)(struct bitmap
* const bm
,
937 const Addr a1
, const Addr a2
)
939 return DRD_(bm_has_conflict_with
)(bm
, a1
, a2
, eStore
);
943 * Return True if the two bitmaps *lhs and *rhs are identical, and false
946 Bool
DRD_(bm_equal
)(struct bitmap
* const lhs
, struct bitmap
* const rhs
)
948 struct bitmap2
* bm2l
;
949 struct bitmap2
* bm2r
;
951 /* It's not possible to have two independent iterators over the same OSet, */
952 /* so complain if lhs == rhs. */
953 tl_assert(lhs
!= rhs
);
955 VG_(OSetGen_ResetIter
)(lhs
->oset
);
956 VG_(OSetGen_ResetIter
)(rhs
->oset
);
958 for ( ; (bm2l
= VG_(OSetGen_Next
)(lhs
->oset
)) != 0; )
961 && ! DRD_(bm_has_any_access
)(lhs
,
962 make_address(bm2l
->addr
, 0),
963 make_address(bm2l
->addr
+ 1, 0)))
965 bm2l
= VG_(OSetGen_Next
)(lhs
->oset
);
973 bm2r
= VG_(OSetGen_Next
)(rhs
->oset
);
977 while (! DRD_(bm_has_any_access
)(rhs
,
978 make_address(bm2r
->addr
, 0),
979 make_address(bm2r
->addr
+ 1, 0)));
982 tl_assert(DRD_(bm_has_any_access
)(rhs
,
983 make_address(bm2r
->addr
, 0),
984 make_address(bm2r
->addr
+ 1, 0)));
987 && (bm2l
->addr
!= bm2r
->addr
988 || VG_(memcmp
)(&bm2l
->bm1
, &bm2r
->bm1
, sizeof(bm2l
->bm1
)) != 0))
996 bm2r
= VG_(OSetGen_Next
)(rhs
->oset
);
997 } while (bm2r
&& ! DRD_(bm_has_any_access
)(rhs
,
998 make_address(bm2r
->addr
, 0),
999 make_address(bm2r
->addr
+ 1, 0)));
1002 tl_assert(DRD_(bm_has_any_access
)(rhs
,
1003 make_address(bm2r
->addr
, 0),
1004 make_address(bm2r
->addr
+ 1, 0)));
1010 void DRD_(bm_swap
)(struct bitmap
* const bm1
, struct bitmap
* const bm2
)
1012 OSet
* const tmp
= bm1
->oset
;
1013 bm1
->oset
= bm2
->oset
;
1017 /** Merge bitmaps *lhs and *rhs into *lhs. */
1018 void DRD_(bm_merge2
)(struct bitmap
* const lhs
, struct bitmap
* const rhs
)
1020 struct bitmap2
* bm2l
;
1021 struct bitmap2
* bm2r
;
1024 * It's not possible to have two independent iterators over the same OSet,
1025 * so complain if lhs == rhs.
1027 tl_assert(lhs
!= rhs
);
1029 s_bitmap_merge_count
++;
1031 VG_(OSetGen_ResetIter
)(rhs
->oset
);
1033 for ( ; (bm2r
= VG_(OSetGen_Next
)(rhs
->oset
)) != 0; )
1035 bm2l
= VG_(OSetGen_Lookup
)(lhs
->oset
, &bm2r
->addr
);
1038 tl_assert(bm2l
!= bm2r
);
1039 bm2_merge(bm2l
, bm2r
);
1043 bm2_insert_copy(lhs
, bm2r
);
1048 /** Clear bitmap2::recalc. */
1049 void DRD_(bm_unmark
)(struct bitmap
* bm
)
1051 struct bitmap2
* bm2
;
1053 for (VG_(OSetGen_ResetIter
)(bm
->oset
);
1054 (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != 0;
1057 bm2
->recalc
= False
;
1062 * Report whether bitmap2::recalc has been set for the second level bitmap
1063 * corresponding to address a.
1065 Bool
DRD_(bm_is_marked
)(struct bitmap
* bm
, const Addr a
)
1067 const struct bitmap2
* bm2
;
1069 bm2
= bm2_lookup(bm
, a
);
1070 return bm2
&& bm2
->recalc
;
1074 * Set bitmap2::recalc in bml for each second level bitmap in bmr that contains
1075 * at least one access.
1077 * @note Any new second-level bitmaps inserted in bml by this function are
1080 void DRD_(bm_mark
)(struct bitmap
* bml
, struct bitmap
* bmr
)
1082 struct bitmap2
* bm2l
;
1083 struct bitmap2
* bm2r
;
1085 for (VG_(OSetGen_ResetIter
)(bmr
->oset
);
1086 (bm2r
= VG_(OSetGen_Next
)(bmr
->oset
)) != 0;
1089 bm2l
= bm2_lookup_or_insert(bml
, bm2r
->addr
);
1090 bm2l
->recalc
= True
;
1094 /** Clear all second-level bitmaps for which bitmap2::recalc == True. */
1095 void DRD_(bm_clear_marked
)(struct bitmap
* bm
)
1097 struct bitmap2
* bm2
;
1099 for (VG_(OSetGen_ResetIter
)(bm
->oset
);
1100 (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != 0;
1108 /** Merge the second level bitmaps from *rhs into *lhs for which recalc == True. */
1109 void DRD_(bm_merge2_marked
)(struct bitmap
* const lhs
, struct bitmap
* const rhs
)
1111 struct bitmap2
* bm2l
;
1112 struct bitmap2
* bm2r
;
1115 * It's not possible to have two independent iterators over the same OSet,
1116 * so complain if lhs == rhs.
1118 tl_assert(lhs
!= rhs
);
1120 s_bitmap_merge_count
++;
1122 VG_(OSetGen_ResetIter
)(rhs
->oset
);
1124 for ( ; (bm2r
= VG_(OSetGen_Next
)(rhs
->oset
)) != 0; )
1126 bm2l
= VG_(OSetGen_Lookup
)(lhs
->oset
, &bm2r
->addr
);
1127 if (bm2l
&& bm2l
->recalc
)
1129 tl_assert(bm2l
!= bm2r
);
1130 bm2_merge(bm2l
, bm2r
);
1135 /** Remove all marked second-level bitmaps that do not contain any access. */
1136 void DRD_(bm_remove_cleared_marked
)(struct bitmap
* bm
)
1138 struct bitmap2
* bm2
;
1140 VG_(OSetGen_ResetIter
)(bm
->oset
);
1141 for ( ; (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != 0; )
1143 const UWord a1
= bm2
->addr
;
1145 && ! DRD_(bm_has_any_access(bm
, make_address(a1
, 0),
1146 make_address(a1
+ 1, 0))))
1149 VG_(OSetGen_ResetIterAt
)(bm
->oset
, &a1
);
1155 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
1156 * @param lhs First bitmap.
1157 * @param rhs Bitmap to be compared with lhs.
1158 * @return !=0 if there are data races, == 0 if there are none.
1160 int DRD_(bm_has_races
)(struct bitmap
* const lhs
, struct bitmap
* const rhs
)
1162 VG_(OSetGen_ResetIter
)(lhs
->oset
);
1163 VG_(OSetGen_ResetIter
)(rhs
->oset
);
1167 const struct bitmap2
* bm2l
;
1168 const struct bitmap2
* bm2r
;
1169 const struct bitmap1
* bm1l
;
1170 const struct bitmap1
* bm1r
;
1173 bm2l
= VG_(OSetGen_Next
)(lhs
->oset
);
1174 bm2r
= VG_(OSetGen_Next
)(rhs
->oset
);
1175 while (bm2l
&& bm2r
&& bm2l
->addr
!= bm2r
->addr
)
1177 if (bm2l
->addr
< bm2r
->addr
)
1178 bm2l
= VG_(OSetGen_Next
)(lhs
->oset
);
1180 bm2r
= VG_(OSetGen_Next
)(rhs
->oset
);
1182 if (bm2l
== 0 || bm2r
== 0)
1188 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
1191 for (b
= 0; b
< BITS_PER_UWORD
; b
++)
1193 UWord
const access_mask
1194 = ((bm1l
->bm0_r
[k
] & bm0_mask(b
)) ? LHS_R
: 0)
1195 | ((bm1l
->bm0_w
[k
] & bm0_mask(b
)) ? LHS_W
: 0)
1196 | ((bm1r
->bm0_r
[k
] & bm0_mask(b
)) ? RHS_R
: 0)
1197 | ((bm1r
->bm0_w
[k
] & bm0_mask(b
)) ? RHS_W
: 0);
1198 Addr
const a
= make_address(bm2l
->addr
, k
* BITS_PER_UWORD
| b
);
1199 if (HAS_RACE(access_mask
) && ! DRD_(is_suppressed
)(a
, a
+ 1))
1209 void DRD_(bm_print
)(struct bitmap
* const bm
)
1211 struct bitmap2
* bm2
;
1213 for (VG_(OSetGen_ResetIter
)(bm
->oset
);
1214 (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != 0;
1221 static void bm2_print(const struct bitmap2
* const bm2
)
1223 const struct bitmap1
* bm1
;
1229 for (a
= make_address(bm2
->addr
, 0);
1230 a
<= make_address(bm2
->addr
+ 1, 0) - 1;
1233 const Bool r
= bm0_is_set(bm1
->bm0_r
, address_lsb(a
)) != 0;
1234 const Bool w
= bm0_is_set(bm1
->bm0_w
, address_lsb(a
)) != 0;
1237 VG_(printf
)("0x%08lx %c %c\n",
1245 ULong
DRD_(bm_get_bitmap_creation_count
)(void)
1247 return s_bitmap_creation_count
;
1250 ULong
DRD_(bm_get_bitmap2_creation_count
)(void)
1252 return s_bitmap2_creation_count
;
1255 ULong
DRD_(bm_get_bitmap2_merge_count
)(void)
1257 return s_bitmap2_merge_count
;
1260 /** Compute *bm2l |= *bm2r. */
1262 void bm2_merge(struct bitmap2
* const bm2l
, const struct bitmap2
* const bm2r
)
1268 tl_assert(bm2l
->addr
== bm2r
->addr
);
1270 s_bitmap2_merge_count
++;
1272 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
1274 bm2l
->bm1
.bm0_r
[k
] |= bm2r
->bm1
.bm0_r
[k
];
1276 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
1278 bm2l
->bm1
.bm0_w
[k
] |= bm2r
->bm1
.bm0_w
[k
];