2 This file is part of drd, a thread error detector.
4 Copyright (C) 2006-2020 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, see <http://www.gnu.org/licenses/>.
19 The GNU General Public License is contained in the file COPYING.
23 #include "drd_basics.h" /* DRD_() */
24 #include "drd_bitmap.h"
25 #include "drd_error.h"
26 #include "drd_suppression.h"
27 #include "pub_drd_bitmap.h"
28 #include "pub_tool_basics.h" /* Addr, SizeT */
29 #include "pub_tool_libcassert.h" /* tl_assert() */
30 #include "pub_tool_libcbase.h" /* VG_(memset) */
31 #include "pub_tool_libcprint.h" /* VG_(printf) */
32 #include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
35 /* Local function declarations. */
37 static void bm2_merge(struct bitmap2
* const bm2l
,
38 const struct bitmap2
* const bm2r
);
39 static void bm2_print(const struct bitmap2
* const bm2
);
42 /* Local variables. */
44 static OSet
* s_bm2_set_template
;
45 static ULong s_bitmap_creation_count
;
46 static ULong s_bitmap_merge_count
;
47 static ULong s_bitmap2_merge_count
;
50 /* Function definitions. */
52 void DRD_(bm_module_init
)(void)
54 tl_assert(!s_bm2_set_template
);
56 = VG_(OSetGen_Create_With_Pool
)(0, 0, VG_(malloc
), "drd.bitmap.bn.2",
57 VG_(free
), 512, sizeof(struct bitmap2
));
60 void DRD_(bm_module_cleanup
)(void)
62 tl_assert(s_bm2_set_template
);
63 VG_(OSetGen_Destroy
)(s_bm2_set_template
);
64 s_bm2_set_template
= NULL
;
67 struct bitmap
* DRD_(bm_new
)()
71 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
72 /* in drd_bitmap.h. */
73 tl_assert((1 << BITS_PER_BITS_PER_UWORD
) == BITS_PER_UWORD
);
75 bm
= VG_(malloc
)("drd.bitmap.bn.1", sizeof(*bm
));
81 void DRD_(bm_delete
)(struct bitmap
* const bm
)
89 /** Initialize *bm. */
90 void DRD_(bm_init
)(struct bitmap
* const bm
)
96 * Cache initialization. a1 is initialized with a value that never can
97 * match any valid address: the upper (ADDR_LSB_BITS + ADDR_IGNORED_BITS)
98 * bits of a1 are always zero for a valid cache entry.
100 for (i
= 0; i
< DRD_BITMAP_N_CACHE_ELEM
; i
++)
102 bm
->cache
[i
].a1
= ~(UWord
)1;
103 bm
->cache
[i
].bm2
= 0;
105 bm
->oset
= VG_(OSetGen_EmptyClone
)(s_bm2_set_template
);
107 s_bitmap_creation_count
++;
110 /** Free the memory allocated by DRD_(bm_init)(). */
111 void DRD_(bm_cleanup
)(struct bitmap
* const bm
)
113 VG_(OSetGen_Destroy
)(bm
->oset
);
117 * Record an access of type access_type at addresses a .. a + size - 1 in
120 * @note The current implementation of bm_access_range does not work for the
121 * highest addresses in the address range. At least on Linux this is
122 * not a problem since the upper part of the address space is reserved
125 void DRD_(bm_access_range
)(struct bitmap
* const bm
,
126 const Addr a1
, const Addr a2
,
127 const BmAccessTypeT access_type
)
129 tl_assert(access_type
== eLoad
|| access_type
== eStore
);
131 if (access_type
== eLoad
)
132 return DRD_(bm_access_range_load
)(bm
, a1
, a2
);
134 return DRD_(bm_access_range_store
)(bm
, a1
, a2
);
137 void DRD_(bm_access_range_load
)(struct bitmap
* const bm
, Addr a1
, Addr a2
)
143 tl_assert(a2
< first_address_with_higher_msb(a2
));
144 tl_assert(a1
== first_address_with_same_lsb(a1
));
145 tl_assert(a2
== first_address_with_same_lsb(a2
));
147 for (b
= a1
; b
< a2
; b
= b_next
)
154 b_next
= first_address_with_higher_msb(b
);
160 bm2
= bm2_lookup_or_insert_exclusive(bm
, address_msb(b
));
163 if (make_address(bm2
->addr
, 0) < a1
)
166 if (make_address(bm2
->addr
, 0) < a2
)
167 b_start
= make_address(bm2
->addr
, 0);
171 if (make_address(bm2
->addr
+ 1, 0) < a2
)
172 b_end
= make_address(bm2
->addr
+ 1, 0);
176 tl_assert(a1
<= b_start
&& b_start
< b_end
&& b_end
&& b_end
<= a2
);
177 tl_assert(address_msb(b_start
) == address_msb(b_end
- 1));
178 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
180 if (address_lsb(b_start
) == 0 && address_lsb(b_end
) == 0)
184 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
186 bm2
->bm1
.bm0_r
[k
] = ~(UWord
)0;
191 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
193 bm0_set(bm2
->bm1
.bm0_r
, b0
);
199 void DRD_(bm_access_load_1
)(struct bitmap
* const bm
, const Addr a1
)
201 bm_access_aligned_load(bm
, a1
, 1);
204 void DRD_(bm_access_load_2
)(struct bitmap
* const bm
, const Addr a1
)
207 bm_access_aligned_load(bm
, a1
, 2);
209 DRD_(bm_access_range
)(bm
, a1
, a1
+ 2, eLoad
);
212 void DRD_(bm_access_load_4
)(struct bitmap
* const bm
, const Addr a1
)
215 bm_access_aligned_load(bm
, a1
, 4);
217 DRD_(bm_access_range
)(bm
, a1
, a1
+ 4, eLoad
);
220 void DRD_(bm_access_load_8
)(struct bitmap
* const bm
, const Addr a1
)
223 bm_access_aligned_load(bm
, a1
, 8);
224 else if ((a1
& 3) == 0)
226 bm_access_aligned_load(bm
, a1
+ 0, 4);
227 bm_access_aligned_load(bm
, a1
+ 4, 4);
230 DRD_(bm_access_range
)(bm
, a1
, a1
+ 8, eLoad
);
233 void DRD_(bm_access_range_store
)(struct bitmap
* const bm
,
234 const Addr a1
, const Addr a2
)
240 tl_assert(a2
< first_address_with_higher_msb(a2
));
241 tl_assert(a1
== first_address_with_same_lsb(a1
));
242 tl_assert(a2
== first_address_with_same_lsb(a2
));
244 for (b
= a1
; b
< a2
; b
= b_next
)
251 b_next
= first_address_with_higher_msb(b
);
257 bm2
= bm2_lookup_or_insert_exclusive(bm
, address_msb(b
));
260 if (make_address(bm2
->addr
, 0) < a1
)
263 if (make_address(bm2
->addr
, 0) < a2
)
264 b_start
= make_address(bm2
->addr
, 0);
268 if (make_address(bm2
->addr
+ 1, 0) < a2
)
269 b_end
= make_address(bm2
->addr
+ 1, 0);
273 tl_assert(a1
<= b_start
&& b_start
< b_end
&& b_end
&& b_end
<= a2
);
274 tl_assert(address_msb(b_start
) == address_msb(b_end
- 1));
275 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
277 if (address_lsb(b_start
) == 0 && address_lsb(b_end
) == 0)
281 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
283 bm2
->bm1
.bm0_w
[k
] = ~(UWord
)0;
288 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
290 bm0_set(bm2
->bm1
.bm0_w
, b0
);
296 void DRD_(bm_access_store_1
)(struct bitmap
* const bm
, const Addr a1
)
298 bm_access_aligned_store(bm
, a1
, 1);
301 void DRD_(bm_access_store_2
)(struct bitmap
* const bm
, const Addr a1
)
304 bm_access_aligned_store(bm
, a1
, 2);
306 DRD_(bm_access_range
)(bm
, a1
, a1
+ 2, eStore
);
309 void DRD_(bm_access_store_4
)(struct bitmap
* const bm
, const Addr a1
)
312 bm_access_aligned_store(bm
, a1
, 4);
314 DRD_(bm_access_range
)(bm
, a1
, a1
+ 4, eStore
);
317 void DRD_(bm_access_store_8
)(struct bitmap
* const bm
, const Addr a1
)
320 bm_access_aligned_store(bm
, a1
, 8);
321 else if ((a1
& 3) == 0)
323 bm_access_aligned_store(bm
, a1
+ 0, 4);
324 bm_access_aligned_store(bm
, a1
+ 4, 4);
327 DRD_(bm_access_range
)(bm
, a1
, a1
+ 8, eStore
);
330 Bool
DRD_(bm_has
)(struct bitmap
* const bm
, const Addr a1
, const Addr a2
,
331 const BmAccessTypeT access_type
)
333 tl_assert(access_type
== eLoad
|| access_type
== eStore
);
335 if (access_type
== eLoad
)
336 return DRD_(bm_has_any_load
)(bm
, a1
, a2
);
338 return DRD_(bm_has_any_store
)(bm
, a1
, a2
);
341 Bool
DRD_(bm_has_any_load_g
)(struct bitmap
* const bm
)
347 VG_(OSetGen_ResetIter
)(bm
->oset
);
348 for ( ; (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != NULL
; ) {
352 const struct bitmap1
* const p1
= &bm2
->bm1
;
354 b_start
= make_address(bm2
->addr
, 0);
355 b_end
= make_address(bm2
->addr
+ 1, 0);
357 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
358 if (bm0_is_set(p1
->bm0_r
, b0
))
365 DRD_(bm_has_any_load
)(struct bitmap
* const bm
, const Addr a1
, const Addr a2
)
371 for (b
= a1
; b
< a2
; b
= b_next
)
373 const struct bitmap2
* bm2
= bm2_lookup(bm
, address_msb(b
));
375 b_next
= first_address_with_higher_msb(b
);
386 const struct bitmap1
* const p1
= &bm2
->bm1
;
388 if (make_address(bm2
->addr
, 0) < a1
)
391 if (make_address(bm2
->addr
, 0) < a2
)
392 b_start
= make_address(bm2
->addr
, 0);
395 tl_assert(a1
<= b_start
&& b_start
<= a2
);
397 if (make_address(bm2
->addr
+ 1, 0) < a2
)
398 b_end
= make_address(bm2
->addr
+ 1, 0);
401 tl_assert(a1
<= b_end
&& b_end
<= a2
);
402 tl_assert(b_start
< b_end
);
403 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
405 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
407 if (bm0_is_set(p1
->bm0_r
, b0
))
417 Bool
DRD_(bm_has_any_store
)(struct bitmap
* const bm
,
418 const Addr a1
, const Addr a2
)
424 for (b
= a1
; b
< a2
; b
= b_next
)
426 const struct bitmap2
* bm2
= bm2_lookup(bm
, address_msb(b
));
428 b_next
= first_address_with_higher_msb(b
);
439 const struct bitmap1
* const p1
= &bm2
->bm1
;
441 if (make_address(bm2
->addr
, 0) < a1
)
444 if (make_address(bm2
->addr
, 0) < a2
)
445 b_start
= make_address(bm2
->addr
, 0);
448 tl_assert(a1
<= b_start
&& b_start
<= a2
);
450 if (make_address(bm2
->addr
+ 1, 0) < a2
)
451 b_end
= make_address(bm2
->addr
+ 1, 0);
454 tl_assert(a1
<= b_end
&& b_end
<= a2
);
455 tl_assert(b_start
< b_end
);
456 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
458 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
460 if (bm0_is_set(p1
->bm0_w
, b0
))
470 /* Return True if there is a read access, write access or both */
471 /* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
472 Bool
DRD_(bm_has_any_access
)(struct bitmap
* const bm
,
473 const Addr a1
, const Addr a2
)
479 for (b
= a1
; b
< a2
; b
= b_next
)
481 const struct bitmap2
* bm2
= bm2_lookup(bm
, address_msb(b
));
483 b_next
= first_address_with_higher_msb(b
);
494 const struct bitmap1
* const p1
= &bm2
->bm1
;
496 if (make_address(bm2
->addr
, 0) < a1
)
499 if (make_address(bm2
->addr
, 0) < a2
)
500 b_start
= make_address(bm2
->addr
, 0);
503 tl_assert(a1
<= b_start
&& b_start
<= a2
);
505 if (make_address(bm2
->addr
+ 1, 0) < a2
)
506 b_end
= make_address(bm2
->addr
+ 1, 0);
509 tl_assert(a1
<= b_end
&& b_end
<= a2
);
510 tl_assert(b_start
< b_end
);
511 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
513 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
516 * Note: the statement below uses a binary or instead of a logical
519 if (bm0_is_set(p1
->bm0_r
, b0
) | bm0_is_set(p1
->bm0_w
, b0
))
530 * Report whether an access of type access_type at address a is recorded in
533 Bool
DRD_(bm_has_1
)(struct bitmap
* const bm
,
534 const Addr a
, const BmAccessTypeT access_type
)
536 const struct bitmap2
* p2
;
537 const struct bitmap1
* p1
;
539 const UWord a0
= address_lsb(a
);
543 p2
= bm2_lookup(bm
, address_msb(a
));
547 p0
= (access_type
== eLoad
) ? p1
->bm0_r
: p1
->bm0_w
;
548 return bm0_is_set(p0
, a0
) ? True
: False
;
553 void DRD_(bm_clear
)(struct bitmap
* const bm
, Addr a1
, Addr a2
)
560 tl_assert(a1
== first_address_with_same_lsb(a1
));
561 tl_assert(a2
== first_address_with_same_lsb(a2
));
563 for (b
= a1
; b
< a2
; b
= b_next
)
568 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
569 tl_assert(a1
<= b
&& b
< a2
);
572 p2
= bm2_lookup_exclusive(bm
, address_msb(b
));
574 b_next
= first_address_with_higher_msb(b
);
584 /* If the first address in the bitmap that must be cleared does not */
585 /* start on an UWord boundary, start clearing the first addresses. */
586 if (uword_lsb(address_lsb(c
)))
588 Addr c_next
= first_address_with_higher_uword_msb(c
);
591 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
592 tl_assert(a1
<= b
&& b
<= c
&& c
<= c_next
&& c_next
<= b_next
595 bm0_clear_range(p2
->bm1
.bm0_r
, address_lsb(c
), SCALED_SIZE(c_next
- c
));
596 bm0_clear_range(p2
->bm1
.bm0_w
, address_lsb(c
), SCALED_SIZE(c_next
- c
));
599 /* If some UWords have to be cleared entirely, do this now. */
600 if (uword_lsb(address_lsb(c
)) == 0)
602 Addr c_next
= first_address_with_same_uword_lsb(b_next
);
603 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
604 tl_assert(uword_lsb(address_lsb(c
)) == 0);
605 tl_assert(uword_lsb(address_lsb(c_next
)) == 0);
606 tl_assert(c_next
<= b_next
);
610 UWord idx
= uword_msb(address_lsb(c
));
611 VG_(memset
)(&p2
->bm1
.bm0_r
[idx
], 0, SCALED_SIZE((c_next
- c
) / 8));
612 VG_(memset
)(&p2
->bm1
.bm0_w
[idx
], 0, SCALED_SIZE((c_next
- c
) / 8));
616 /* If the last address in the bitmap that must be cleared does not */
617 /* fall on an UWord boundary, clear the last addresses. */
618 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
619 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
621 bm0_clear_range(p2
->bm1
.bm0_r
, address_lsb(c
), SCALED_SIZE(b_next
- c
));
622 bm0_clear_range(p2
->bm1
.bm0_w
, address_lsb(c
), SCALED_SIZE(b_next
- c
));
627 * Clear all references to loads in bitmap bm starting at address a1 and
628 * up to but not including address a2.
630 void DRD_(bm_clear_load
)(struct bitmap
* const bm
, Addr a1
, Addr a2
)
637 tl_assert(a1
== first_address_with_same_lsb(a1
));
638 tl_assert(a2
== first_address_with_same_lsb(a2
));
640 for (b
= a1
; b
< a2
; b
= b_next
)
645 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
646 tl_assert(a1
<= b
&& b
< a2
);
649 p2
= bm2_lookup_exclusive(bm
, address_msb(b
));
651 b_next
= first_address_with_higher_msb(b
);
661 /* If the first address in the bitmap that must be cleared does not */
662 /* start on an UWord boundary, start clearing the first addresses. */
663 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
664 tl_assert(a1
<= b
&& b
<= c
&& c
< b_next
&& b_next
<= a2
);
666 if (uword_lsb(address_lsb(c
)))
668 Addr c_next
= first_address_with_higher_uword_msb(c
);
671 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
672 tl_assert(a1
<= b
&& b
<= c
&& c
< c_next
&& c_next
<= b_next
675 bm0_clear_range(p2
->bm1
.bm0_r
, address_lsb(c
), SCALED_SIZE(c_next
- c
));
678 /* If some UWords have to be cleared entirely, do this now. */
679 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
680 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
682 if (uword_lsb(address_lsb(c
)) == 0)
684 Addr c_next
= first_address_with_same_uword_lsb(b_next
);
685 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
686 tl_assert(uword_lsb(address_lsb(c
)) == 0);
687 tl_assert(uword_lsb(address_lsb(c_next
)) == 0);
688 tl_assert(a1
<= b
&& b
<= c
&& c
<= c_next
&& c_next
<= b_next
693 UWord idx
= uword_msb(address_lsb(c
));
694 VG_(memset
)(&p2
->bm1
.bm0_r
[idx
], 0, SCALED_SIZE((c_next
- c
) / 8));
698 /* If the last address in the bitmap that must be cleared does not */
699 /* fall on an UWord boundary, clear the last addresses. */
700 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
701 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
703 bm0_clear_range(p2
->bm1
.bm0_r
, address_lsb(c
), SCALED_SIZE(b_next
- c
));
708 * Clear all references to stores in bitmap bm starting at address a1 and
709 * up to but not including address a2.
711 void DRD_(bm_clear_store
)(struct bitmap
* const bm
,
712 const Addr a1
, const Addr a2
)
719 tl_assert(a1
== first_address_with_same_lsb(a1
));
720 tl_assert(a2
== first_address_with_same_lsb(a2
));
722 for (b
= a1
; b
< a2
; b
= b_next
)
727 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
728 tl_assert(a1
<= b
&& b
< a2
);
731 p2
= bm2_lookup_exclusive(bm
, address_msb(b
));
733 b_next
= first_address_with_higher_msb(b
);
743 /* If the first address in the bitmap that must be cleared does not */
744 /* start on an UWord boundary, start clearing the first addresses. */
745 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
746 tl_assert(a1
<= b
&& b
<= c
&& c
< b_next
&& b_next
<= a2
);
748 if (uword_lsb(address_lsb(c
)))
750 Addr c_next
= first_address_with_higher_uword_msb(c
);
753 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
754 tl_assert(a1
<= b
&& b
<= c
&& c
< c_next
&& c_next
<= b_next
757 bm0_clear_range(p2
->bm1
.bm0_w
, address_lsb(c
), SCALED_SIZE(c_next
- c
));
760 /* If some UWords have to be cleared entirely, do this now. */
761 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
762 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
764 if (uword_lsb(address_lsb(c
)) == 0)
766 Addr c_next
= first_address_with_same_uword_lsb(b_next
);
767 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
768 tl_assert(uword_lsb(address_lsb(c
)) == 0);
769 tl_assert(uword_lsb(address_lsb(c_next
)) == 0);
770 tl_assert(a1
<= b
&& b
<= c
&& c
<= c_next
&& c_next
<= b_next
775 UWord idx
= uword_msb(address_lsb(c
));
776 VG_(memset
)(&p2
->bm1
.bm0_w
[idx
], 0, SCALED_SIZE((c_next
- c
) / 8));
780 /* If the last address in the bitmap that must be cleared does not */
781 /* fall on an UWord boundary, clear the last addresses. */
782 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
783 tl_assert(a1
<= b
&& b
<= c
&& c
<= b_next
&& b_next
<= a2
);
785 bm0_clear_range(p2
->bm1
.bm0_w
, address_lsb(c
), SCALED_SIZE(b_next
- c
));
790 * Clear bitmap bm starting at address a1 and up to but not including address
791 * a2. Return True if and only if any of the addresses was set before
794 Bool
DRD_(bm_test_and_clear
)(struct bitmap
* const bm
,
795 const Addr a1
, const Addr a2
)
799 result
= DRD_(bm_has_any_access
)(bm
, a1
, a2
) != 0;
800 DRD_(bm_clear
)(bm
, a1
, a2
);
804 Bool
DRD_(bm_has_conflict_with
)(struct bitmap
* const bm
,
805 const Addr a1
, const Addr a2
,
806 const BmAccessTypeT access_type
)
812 for (b
= a1
; b
< a2
; b
= b_next
)
814 const struct bitmap2
* bm2
= bm2_lookup(bm
, address_msb(b
));
816 b_next
= first_address_with_higher_msb(b
);
827 const struct bitmap1
* const p1
= &bm2
->bm1
;
829 if (make_address(bm2
->addr
, 0) < a1
)
832 if (make_address(bm2
->addr
, 0) < a2
)
833 b_start
= make_address(bm2
->addr
, 0);
836 tl_assert(a1
<= b_start
&& b_start
<= a2
);
838 if (make_address(bm2
->addr
+ 1, 0) < a2
)
839 b_end
= make_address(bm2
->addr
+ 1, 0);
842 tl_assert(a1
<= b_end
&& b_end
<= a2
);
843 tl_assert(b_start
< b_end
);
844 tl_assert(address_lsb(b_start
) <= address_lsb(b_end
- 1));
846 for (b0
= address_lsb(b_start
); b0
<= address_lsb(b_end
- 1); b0
++)
848 if (access_type
== eLoad
)
850 if (bm0_is_set(p1
->bm0_w
, b0
))
857 tl_assert(access_type
== eStore
);
858 if (bm0_is_set(p1
->bm0_r
, b0
)
859 | bm0_is_set(p1
->bm0_w
, b0
))
870 Bool
DRD_(bm_load_has_conflict_with
)(struct bitmap
* const bm
,
871 const Addr a1
, const Addr a2
)
873 return DRD_(bm_has_conflict_with
)(bm
, a1
, a2
, eLoad
);
876 Bool
DRD_(bm_load_1_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
878 return bm_aligned_load_has_conflict_with(bm
, a1
, 1);
881 Bool
DRD_(bm_load_2_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
884 return bm_aligned_load_has_conflict_with(bm
, a1
, 2);
886 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 2, eLoad
);
889 Bool
DRD_(bm_load_4_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
892 return bm_aligned_load_has_conflict_with(bm
, a1
, 4);
894 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 4, eLoad
);
897 Bool
DRD_(bm_load_8_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
900 return bm_aligned_load_has_conflict_with(bm
, a1
, 8);
902 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 8, eLoad
);
905 Bool
DRD_(bm_store_1_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
907 return bm_aligned_store_has_conflict_with(bm
, a1
, 1);
910 Bool
DRD_(bm_store_2_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
913 return bm_aligned_store_has_conflict_with(bm
, a1
, 2);
915 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 2, eStore
);
918 Bool
DRD_(bm_store_4_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
921 return bm_aligned_store_has_conflict_with(bm
, a1
, 4);
923 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 4, eStore
);
926 Bool
DRD_(bm_store_8_has_conflict_with
)(struct bitmap
* const bm
, const Addr a1
)
929 return bm_aligned_store_has_conflict_with(bm
, a1
, 8);
931 return DRD_(bm_has_conflict_with
)(bm
, a1
, a1
+ 8, eStore
);
934 Bool
DRD_(bm_store_has_conflict_with
)(struct bitmap
* const bm
,
935 const Addr a1
, const Addr a2
)
937 return DRD_(bm_has_conflict_with
)(bm
, a1
, a2
, eStore
);
941 * Return True if the two bitmaps *lhs and *rhs are identical, and false
944 Bool
DRD_(bm_equal
)(struct bitmap
* const lhs
, struct bitmap
* const rhs
)
946 struct bitmap2
* bm2l
;
947 struct bitmap2
* bm2r
;
949 /* It's not possible to have two independent iterators over the same OSet, */
950 /* so complain if lhs == rhs. */
951 tl_assert(lhs
!= rhs
);
953 VG_(OSetGen_ResetIter
)(lhs
->oset
);
954 VG_(OSetGen_ResetIter
)(rhs
->oset
);
956 for ( ; (bm2l
= VG_(OSetGen_Next
)(lhs
->oset
)) != 0; )
959 && ! DRD_(bm_has_any_access
)(lhs
,
960 make_address(bm2l
->addr
, 0),
961 make_address(bm2l
->addr
+ 1, 0)))
963 bm2l
= VG_(OSetGen_Next
)(lhs
->oset
);
971 bm2r
= VG_(OSetGen_Next
)(rhs
->oset
);
975 while (! DRD_(bm_has_any_access
)(rhs
,
976 make_address(bm2r
->addr
, 0),
977 make_address(bm2r
->addr
+ 1, 0)));
980 tl_assert(DRD_(bm_has_any_access
)(rhs
,
981 make_address(bm2r
->addr
, 0),
982 make_address(bm2r
->addr
+ 1, 0)));
985 && (bm2l
->addr
!= bm2r
->addr
986 || VG_(memcmp
)(&bm2l
->bm1
, &bm2r
->bm1
, sizeof(bm2l
->bm1
)) != 0))
994 bm2r
= VG_(OSetGen_Next
)(rhs
->oset
);
995 } while (bm2r
&& ! DRD_(bm_has_any_access
)(rhs
,
996 make_address(bm2r
->addr
, 0),
997 make_address(bm2r
->addr
+ 1, 0)));
1000 tl_assert(DRD_(bm_has_any_access
)(rhs
,
1001 make_address(bm2r
->addr
, 0),
1002 make_address(bm2r
->addr
+ 1, 0)));
1008 void DRD_(bm_swap
)(struct bitmap
* const bm1
, struct bitmap
* const bm2
)
1010 OSet
* const tmp
= bm1
->oset
;
1011 bm1
->oset
= bm2
->oset
;
1015 /** Merge bitmaps *lhs and *rhs into *lhs. */
1016 void DRD_(bm_merge2
)(struct bitmap
* const lhs
, struct bitmap
* const rhs
)
1018 struct bitmap2
* bm2l
;
1019 struct bitmap2
* bm2r
;
1022 * It's not possible to have two independent iterators over the same OSet,
1023 * so complain if lhs == rhs.
1025 tl_assert(lhs
!= rhs
);
1027 s_bitmap_merge_count
++;
1029 VG_(OSetGen_ResetIter
)(rhs
->oset
);
1031 for ( ; (bm2r
= VG_(OSetGen_Next
)(rhs
->oset
)) != 0; )
1033 bm2l
= VG_(OSetGen_Lookup
)(lhs
->oset
, &bm2r
->addr
);
1036 tl_assert(bm2l
!= bm2r
);
1037 bm2_merge(bm2l
, bm2r
);
1041 bm2_insert_copy(lhs
, bm2r
);
1046 /** Clear bitmap2::recalc. */
1047 void DRD_(bm_unmark
)(struct bitmap
* bm
)
1049 struct bitmap2
* bm2
;
1051 for (VG_(OSetGen_ResetIter
)(bm
->oset
);
1052 (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != 0;
1055 bm2
->recalc
= False
;
1060 * Report whether bitmap2::recalc has been set for the second level bitmap
1061 * corresponding to address a.
1063 Bool
DRD_(bm_is_marked
)(struct bitmap
* bm
, const Addr a
)
1065 const struct bitmap2
* bm2
;
1067 bm2
= bm2_lookup(bm
, a
);
1068 return bm2
&& bm2
->recalc
;
1072 * Set bitmap2::recalc in bml for each second level bitmap in bmr that contains
1073 * at least one access.
1075 * @note Any new second-level bitmaps inserted in bml by this function are
1078 void DRD_(bm_mark
)(struct bitmap
* bml
, struct bitmap
* bmr
)
1080 struct bitmap2
* bm2l
;
1081 struct bitmap2
* bm2r
;
1083 for (VG_(OSetGen_ResetIter
)(bmr
->oset
);
1084 (bm2r
= VG_(OSetGen_Next
)(bmr
->oset
)) != 0;
1087 bm2l
= bm2_lookup_or_insert(bml
, bm2r
->addr
);
1088 bm2l
->recalc
= True
;
1092 /** Clear all second-level bitmaps for which bitmap2::recalc == True. */
1093 void DRD_(bm_clear_marked
)(struct bitmap
* bm
)
1095 struct bitmap2
* bm2
;
1097 for (VG_(OSetGen_ResetIter
)(bm
->oset
);
1098 (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != 0;
1106 /** Merge the second level bitmaps from *rhs into *lhs for which recalc == True. */
1107 void DRD_(bm_merge2_marked
)(struct bitmap
* const lhs
, struct bitmap
* const rhs
)
1109 struct bitmap2
* bm2l
;
1110 struct bitmap2
* bm2r
;
1113 * It's not possible to have two independent iterators over the same OSet,
1114 * so complain if lhs == rhs.
1116 tl_assert(lhs
!= rhs
);
1118 s_bitmap_merge_count
++;
1120 VG_(OSetGen_ResetIter
)(rhs
->oset
);
1122 for ( ; (bm2r
= VG_(OSetGen_Next
)(rhs
->oset
)) != 0; )
1124 bm2l
= VG_(OSetGen_Lookup
)(lhs
->oset
, &bm2r
->addr
);
1125 if (bm2l
&& bm2l
->recalc
)
1127 tl_assert(bm2l
!= bm2r
);
1128 bm2_merge(bm2l
, bm2r
);
1133 /** Remove all marked second-level bitmaps that do not contain any access. */
1134 void DRD_(bm_remove_cleared_marked
)(struct bitmap
* bm
)
1136 struct bitmap2
* bm2
;
1138 VG_(OSetGen_ResetIter
)(bm
->oset
);
1139 for ( ; (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != 0; )
1141 const UWord a1
= bm2
->addr
;
1143 && ! DRD_(bm_has_any_access(bm
, make_address(a1
, 0),
1144 make_address(a1
+ 1, 0))))
1147 VG_(OSetGen_ResetIterAt
)(bm
->oset
, &a1
);
1153 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
1154 * @param lhs First bitmap.
1155 * @param rhs Bitmap to be compared with lhs.
1156 * @return !=0 if there are data races, == 0 if there are none.
1158 int DRD_(bm_has_races
)(struct bitmap
* const lhs
, struct bitmap
* const rhs
)
1160 VG_(OSetGen_ResetIter
)(lhs
->oset
);
1161 VG_(OSetGen_ResetIter
)(rhs
->oset
);
1165 const struct bitmap2
* bm2l
;
1166 const struct bitmap2
* bm2r
;
1167 const struct bitmap1
* bm1l
;
1168 const struct bitmap1
* bm1r
;
1171 bm2l
= VG_(OSetGen_Next
)(lhs
->oset
);
1172 bm2r
= VG_(OSetGen_Next
)(rhs
->oset
);
1173 while (bm2l
&& bm2r
&& bm2l
->addr
!= bm2r
->addr
)
1175 if (bm2l
->addr
< bm2r
->addr
)
1176 bm2l
= VG_(OSetGen_Next
)(lhs
->oset
);
1178 bm2r
= VG_(OSetGen_Next
)(rhs
->oset
);
1180 if (bm2l
== 0 || bm2r
== 0)
1186 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
1189 for (b
= 0; b
< BITS_PER_UWORD
; b
++)
1191 UWord
const access_mask
1192 = ((bm1l
->bm0_r
[k
] & bm0_mask(b
)) ? LHS_R
: 0)
1193 | ((bm1l
->bm0_w
[k
] & bm0_mask(b
)) ? LHS_W
: 0)
1194 | ((bm1r
->bm0_r
[k
] & bm0_mask(b
)) ? RHS_R
: 0)
1195 | ((bm1r
->bm0_w
[k
] & bm0_mask(b
)) ? RHS_W
: 0);
1196 Addr
const a
= make_address(bm2l
->addr
, k
* BITS_PER_UWORD
| b
);
1197 if (HAS_RACE(access_mask
) && ! DRD_(is_suppressed
)(a
, a
+ 1))
1207 void DRD_(bm_print
)(struct bitmap
* const bm
)
1209 struct bitmap2
* bm2
;
1211 for (VG_(OSetGen_ResetIter
)(bm
->oset
);
1212 (bm2
= VG_(OSetGen_Next
)(bm
->oset
)) != 0;
1219 static void bm2_print(const struct bitmap2
* const bm2
)
1221 const struct bitmap1
* bm1
;
1227 for (a
= make_address(bm2
->addr
, 0);
1228 a
<= make_address(bm2
->addr
+ 1, 0) - 1;
1231 const Bool r
= bm0_is_set(bm1
->bm0_r
, address_lsb(a
)) != 0;
1232 const Bool w
= bm0_is_set(bm1
->bm0_w
, address_lsb(a
)) != 0;
1235 VG_(printf
)("0x%08lx %c %c\n",
1243 ULong
DRD_(bm_get_bitmap_creation_count
)(void)
1245 return s_bitmap_creation_count
;
1248 ULong
DRD_(bm_get_bitmap2_creation_count
)(void)
1250 return s_bitmap2_creation_count
;
1253 ULong
DRD_(bm_get_bitmap2_merge_count
)(void)
1255 return s_bitmap2_merge_count
;
1258 /** Compute *bm2l |= *bm2r. */
1260 void bm2_merge(struct bitmap2
* const bm2l
, const struct bitmap2
* const bm2r
)
1266 tl_assert(bm2l
->addr
== bm2r
->addr
);
1268 s_bitmap2_merge_count
++;
1270 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
1272 bm2l
->bm1
.bm0_r
[k
] |= bm2r
->bm1
.bm0_r
[k
];
1274 for (k
= 0; k
< BITMAP1_UWORD_COUNT
; k
++)
1276 bm2l
->bm1
.bm0_w
[k
] |= bm2r
->bm1
.bm0_w
[k
];