1 /* -*- mode: C; c-basic-offset: 3; indent-tabs-mode: nil; -*- */
3 This file is part of drd, a thread error detector.
5 Copyright (C) 2006-2011 Bart Van Assche <bvanassche@acm.org>.
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 The GNU General Public License is contained in the file COPYING.
26 #include "drd_basics.h" /* DRD_() */
27 #include "drd_bitmap.h"
28 #include "drd_error.h"
29 #include "drd_suppression.h"
30 #include "pub_drd_bitmap.h"
31 #include "pub_tool_basics.h" /* Addr, SizeT */
32 #include "pub_tool_debuginfo.h" /* VG_(get_objname)() */
33 #include "pub_tool_libcassert.h" /* tl_assert() */
34 #include "pub_tool_libcbase.h" /* VG_(memset) */
35 #include "pub_tool_libcprint.h" /* VG_(printf) */
36 #include "pub_tool_machine.h" /* VG_(get_IP)() */
37 #include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
40 /* Local function declarations. */
42 static void bm2_merge(struct bitmap2* const bm2l,
43 const struct bitmap2* const bm2r);
44 static void bm2_print(const struct bitmap2* const bm2);
47 /* Local variables. */
49 static ULong s_bitmap_creation_count;
50 static ULong s_bitmap_merge_count;
51 static ULong s_bitmap2_merge_count;
54 /* Function definitions. */
56 struct bitmap* DRD_(bm_new)()
60 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
61 /* in drd_bitmap.h. */
62 tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
64 bm = VG_(malloc)("drd.bitmap.bn.1", sizeof(*bm));
70 void DRD_(bm_delete)(struct bitmap* const bm)
78 /** Initialize *bm. */
79 void DRD_(bm_init)(struct bitmap* const bm)
85 * Cache initialization. a1 is initialized with a value that never can
86 * match any valid address: the upper (ADDR_LSB_BITS + ADDR_IGNORED_BITS)
87 * bits of a1 are always zero for a valid cache entry.
89 for (i = 0; i < DRD_BITMAP_N_CACHE_ELEM; i++)
91 bm->cache[i].a1 = ~(UWord)1;
94 bm->oset = VG_(OSetGen_Create)(0, 0, DRD_(bm2_alloc_node),
95 "drd.bitmap.bn.2", DRD_(bm2_free_node));
97 s_bitmap_creation_count++;
100 /** Free the memory allocated by DRD_(bm_init)(). */
101 void DRD_(bm_cleanup)(struct bitmap* const bm)
103 VG_(OSetGen_Destroy)(bm->oset);
107 * Record an access of type access_type at addresses a .. a + size - 1 in
110 * @note The current implementation of bm_access_range does not work for the
111 * highest addresses in the address range. At least on Linux this is
112 * not a problem since the upper part of the address space is reserved
115 void DRD_(bm_access_range)(struct bitmap* const bm,
116 const Addr a1, const Addr a2,
117 const BmAccessTypeT access_type)
119 tl_assert(access_type == eLoad || access_type == eStore);
121 if (access_type == eLoad)
122 return DRD_(bm_access_range_load)(bm, a1, a2);
124 return DRD_(bm_access_range_store)(bm, a1, a2);
127 void DRD_(bm_access_range_load)(struct bitmap* const bm, Addr a1, Addr a2)
133 tl_assert(a2 < first_address_with_higher_msb(a2));
134 tl_assert(a1 == first_address_with_same_lsb(a1));
135 tl_assert(a2 == first_address_with_same_lsb(a2));
137 for (b = a1; b < a2; b = b_next)
144 b_next = first_address_with_higher_msb(b);
150 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
153 if (make_address(bm2->addr, 0) < a1)
156 if (make_address(bm2->addr, 0) < a2)
157 b_start = make_address(bm2->addr, 0);
161 if (make_address(bm2->addr + 1, 0) < a2)
162 b_end = make_address(bm2->addr + 1, 0);
166 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
167 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
168 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
170 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
174 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
176 bm2->bm1.bm0_r[k] = ~(UWord)0;
181 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
183 bm0_set(bm2->bm1.bm0_r, b0);
189 void DRD_(bm_access_load_1)(struct bitmap* const bm, const Addr a1)
191 bm_access_aligned_load(bm, a1, 1);
194 void DRD_(bm_access_load_2)(struct bitmap* const bm, const Addr a1)
197 bm_access_aligned_load(bm, a1, 2);
199 DRD_(bm_access_range)(bm, a1, a1 + 2, eLoad);
202 void DRD_(bm_access_load_4)(struct bitmap* const bm, const Addr a1)
205 bm_access_aligned_load(bm, a1, 4);
207 DRD_(bm_access_range)(bm, a1, a1 + 4, eLoad);
210 void DRD_(bm_access_load_8)(struct bitmap* const bm, const Addr a1)
213 bm_access_aligned_load(bm, a1, 8);
214 else if ((a1 & 3) == 0)
216 bm_access_aligned_load(bm, a1 + 0, 4);
217 bm_access_aligned_load(bm, a1 + 4, 4);
220 DRD_(bm_access_range)(bm, a1, a1 + 8, eLoad);
223 void DRD_(bm_access_range_store)(struct bitmap* const bm,
224 const Addr a1, const Addr a2)
230 tl_assert(a2 < first_address_with_higher_msb(a2));
231 tl_assert(a1 == first_address_with_same_lsb(a1));
232 tl_assert(a2 == first_address_with_same_lsb(a2));
234 for (b = a1; b < a2; b = b_next)
241 b_next = first_address_with_higher_msb(b);
247 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
250 if (make_address(bm2->addr, 0) < a1)
253 if (make_address(bm2->addr, 0) < a2)
254 b_start = make_address(bm2->addr, 0);
258 if (make_address(bm2->addr + 1, 0) < a2)
259 b_end = make_address(bm2->addr + 1, 0);
263 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
264 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
265 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
267 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
271 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
273 bm2->bm1.bm0_w[k] = ~(UWord)0;
278 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
280 bm0_set(bm2->bm1.bm0_w, b0);
286 void DRD_(bm_access_store_1)(struct bitmap* const bm, const Addr a1)
288 bm_access_aligned_store(bm, a1, 1);
291 void DRD_(bm_access_store_2)(struct bitmap* const bm, const Addr a1)
294 bm_access_aligned_store(bm, a1, 2);
296 DRD_(bm_access_range)(bm, a1, a1 + 2, eStore);
299 void DRD_(bm_access_store_4)(struct bitmap* const bm, const Addr a1)
302 bm_access_aligned_store(bm, a1, 4);
304 DRD_(bm_access_range)(bm, a1, a1 + 4, eStore);
307 void DRD_(bm_access_store_8)(struct bitmap* const bm, const Addr a1)
310 bm_access_aligned_store(bm, a1, 8);
311 else if ((a1 & 3) == 0)
313 bm_access_aligned_store(bm, a1 + 0, 4);
314 bm_access_aligned_store(bm, a1 + 4, 4);
317 DRD_(bm_access_range)(bm, a1, a1 + 8, eStore);
320 Bool DRD_(bm_has)(struct bitmap* const bm, const Addr a1, const Addr a2,
321 const BmAccessTypeT access_type)
323 tl_assert(access_type == eLoad || access_type == eStore);
325 if (access_type == eLoad)
326 return DRD_(bm_has_any_load)(bm, a1, a2);
328 return DRD_(bm_has_any_store)(bm, a1, a2);
332 DRD_(bm_has_any_load)(struct bitmap* const bm, const Addr a1, const Addr a2)
338 for (b = a1; b < a2; b = b_next)
340 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
342 b_next = first_address_with_higher_msb(b);
353 const struct bitmap1* const p1 = &bm2->bm1;
355 if (make_address(bm2->addr, 0) < a1)
358 if (make_address(bm2->addr, 0) < a2)
359 b_start = make_address(bm2->addr, 0);
362 tl_assert(a1 <= b_start && b_start <= a2);
364 if (make_address(bm2->addr + 1, 0) < a2)
365 b_end = make_address(bm2->addr + 1, 0);
368 tl_assert(a1 <= b_end && b_end <= a2);
369 tl_assert(b_start < b_end);
370 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
372 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
374 if (bm0_is_set(p1->bm0_r, b0))
384 Bool DRD_(bm_has_any_store)(struct bitmap* const bm,
385 const Addr a1, const Addr a2)
391 for (b = a1; b < a2; b = b_next)
393 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
395 b_next = first_address_with_higher_msb(b);
406 const struct bitmap1* const p1 = &bm2->bm1;
408 if (make_address(bm2->addr, 0) < a1)
411 if (make_address(bm2->addr, 0) < a2)
412 b_start = make_address(bm2->addr, 0);
415 tl_assert(a1 <= b_start && b_start <= a2);
417 if (make_address(bm2->addr + 1, 0) < a2)
418 b_end = make_address(bm2->addr + 1, 0);
421 tl_assert(a1 <= b_end && b_end <= a2);
422 tl_assert(b_start < b_end);
423 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
425 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
427 if (bm0_is_set(p1->bm0_w, b0))
437 /* Return True if there is a read access, write access or both */
438 /* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
439 Bool DRD_(bm_has_any_access)(struct bitmap* const bm,
440 const Addr a1, const Addr a2)
446 for (b = a1; b < a2; b = b_next)
448 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
450 b_next = first_address_with_higher_msb(b);
461 const struct bitmap1* const p1 = &bm2->bm1;
463 if (make_address(bm2->addr, 0) < a1)
466 if (make_address(bm2->addr, 0) < a2)
467 b_start = make_address(bm2->addr, 0);
470 tl_assert(a1 <= b_start && b_start <= a2);
472 if (make_address(bm2->addr + 1, 0) < a2)
473 b_end = make_address(bm2->addr + 1, 0);
476 tl_assert(a1 <= b_end && b_end <= a2);
477 tl_assert(b_start < b_end);
478 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
480 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
483 * Note: the statement below uses a binary or instead of a logical
486 if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
497 * Report whether an access of type access_type at address a is recorded in
500 Bool DRD_(bm_has_1)(struct bitmap* const bm,
501 const Addr a, const BmAccessTypeT access_type)
503 const struct bitmap2* p2;
504 const struct bitmap1* p1;
506 const UWord a0 = address_lsb(a);
510 p2 = bm2_lookup(bm, address_msb(a));
514 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
515 return bm0_is_set(p0, a0) ? True : False;
520 void DRD_(bm_clear)(struct bitmap* const bm, Addr a1, Addr a2)
527 tl_assert(a1 == first_address_with_same_lsb(a1));
528 tl_assert(a2 == first_address_with_same_lsb(a2));
530 for (b = a1; b < a2; b = b_next)
535 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
536 tl_assert(a1 <= b && b < a2);
539 p2 = bm2_lookup_exclusive(bm, address_msb(b));
541 b_next = first_address_with_higher_msb(b);
551 /* If the first address in the bitmap that must be cleared does not */
552 /* start on an UWord boundary, start clearing the first addresses. */
553 if (uword_lsb(address_lsb(c)))
555 Addr c_next = first_address_with_higher_uword_msb(c);
558 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
559 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
562 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
563 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
566 /* If some UWords have to be cleared entirely, do this now. */
567 if (uword_lsb(address_lsb(c)) == 0)
569 Addr c_next = first_address_with_same_uword_lsb(b_next);
570 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
571 tl_assert(uword_lsb(address_lsb(c)) == 0);
572 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
573 tl_assert(c_next <= b_next);
577 UWord idx = uword_msb(address_lsb(c));
578 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
579 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
583 /* If the last address in the bitmap that must be cleared does not */
584 /* fall on an UWord boundary, clear the last addresses. */
585 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
586 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
588 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
589 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
594 * Clear all references to loads in bitmap bm starting at address a1 and
595 * up to but not including address a2.
597 void DRD_(bm_clear_load)(struct bitmap* const bm, Addr a1, Addr a2)
604 tl_assert(a1 == first_address_with_same_lsb(a1));
605 tl_assert(a2 == first_address_with_same_lsb(a2));
607 for (b = a1; b < a2; b = b_next)
612 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
613 tl_assert(a1 <= b && b < a2);
616 p2 = bm2_lookup_exclusive(bm, address_msb(b));
618 b_next = first_address_with_higher_msb(b);
628 /* If the first address in the bitmap that must be cleared does not */
629 /* start on an UWord boundary, start clearing the first addresses. */
630 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
631 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
633 if (uword_lsb(address_lsb(c)))
635 Addr c_next = first_address_with_higher_uword_msb(c);
638 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
639 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
642 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
645 /* If some UWords have to be cleared entirely, do this now. */
646 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
647 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
649 if (uword_lsb(address_lsb(c)) == 0)
651 Addr c_next = first_address_with_same_uword_lsb(b_next);
652 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
653 tl_assert(uword_lsb(address_lsb(c)) == 0);
654 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
655 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
660 UWord idx = uword_msb(address_lsb(c));
661 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
665 /* If the last address in the bitmap that must be cleared does not */
666 /* fall on an UWord boundary, clear the last addresses. */
667 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
668 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
670 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
675 * Clear all references to stores in bitmap bm starting at address a1 and
676 * up to but not including address a2.
678 void DRD_(bm_clear_store)(struct bitmap* const bm,
679 const Addr a1, const Addr a2)
686 tl_assert(a1 == first_address_with_same_lsb(a1));
687 tl_assert(a2 == first_address_with_same_lsb(a2));
689 for (b = a1; b < a2; b = b_next)
694 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
695 tl_assert(a1 <= b && b < a2);
698 p2 = bm2_lookup_exclusive(bm, address_msb(b));
700 b_next = first_address_with_higher_msb(b);
710 /* If the first address in the bitmap that must be cleared does not */
711 /* start on an UWord boundary, start clearing the first addresses. */
712 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
713 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
715 if (uword_lsb(address_lsb(c)))
717 Addr c_next = first_address_with_higher_uword_msb(c);
720 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
721 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
724 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
727 /* If some UWords have to be cleared entirely, do this now. */
728 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
729 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
731 if (uword_lsb(address_lsb(c)) == 0)
733 Addr c_next = first_address_with_same_uword_lsb(b_next);
734 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
735 tl_assert(uword_lsb(address_lsb(c)) == 0);
736 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
737 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
742 UWord idx = uword_msb(address_lsb(c));
743 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
747 /* If the last address in the bitmap that must be cleared does not */
748 /* fall on an UWord boundary, clear the last addresses. */
749 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS
750 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
752 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
757 * Clear bitmap bm starting at address a1 and up to but not including address
758 * a2. Return True if and only if any of the addresses was set before
761 Bool DRD_(bm_test_and_clear)(struct bitmap* const bm,
762 const Addr a1, const Addr a2)
766 result = DRD_(bm_has_any_access)(bm, a1, a2) != 0;
767 DRD_(bm_clear)(bm, a1, a2);
771 Bool DRD_(bm_has_conflict_with)(struct bitmap* const bm,
772 const Addr a1, const Addr a2,
773 const BmAccessTypeT access_type)
779 for (b = a1; b < a2; b = b_next)
781 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
783 b_next = first_address_with_higher_msb(b);
794 const struct bitmap1* const p1 = &bm2->bm1;
796 if (make_address(bm2->addr, 0) < a1)
799 if (make_address(bm2->addr, 0) < a2)
800 b_start = make_address(bm2->addr, 0);
803 tl_assert(a1 <= b_start && b_start <= a2);
805 if (make_address(bm2->addr + 1, 0) < a2)
806 b_end = make_address(bm2->addr + 1, 0);
809 tl_assert(a1 <= b_end && b_end <= a2);
810 tl_assert(b_start < b_end);
811 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
813 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
815 if (access_type == eLoad)
817 if (bm0_is_set(p1->bm0_w, b0))
824 tl_assert(access_type == eStore);
825 if (bm0_is_set(p1->bm0_r, b0)
826 | bm0_is_set(p1->bm0_w, b0))
837 Bool DRD_(bm_load_has_conflict_with)(struct bitmap* const bm,
838 const Addr a1, const Addr a2)
840 return DRD_(bm_has_conflict_with)(bm, a1, a2, eLoad);
843 Bool DRD_(bm_load_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
845 return bm_aligned_load_has_conflict_with(bm, a1, 1);
848 Bool DRD_(bm_load_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
851 return bm_aligned_load_has_conflict_with(bm, a1, 2);
853 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eLoad);
856 Bool DRD_(bm_load_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
859 return bm_aligned_load_has_conflict_with(bm, a1, 4);
861 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eLoad);
864 Bool DRD_(bm_load_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
867 return bm_aligned_load_has_conflict_with(bm, a1, 8);
869 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eLoad);
872 Bool DRD_(bm_store_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
874 return bm_aligned_store_has_conflict_with(bm, a1, 1);
877 Bool DRD_(bm_store_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
880 return bm_aligned_store_has_conflict_with(bm, a1, 2);
882 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eStore);
885 Bool DRD_(bm_store_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
888 return bm_aligned_store_has_conflict_with(bm, a1, 4);
890 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eStore);
893 Bool DRD_(bm_store_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
896 return bm_aligned_store_has_conflict_with(bm, a1, 8);
898 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eStore);
901 Bool DRD_(bm_store_has_conflict_with)(struct bitmap* const bm,
902 const Addr a1, const Addr a2)
904 return DRD_(bm_has_conflict_with)(bm, a1, a2, eStore);
908 * Return True if the two bitmaps *lhs and *rhs are identical, and false
911 Bool DRD_(bm_equal)(struct bitmap* const lhs, struct bitmap* const rhs)
913 struct bitmap2* bm2l;
914 struct bitmap2* bm2r;
916 /* It's not possible to have two independent iterators over the same OSet, */
917 /* so complain if lhs == rhs. */
918 tl_assert(lhs != rhs);
920 VG_(OSetGen_ResetIter)(lhs->oset);
921 VG_(OSetGen_ResetIter)(rhs->oset);
923 for ( ; (bm2l = VG_(OSetGen_Next)(lhs->oset)) != 0; )
926 && ! DRD_(bm_has_any_access)(lhs,
927 make_address(bm2l->addr, 0),
928 make_address(bm2l->addr + 1, 0)))
930 bm2l = VG_(OSetGen_Next)(lhs->oset);
938 bm2r = VG_(OSetGen_Next)(rhs->oset);
942 while (! DRD_(bm_has_any_access)(rhs,
943 make_address(bm2r->addr, 0),
944 make_address(bm2r->addr + 1, 0)));
947 tl_assert(DRD_(bm_has_any_access)(rhs,
948 make_address(bm2r->addr, 0),
949 make_address(bm2r->addr + 1, 0)));
952 && (bm2l->addr != bm2r->addr
953 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
961 bm2r = VG_(OSetGen_Next)(rhs->oset);
962 } while (bm2r && ! DRD_(bm_has_any_access)(rhs,
963 make_address(bm2r->addr, 0),
964 make_address(bm2r->addr + 1, 0)));
967 tl_assert(DRD_(bm_has_any_access)(rhs,
968 make_address(bm2r->addr, 0),
969 make_address(bm2r->addr + 1, 0)));
975 void DRD_(bm_swap)(struct bitmap* const bm1, struct bitmap* const bm2)
977 OSet* const tmp = bm1->oset;
978 bm1->oset = bm2->oset;
982 /** Merge bitmaps *lhs and *rhs into *lhs. */
983 void DRD_(bm_merge2)(struct bitmap* const lhs, struct bitmap* const rhs)
985 struct bitmap2* bm2l;
986 struct bitmap2* bm2r;
989 * It's not possible to have two independent iterators over the same OSet,
990 * so complain if lhs == rhs.
992 tl_assert(lhs != rhs);
994 s_bitmap_merge_count++;
996 VG_(OSetGen_ResetIter)(rhs->oset);
998 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
1000 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1003 tl_assert(bm2l != bm2r);
1004 bm2_merge(bm2l, bm2r);
1008 bm2_insert_copy(lhs, bm2r);
1013 /** Clear bitmap2::recalc. */
1014 void DRD_(bm_unmark)(struct bitmap* bm)
1016 struct bitmap2* bm2;
1018 for (VG_(OSetGen_ResetIter)(bm->oset);
1019 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1022 bm2->recalc = False;
1027 * Report whether bitmap2::recalc has been set for the second level bitmap
1028 * corresponding to address a.
1030 Bool DRD_(bm_is_marked)(struct bitmap* bm, const Addr a)
1032 const struct bitmap2* bm2;
1034 bm2 = bm2_lookup(bm, a);
1035 return bm2 && bm2->recalc;
1039 * Set bitmap2::recalc in bml for each second level bitmap in bmr that contains
1040 * at least one access.
1042 * @note Any new second-level bitmaps inserted in bml by this function are
1045 void DRD_(bm_mark)(struct bitmap* bml, struct bitmap* bmr)
1047 struct bitmap2* bm2l;
1048 struct bitmap2* bm2r;
1050 for (VG_(OSetGen_ResetIter)(bmr->oset);
1051 (bm2r = VG_(OSetGen_Next)(bmr->oset)) != 0;
1054 /*if (DRD_(bm_has_any_access(bmr, make_address(bm2r->addr, 0),
1055 make_address(bm2r->addr + 1, 0))))*/
1057 bm2l = bm2_lookup_or_insert(bml, bm2r->addr);
1058 bm2l->recalc = True;
1063 /** Clear all second-level bitmaps for which bitmap2::recalc == True. */
1064 void DRD_(bm_clear_marked)(struct bitmap* bm)
1066 struct bitmap2* bm2;
1068 for (VG_(OSetGen_ResetIter)(bm->oset);
1069 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1077 /** Merge the second level bitmaps from *rhs into *lhs for which recalc == True. */
1078 void DRD_(bm_merge2_marked)(struct bitmap* const lhs, struct bitmap* const rhs)
1080 struct bitmap2* bm2l;
1081 struct bitmap2* bm2r;
1083 tl_assert(lhs != rhs);
1086 * It's not possible to have two independent iterators over the same OSet,
1087 * so complain if lhs == rhs.
1089 tl_assert(lhs != rhs);
1091 s_bitmap_merge_count++;
1093 VG_(OSetGen_ResetIter)(rhs->oset);
1095 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
1097 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1098 if (bm2l && bm2l->recalc)
1100 tl_assert(bm2l != bm2r);
1101 bm2_merge(bm2l, bm2r);
1106 /** Remove all marked second-level bitmaps that do not contain any access. */
1107 void DRD_(bm_remove_cleared_marked)(struct bitmap* bm)
1109 struct bitmap2* bm2;
1111 VG_(OSetGen_ResetIter)(bm->oset);
1112 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0; )
1114 const UWord a1 = bm2->addr;
1116 && ! DRD_(bm_has_any_access(bm, make_address(a1, 0),
1117 make_address(a1 + 1, 0))))
1120 VG_(OSetGen_ResetIterAt)(bm->oset, &a1);
1126 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
1127 * @param lhs First bitmap.
1128 * @param rhs Bitmap to be compared with lhs.
1129 * @return !=0 if there are data races, == 0 if there are none.
1131 int DRD_(bm_has_races)(struct bitmap* const lhs, struct bitmap* const rhs)
1133 VG_(OSetGen_ResetIter)(lhs->oset);
1134 VG_(OSetGen_ResetIter)(rhs->oset);
1138 const struct bitmap2* bm2l;
1139 const struct bitmap2* bm2r;
1140 const struct bitmap1* bm1l;
1141 const struct bitmap1* bm1r;
1144 bm2l = VG_(OSetGen_Next)(lhs->oset);
1145 bm2r = VG_(OSetGen_Next)(rhs->oset);
1146 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
1148 if (bm2l->addr < bm2r->addr)
1149 bm2l = VG_(OSetGen_Next)(lhs->oset);
1151 bm2r = VG_(OSetGen_Next)(rhs->oset);
1153 if (bm2l == 0 || bm2r == 0)
1159 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1162 for (b = 0; b < BITS_PER_UWORD; b++)
1164 UWord const access_mask
1165 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
1166 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
1167 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
1168 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
1169 Addr const a = make_address(bm2l->addr, k * BITS_PER_UWORD | b);
1170 if (HAS_RACE(access_mask) && ! DRD_(is_suppressed)(a, a + 1))
1180 void DRD_(bm_print)(struct bitmap* const bm)
1182 struct bitmap2* bm2;
1184 for (VG_(OSetGen_ResetIter)(bm->oset);
1185 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1192 static void bm2_print(const struct bitmap2* const bm2)
1194 const struct bitmap1* bm1;
1200 for (a = make_address(bm2->addr, 0);
1201 a <= make_address(bm2->addr + 1, 0) - 1;
1204 const Bool r = bm0_is_set(bm1->bm0_r, address_lsb(a)) != 0;
1205 const Bool w = bm0_is_set(bm1->bm0_w, address_lsb(a)) != 0;
1208 VG_(printf)("0x%08lx %c %c\n",
1216 ULong DRD_(bm_get_bitmap_creation_count)(void)
1218 return s_bitmap_creation_count;
1221 ULong DRD_(bm_get_bitmap2_creation_count)(void)
1223 return s_bitmap2_creation_count;
1226 ULong DRD_(bm_get_bitmap2_merge_count)(void)
1228 return s_bitmap2_merge_count;
1231 /** Compute *bm2l |= *bm2r. */
1233 void bm2_merge(struct bitmap2* const bm2l, const struct bitmap2* const bm2r)
1239 tl_assert(bm2l->addr == bm2r->addr);
1241 s_bitmap2_merge_count++;
1243 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1245 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
1247 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1249 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];