1 /* 2 This file is part of drd, a thread error detector. 3 4 Copyright (C) 2006-2017 Bart Van Assche <bvanassche@acm.org>. 5 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. 10 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. 15 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 19 02111-1307, USA. 20 21 The GNU General Public License is contained in the file COPYING. 22 */ 23 24 25 #ifndef __DRD_BITMAP_H 26 #define __DRD_BITMAP_H 27 28 29 #include "pub_drd_bitmap.h" 30 #include "pub_tool_basics.h" 31 #include "pub_tool_oset.h" 32 #include "pub_tool_libcbase.h" 33 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 34 #include "pub_tool_libcassert.h" 35 #endif 36 37 38 /* Bitmap representation. A bitmap is a data structure in which two bits are 39 * reserved per 32 bit address: one bit that indicates that the data at the 40 * specified address has been read, and one bit that indicates that the data 41 * has been written to. 42 */ 43 44 /* Client addresses are split into bitfields as follows: 45 * ------------------------------------------------------ 46 * | Address MSB | Address LSB | Ignored bits | 47 * ------------------------------------------------------ 48 * | Address MSB | UWord MSB | UWord LSB | Ignored bits | 49 * ------------------------------------------------------ 50 */ 51 52 53 54 /* Address MSB / LSB split. */ 55 56 57 /** Number of least significant address bits that are ignored. */ 58 #define ADDR_IGNORED_BITS 0 59 #define ADDR_IGNORED_MASK ((1U << ADDR_IGNORED_BITS) - 1U) 60 #define ADDR_GRANULARITY (1U << ADDR_IGNORED_BITS) 61 62 /** 63 * Round argument a up to a multiple of (1 << ADDR_GRANULARITY), and next 64 * shift it right ADDR_GRANULARITY bits. The expression below is optimized 65 * for the case where a is a constant. 66 */ 67 #define SCALED_SIZE(a) \ 68 (((((a) - 1U) | ADDR_IGNORED_MASK) + 1U) >> ADDR_IGNORED_BITS) 69 70 /** 71 * Number of bits assigned to the least significant component of an address. 72 */ 73 #define ADDR_LSB_BITS 12 74 75 /** 76 * Mask that has to be applied to an address of type Addr in order to 77 * compute the least significant part of an address split, after having 78 * shifted the address bits ADDR_GRANULARITY to the right. 79 */ 80 #define ADDR_LSB_MASK (((UWord)1 << ADDR_LSB_BITS) - 1U) 81 82 /** Compute least significant bits of an address of type Addr. */ 83 static __inline__ 84 UWord address_lsb(const Addr a) 85 { return (a >> ADDR_IGNORED_BITS) & ADDR_LSB_MASK; } 86 87 /** 88 * Compute the first address for which address_lsb() is equal to 89 * address_lsb(a). 90 */ 91 static __inline__ 92 Addr first_address_with_same_lsb(const Addr a) 93 { 94 return ((a | ADDR_IGNORED_MASK) ^ ADDR_IGNORED_MASK); 95 } 96 97 /** 98 * Compute the first address for which address_lsb() is greater than 99 * address_lsb(a). 100 */ 101 static __inline__ 102 Addr first_address_with_higher_lsb(const Addr a) 103 { 104 return ((a | ADDR_IGNORED_MASK) + 1U); 105 } 106 107 /** Compute most significant bits of an address of type Addr. */ 108 static __inline__ 109 UWord address_msb(const Addr a) 110 { return a >> (ADDR_LSB_BITS + ADDR_IGNORED_BITS); } 111 112 static __inline__ 113 Addr first_address_with_higher_msb(const Addr a) 114 { 115 return ((a | ((ADDR_LSB_MASK << ADDR_IGNORED_BITS) | ADDR_IGNORED_MASK)) 116 + 1U); 117 } 118 119 /** 120 * Convert LSB and MSB back into an address. 121 * 122 * @note It is assumed that sizeof(Addr) == sizeof(UWord). 123 */ 124 static __inline__ 125 Addr make_address(const UWord a1, const UWord a0) 126 { 127 return ((a1 << (ADDR_LSB_BITS + ADDR_IGNORED_BITS)) 128 | (a0 << ADDR_IGNORED_BITS)); 129 } 130 131 132 133 134 135 /** Number of bits that fit in a variable of type UWord. */ 136 #define BITS_PER_UWORD (8U * sizeof(UWord)) 137 138 /** Log2 of BITS_PER_UWORD. */ 139 #if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_arm) \ 140 || defined(VGA_mips32) 141 #define BITS_PER_BITS_PER_UWORD 5 142 #elif defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \ 143 || defined(VGA_s390x) || defined(VGA_mips64) || defined(VGA_arm64) 144 #define BITS_PER_BITS_PER_UWORD 6 145 #else 146 #error Unknown platform. 147 #endif 148 149 /** Number of UWord's needed to store one bit per address LSB. */ 150 #define BITMAP1_UWORD_COUNT (1U << (ADDR_LSB_BITS - BITS_PER_BITS_PER_UWORD)) 151 152 /** 153 * Mask that has to be applied to an (Addr >> ADDR_IGNORED_BITS) expression 154 * in order to compute the least significant part of an UWord. 155 */ 156 #define UWORD_LSB_MASK (((UWord)1 << BITS_PER_BITS_PER_UWORD) - 1) 157 158 /** 159 * Compute index into bm0[] array. 160 * 161 * @param a Address shifted right ADDR_IGNORED_BITS bits. 162 */ 163 static __inline__ 164 UWord uword_msb(const UWord a) 165 { 166 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 167 tl_assert(a < (1U << ADDR_LSB_BITS)); 168 #endif 169 return a >> BITS_PER_BITS_PER_UWORD; 170 } 171 172 /** 173 * Return the least significant bits. 174 * 175 * @param a Address shifted right ADDR_IGNORED_BITS bits. 176 */ 177 static __inline__ 178 UWord uword_lsb(const UWord a) 179 { 180 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 181 tl_assert(a < (1U << ADDR_LSB_BITS)); 182 #endif 183 return a & UWORD_LSB_MASK; 184 } 185 186 /** 187 * Compute the highest address lower than a for which 188 * uword_lsb(address_lsb(a)) == 0. 189 * 190 * @param a Address. 191 */ 192 static __inline__ 193 Addr first_address_with_same_uword_lsb(const Addr a) 194 { 195 return (a & (~UWORD_LSB_MASK << ADDR_IGNORED_BITS)); 196 } 197 198 /** 199 * First address that will go in the UWord past the one 'a' goes in. 200 * 201 * @param a Address. 202 */ 203 static __inline__ 204 Addr first_address_with_higher_uword_msb(const Addr a) 205 { 206 return ((a | ((UWORD_LSB_MASK << ADDR_IGNORED_BITS) | ADDR_IGNORED_MASK)) 207 + 1); 208 } 209 210 211 212 /* Local variables. */ 213 214 static ULong s_bitmap2_creation_count; 215 216 217 218 /*********************************************************************/ 219 /* Functions for manipulating a struct bitmap1. */ 220 /*********************************************************************/ 221 222 223 /* Lowest level, corresponding to the lowest ADDR_LSB_BITS of an address. */ 224 struct bitmap1 225 { 226 UWord bm0_r[BITMAP1_UWORD_COUNT]; 227 UWord bm0_w[BITMAP1_UWORD_COUNT]; 228 }; 229 230 static __inline__ UWord bm0_mask(const UWord a) 231 { 232 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 233 tl_assert(address_msb(make_address(0, a)) == 0); 234 #endif 235 return ((UWord)1 << uword_lsb(a)); 236 } 237 238 /** Set the bit corresponding to address a in bitmap bm0. */ 239 static __inline__ void bm0_set(UWord* bm0, const UWord a) 240 { 241 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 242 tl_assert(address_msb(make_address(0, a)) == 0); 243 #endif 244 bm0[uword_msb(a)] |= (UWord)1 << uword_lsb(a); 245 } 246 247 /** 248 * Set the bits corresponding to all of the addresses in range 249 * [ a << ADDR_IGNORED_BITS .. (a + size) << ADDR_IGNORED_BITS [ 250 * in bitmap bm0. 251 */ 252 static __inline__ void bm0_set_range(UWord* bm0, 253 const UWord a, const SizeT size) 254 { 255 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 256 tl_assert(size > 0); 257 tl_assert(address_msb(make_address(0, a)) == 0); 258 tl_assert(address_msb(make_address(0, a + size - 1)) == 0); 259 tl_assert(uword_msb(a) == uword_msb(a + size - 1)); 260 #endif 261 bm0[uword_msb(a)] 262 |= (((UWord)1 << size) - 1) << uword_lsb(a); 263 } 264 265 /** Clear the bit corresponding to address a in bitmap bm0. */ 266 static __inline__ void bm0_clear(UWord* bm0, const UWord a) 267 { 268 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 269 tl_assert(address_msb(make_address(0, a)) == 0); 270 #endif 271 bm0[uword_msb(a)] &= ~((UWord)1 << uword_lsb(a)); 272 } 273 274 /** 275 * Clear all of the addresses in range 276 * [ a << ADDR_IGNORED_BITS .. (a + size) << ADDR_IGNORED_BITS [ 277 * in bitmap bm0. 278 */ 279 static __inline__ void bm0_clear_range(UWord* bm0, 280 const UWord a, const SizeT size) 281 { 282 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 283 tl_assert(address_msb(make_address(0, a)) == 0); 284 tl_assert(size == 0 || address_msb(make_address(0, a + size - 1)) == 0); 285 tl_assert(size == 0 || uword_msb(a) == uword_msb(a + size - 1)); 286 #endif 287 /* 288 * Note: although the expression below yields a correct result even if 289 * size == 0, do not touch bm0[] if size == 0 because this might otherwise 290 * cause an access of memory just past the end of the bm0[] array. 291 */ 292 if (size > 0) 293 { 294 bm0[uword_msb(a)] 295 &= ~((((UWord)1 << size) - 1) << uword_lsb(a)); 296 } 297 } 298 299 /** Test whether the bit corresponding to address a is set in bitmap bm0. */ 300 static __inline__ UWord bm0_is_set(const UWord* bm0, const UWord a) 301 { 302 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 303 tl_assert(address_msb(make_address(0, a)) == 0); 304 #endif 305 return (bm0[uword_msb(a)] & ((UWord)1 << uword_lsb(a))); 306 } 307 308 /** 309 * Return true if a bit corresponding to any of the addresses in range 310 * [ a << ADDR_IGNORED_BITS .. (a + size) << ADDR_IGNORED_BITS [ 311 * is set in bm0. 312 */ 313 static __inline__ UWord bm0_is_any_set(const UWord* bm0, 314 const Addr a, const SizeT size) 315 { 316 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 317 tl_assert(size > 0); 318 tl_assert(address_msb(make_address(0, a)) == 0); 319 tl_assert(address_msb(make_address(0, a + size - 1)) == 0); 320 tl_assert(uword_msb(a) == uword_msb(a + size - 1)); 321 #endif 322 return (bm0[uword_msb(a)] & ((((UWord)1 << size) - 1) << uword_lsb(a))); 323 } 324 325 326 327 /*********************************************************************/ 328 /* Functions for manipulating a struct bitmap. */ 329 /*********************************************************************/ 330 331 332 /* Second level bitmap. */ 333 struct bitmap2 334 { 335 Addr addr; ///< address_msb(...) 336 Bool recalc; 337 struct bitmap1 bm1; 338 }; 339 340 341 static void bm2_clear(struct bitmap2* const bm2); 342 static __inline__ 343 struct bitmap2* bm2_insert(struct bitmap* const bm, const UWord a1); 344 345 346 347 /** 348 * Rotate elements cache[0..n-1] such that the element at position n-1 is 349 * moved to position 0. This allows to speed up future cache lookups. 350 */ 351 static __inline__ 352 void bm_cache_rotate(struct bm_cache_elem cache[], const int n) 353 { 354 #if 0 355 struct bm_cache_elem t; 356 357 tl_assert(2 <= n && n <= 8); 358 359 t = cache[0]; 360 if (n > 1) 361 cache[0] = cache[1]; 362 if (n > 2) 363 cache[1] = cache[2]; 364 if (n > 3) 365 cache[2] = cache[3]; 366 if (n > 4) 367 cache[3] = cache[4]; 368 if (n > 5) 369 cache[4] = cache[5]; 370 if (n > 6) 371 cache[5] = cache[6]; 372 if (n > 7) 373 cache[6] = cache[7]; 374 cache[n - 1] = t; 375 #endif 376 } 377 378 static __inline__ 379 Bool bm_cache_lookup(struct bitmap* const bm, const UWord a1, 380 struct bitmap2** bm2) 381 { 382 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 383 tl_assert(bm); 384 tl_assert(bm2); 385 #endif 386 387 #if DRD_BITMAP_N_CACHE_ELEM > 8 388 #error Please update the code below. 389 #endif 390 #if DRD_BITMAP_N_CACHE_ELEM >= 1 391 if (a1 == bm->cache[0].a1) 392 { 393 *bm2 = bm->cache[0].bm2; 394 return True; 395 } 396 #endif 397 #if DRD_BITMAP_N_CACHE_ELEM >= 2 398 if (a1 == bm->cache[1].a1) 399 { 400 *bm2 = bm->cache[1].bm2; 401 return True; 402 } 403 #endif 404 #if DRD_BITMAP_N_CACHE_ELEM >= 3 405 if (a1 == bm->cache[2].a1) 406 { 407 *bm2 = bm->cache[2].bm2; 408 bm_cache_rotate(bm->cache, 3); 409 return True; 410 } 411 #endif 412 #if DRD_BITMAP_N_CACHE_ELEM >= 4 413 if (a1 == bm->cache[3].a1) 414 { 415 *bm2 = bm->cache[3].bm2; 416 bm_cache_rotate(bm->cache, 4); 417 return True; 418 } 419 #endif 420 #if DRD_BITMAP_N_CACHE_ELEM >= 5 421 if (a1 == bm->cache[4].a1) 422 { 423 *bm2 = bm->cache[4].bm2; 424 bm_cache_rotate(bm->cache, 5); 425 return True; 426 } 427 #endif 428 #if DRD_BITMAP_N_CACHE_ELEM >= 6 429 if (a1 == bm->cache[5].a1) 430 { 431 *bm2 = bm->cache[5].bm2; 432 bm_cache_rotate(bm->cache, 6); 433 return True; 434 } 435 #endif 436 #if DRD_BITMAP_N_CACHE_ELEM >= 7 437 if (a1 == bm->cache[6].a1) 438 { 439 *bm2 = bm->cache[6].bm2; 440 bm_cache_rotate(bm->cache, 7); 441 return True; 442 } 443 #endif 444 #if DRD_BITMAP_N_CACHE_ELEM >= 8 445 if (a1 == bm->cache[7].a1) 446 { 447 *bm2 = bm->cache[7].bm2; 448 bm_cache_rotate(bm->cache, 8); 449 return True; 450 } 451 #endif 452 *bm2 = 0; 453 return False; 454 } 455 456 static __inline__ 457 void bm_update_cache(struct bitmap* const bm, 458 const UWord a1, 459 struct bitmap2* const bm2) 460 { 461 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 462 tl_assert(bm); 463 #endif 464 465 #if DRD_BITMAP_N_CACHE_ELEM > 8 466 #error Please update the code below. 467 #endif 468 #if DRD_BITMAP_N_CACHE_ELEM >= 8 469 bm->cache[7] = bm->cache[6]; 470 #endif 471 #if DRD_BITMAP_N_CACHE_ELEM >= 7 472 bm->cache[6] = bm->cache[5]; 473 #endif 474 #if DRD_BITMAP_N_CACHE_ELEM >= 6 475 bm->cache[5] = bm->cache[4]; 476 #endif 477 #if DRD_BITMAP_N_CACHE_ELEM >= 5 478 bm->cache[4] = bm->cache[3]; 479 #endif 480 #if DRD_BITMAP_N_CACHE_ELEM >= 4 481 bm->cache[3] = bm->cache[2]; 482 #endif 483 #if DRD_BITMAP_N_CACHE_ELEM >= 3 484 bm->cache[2] = bm->cache[1]; 485 #endif 486 #if DRD_BITMAP_N_CACHE_ELEM >= 2 487 bm->cache[1] = bm->cache[0]; 488 #endif 489 bm->cache[0].a1 = a1; 490 bm->cache[0].bm2 = bm2; 491 } 492 493 /** 494 * Look up the address a1 in bitmap bm and return a pointer to a potentially 495 * shared second level bitmap. The bitmap where the returned pointer points 496 * at may not be modified by the caller. 497 * 498 * @param a1 client address shifted right by ADDR_LSB_BITS. 499 * @param bm bitmap pointer. 500 */ 501 static __inline__ 502 const struct bitmap2* bm2_lookup(struct bitmap* const bm, const UWord a1) 503 { 504 struct bitmap2* bm2; 505 506 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 507 tl_assert(bm); 508 #endif 509 510 if (! bm_cache_lookup(bm, a1, &bm2)) 511 { 512 bm2 = VG_(OSetGen_Lookup)(bm->oset, &a1); 513 bm_update_cache(bm, a1, bm2); 514 } 515 return bm2; 516 } 517 518 /** 519 * Look up the address a1 in bitmap bm and return a pointer to a second 520 * level bitmap that is not shared and hence may be modified. 521 * 522 * @param a1 client address shifted right by ADDR_LSB_BITS. 523 * @param bm bitmap pointer. 524 */ 525 static __inline__ 526 struct bitmap2* 527 bm2_lookup_exclusive(struct bitmap* const bm, const UWord a1) 528 { 529 struct bitmap2* bm2; 530 531 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 532 tl_assert(bm); 533 #endif 534 535 if (! bm_cache_lookup(bm, a1, &bm2)) 536 { 537 bm2 = VG_(OSetGen_Lookup)(bm->oset, &a1); 538 } 539 540 return bm2; 541 } 542 543 /** Clear the content of the second-level bitmap. */ 544 static __inline__ 545 void bm2_clear(struct bitmap2* const bm2) 546 { 547 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 548 tl_assert(bm2); 549 #endif 550 VG_(memset)(&bm2->bm1, 0, sizeof(bm2->bm1)); 551 } 552 553 /** 554 * Insert an uninitialized second level bitmap for the address a1. 555 * 556 * @param bm bitmap pointer. 557 * @param a1 client address shifted right by ADDR_LSB_BITS. 558 * 559 * @note bitmap2::recalc isn't initialized here on purpose. 560 */ 561 static __inline__ 562 struct bitmap2* bm2_insert(struct bitmap* const bm, const UWord a1) 563 { 564 struct bitmap2* bm2; 565 566 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 567 tl_assert(bm); 568 #endif 569 570 s_bitmap2_creation_count++; 571 572 bm2 = VG_(OSetGen_AllocNode)(bm->oset, sizeof(*bm2)); 573 bm2->addr = a1; 574 VG_(OSetGen_Insert)(bm->oset, bm2); 575 576 bm_update_cache(bm, a1, bm2); 577 578 return bm2; 579 } 580 581 static __inline__ 582 struct bitmap2* bm2_insert_copy(struct bitmap* const bm, 583 struct bitmap2* const bm2) 584 { 585 struct bitmap2* bm2_copy; 586 587 bm2_copy = bm2_insert(bm, bm2->addr); 588 VG_(memcpy)(&bm2_copy->bm1, &bm2->bm1, sizeof(bm2->bm1)); 589 return bm2_copy; 590 } 591 592 /** 593 * Look up the address a1 in bitmap bm, and insert it if not found. 594 * The returned second level bitmap may not be modified. 595 * 596 * @param bm bitmap pointer. 597 * @param a1 client address shifted right by ADDR_LSB_BITS. 598 */ 599 static __inline__ 600 struct bitmap2* bm2_lookup_or_insert(struct bitmap* const bm, const UWord a1) 601 { 602 struct bitmap2* bm2; 603 604 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 605 tl_assert(bm); 606 #endif 607 608 if (bm_cache_lookup(bm, a1, &bm2)) 609 { 610 if (bm2 == 0) 611 { 612 bm2 = bm2_insert(bm, a1); 613 bm2_clear(bm2); 614 } 615 } 616 else 617 { 618 bm2 = VG_(OSetGen_Lookup)(bm->oset, &a1); 619 if (! bm2) 620 { 621 bm2 = bm2_insert(bm, a1); 622 bm2_clear(bm2); 623 } 624 bm_update_cache(bm, a1, bm2); 625 } 626 return bm2; 627 } 628 629 /** 630 * Look up the address a1 in bitmap bm, and insert it if not found. 631 * The returned second level bitmap may be modified. 632 * 633 * @param a1 client address shifted right by ADDR_LSB_BITS. 634 * @param bm bitmap pointer. 635 */ 636 static __inline__ 637 struct bitmap2* bm2_lookup_or_insert_exclusive(struct bitmap* const bm, 638 const UWord a1) 639 { 640 return bm2_lookup_or_insert(bm, a1); 641 } 642 643 static __inline__ 644 void bm2_remove(struct bitmap* const bm, const UWord a1) 645 { 646 struct bitmap2* bm2; 647 648 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 649 tl_assert(bm); 650 #endif 651 652 bm2 = VG_(OSetGen_Remove)(bm->oset, &a1); 653 VG_(OSetGen_FreeNode)(bm->oset, bm2); 654 655 bm_update_cache(bm, a1, NULL); 656 } 657 658 static __inline__ 659 void bm_access_aligned_load(struct bitmap* const bm, 660 const Addr a1, const SizeT size) 661 { 662 struct bitmap2* bm2; 663 664 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 665 tl_assert(bm); 666 #endif 667 668 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(a1)); 669 bm0_set_range(bm2->bm1.bm0_r, 670 (a1 >> ADDR_IGNORED_BITS) & ADDR_LSB_MASK, 671 SCALED_SIZE(size)); 672 } 673 674 static __inline__ 675 void bm_access_aligned_store(struct bitmap* const bm, 676 const Addr a1, const SizeT size) 677 { 678 struct bitmap2* bm2; 679 680 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 681 tl_assert(bm); 682 #endif 683 684 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(a1)); 685 bm0_set_range(bm2->bm1.bm0_w, 686 (a1 >> ADDR_IGNORED_BITS) & ADDR_LSB_MASK, 687 SCALED_SIZE(size)); 688 } 689 690 static __inline__ 691 Bool bm_aligned_load_has_conflict_with(struct bitmap* const bm, 692 const Addr a, const SizeT size) 693 { 694 const struct bitmap2* bm2; 695 696 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 697 tl_assert(bm); 698 #endif 699 700 bm2 = bm2_lookup(bm, address_msb(a)); 701 return (bm2 702 && bm0_is_any_set(bm2->bm1.bm0_w, 703 address_lsb(a), 704 SCALED_SIZE(size))); 705 } 706 707 static __inline__ 708 Bool bm_aligned_store_has_conflict_with(struct bitmap* const bm, 709 const Addr a, const SizeT size) 710 { 711 const struct bitmap2* bm2; 712 713 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 714 tl_assert(bm); 715 #endif 716 717 bm2 = bm2_lookup(bm, address_msb(a)); 718 if (bm2) 719 { 720 if (bm0_is_any_set(bm2->bm1.bm0_r, address_lsb(a), SCALED_SIZE(size)) 721 | bm0_is_any_set(bm2->bm1.bm0_w, address_lsb(a), SCALED_SIZE(size))) 722 { 723 return True; 724 } 725 } 726 return False; 727 } 728 729 #endif /* __DRD_BITMAP_H */ 730