1 /* 2 This file is part of drd, a thread error detector. 3 4 Copyright (C) 2006-2015 Bart Van Assche <bvanassche (at) 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 || defined(VGA_tilegx) 145 #define BITS_PER_BITS_PER_UWORD 6 146 #else 147 #error Unknown platform. 148 #endif 149 150 /** Number of UWord's needed to store one bit per address LSB. */ 151 #define BITMAP1_UWORD_COUNT (1U << (ADDR_LSB_BITS - BITS_PER_BITS_PER_UWORD)) 152 153 /** 154 * Mask that has to be applied to an (Addr >> ADDR_IGNORED_BITS) expression 155 * in order to compute the least significant part of an UWord. 156 */ 157 #define UWORD_LSB_MASK (((UWord)1 << BITS_PER_BITS_PER_UWORD) - 1) 158 159 /** 160 * Compute index into bm0[] array. 161 * 162 * @param a Address shifted right ADDR_IGNORED_BITS bits. 163 */ 164 static __inline__ 165 UWord uword_msb(const UWord a) 166 { 167 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 168 tl_assert(a < (1U << ADDR_LSB_BITS)); 169 #endif 170 return a >> BITS_PER_BITS_PER_UWORD; 171 } 172 173 /** 174 * Return the least significant bits. 175 * 176 * @param a Address shifted right ADDR_IGNORED_BITS bits. 177 */ 178 static __inline__ 179 UWord uword_lsb(const UWord a) 180 { 181 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 182 tl_assert(a < (1U << ADDR_LSB_BITS)); 183 #endif 184 return a & UWORD_LSB_MASK; 185 } 186 187 /** 188 * Compute the highest address lower than a for which 189 * uword_lsb(address_lsb(a)) == 0. 190 * 191 * @param a Address. 192 */ 193 static __inline__ 194 Addr first_address_with_same_uword_lsb(const Addr a) 195 { 196 return (a & (~UWORD_LSB_MASK << ADDR_IGNORED_BITS)); 197 } 198 199 /** 200 * First address that will go in the UWord past the one 'a' goes in. 201 * 202 * @param a Address. 203 */ 204 static __inline__ 205 Addr first_address_with_higher_uword_msb(const Addr a) 206 { 207 return ((a | ((UWORD_LSB_MASK << ADDR_IGNORED_BITS) | ADDR_IGNORED_MASK)) 208 + 1); 209 } 210 211 212 213 /* Local variables. */ 214 215 static ULong s_bitmap2_creation_count; 216 217 218 219 /*********************************************************************/ 220 /* Functions for manipulating a struct bitmap1. */ 221 /*********************************************************************/ 222 223 224 /* Lowest level, corresponding to the lowest ADDR_LSB_BITS of an address. */ 225 struct bitmap1 226 { 227 UWord bm0_r[BITMAP1_UWORD_COUNT]; 228 UWord bm0_w[BITMAP1_UWORD_COUNT]; 229 }; 230 231 static __inline__ UWord bm0_mask(const UWord a) 232 { 233 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 234 tl_assert(address_msb(make_address(0, a)) == 0); 235 #endif 236 return ((UWord)1 << uword_lsb(a)); 237 } 238 239 /** Set the bit corresponding to address a in bitmap bm0. */ 240 static __inline__ void bm0_set(UWord* bm0, const UWord a) 241 { 242 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 243 tl_assert(address_msb(make_address(0, a)) == 0); 244 #endif 245 bm0[uword_msb(a)] |= (UWord)1 << uword_lsb(a); 246 } 247 248 /** 249 * Set the bits corresponding to all of the addresses in range 250 * [ a << ADDR_IGNORED_BITS .. (a + size) << ADDR_IGNORED_BITS [ 251 * in bitmap bm0. 252 */ 253 static __inline__ void bm0_set_range(UWord* bm0, 254 const UWord a, const SizeT size) 255 { 256 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 257 tl_assert(size > 0); 258 tl_assert(address_msb(make_address(0, a)) == 0); 259 tl_assert(address_msb(make_address(0, a + size - 1)) == 0); 260 tl_assert(uword_msb(a) == uword_msb(a + size - 1)); 261 #endif 262 bm0[uword_msb(a)] 263 |= (((UWord)1 << size) - 1) << uword_lsb(a); 264 } 265 266 /** Clear the bit corresponding to address a in bitmap bm0. */ 267 static __inline__ void bm0_clear(UWord* bm0, const UWord a) 268 { 269 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 270 tl_assert(address_msb(make_address(0, a)) == 0); 271 #endif 272 bm0[uword_msb(a)] &= ~((UWord)1 << uword_lsb(a)); 273 } 274 275 /** 276 * Clear all of the addresses in range 277 * [ a << ADDR_IGNORED_BITS .. (a + size) << ADDR_IGNORED_BITS [ 278 * in bitmap bm0. 279 */ 280 static __inline__ void bm0_clear_range(UWord* bm0, 281 const UWord a, const SizeT size) 282 { 283 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 284 tl_assert(address_msb(make_address(0, a)) == 0); 285 tl_assert(size == 0 || address_msb(make_address(0, a + size - 1)) == 0); 286 tl_assert(size == 0 || uword_msb(a) == uword_msb(a + size - 1)); 287 #endif 288 /* 289 * Note: although the expression below yields a correct result even if 290 * size == 0, do not touch bm0[] if size == 0 because this might otherwise 291 * cause an access of memory just past the end of the bm0[] array. 292 */ 293 if (size > 0) 294 { 295 bm0[uword_msb(a)] 296 &= ~((((UWord)1 << size) - 1) << uword_lsb(a)); 297 } 298 } 299 300 /** Test whether the bit corresponding to address a is set in bitmap bm0. */ 301 static __inline__ UWord bm0_is_set(const UWord* bm0, const UWord a) 302 { 303 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 304 tl_assert(address_msb(make_address(0, a)) == 0); 305 #endif 306 return (bm0[uword_msb(a)] & ((UWord)1 << uword_lsb(a))); 307 } 308 309 /** 310 * Return true if a bit corresponding to any of the addresses in range 311 * [ a << ADDR_IGNORED_BITS .. (a + size) << ADDR_IGNORED_BITS [ 312 * is set in bm0. 313 */ 314 static __inline__ UWord bm0_is_any_set(const UWord* bm0, 315 const Addr a, const SizeT size) 316 { 317 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 318 tl_assert(size > 0); 319 tl_assert(address_msb(make_address(0, a)) == 0); 320 tl_assert(address_msb(make_address(0, a + size - 1)) == 0); 321 tl_assert(uword_msb(a) == uword_msb(a + size - 1)); 322 #endif 323 return (bm0[uword_msb(a)] & ((((UWord)1 << size) - 1) << uword_lsb(a))); 324 } 325 326 327 328 /*********************************************************************/ 329 /* Functions for manipulating a struct bitmap. */ 330 /*********************************************************************/ 331 332 333 /* Second level bitmap. */ 334 struct bitmap2 335 { 336 Addr addr; ///< address_msb(...) 337 Bool recalc; 338 struct bitmap1 bm1; 339 }; 340 341 342 static void bm2_clear(struct bitmap2* const bm2); 343 static __inline__ 344 struct bitmap2* bm2_insert(struct bitmap* const bm, const UWord a1); 345 346 347 348 /** 349 * Rotate elements cache[0..n-1] such that the element at position n-1 is 350 * moved to position 0. This allows to speed up future cache lookups. 351 */ 352 static __inline__ 353 void bm_cache_rotate(struct bm_cache_elem cache[], const int n) 354 { 355 #if 0 356 struct bm_cache_elem t; 357 358 tl_assert(2 <= n && n <= 8); 359 360 t = cache[0]; 361 if (n > 1) 362 cache[0] = cache[1]; 363 if (n > 2) 364 cache[1] = cache[2]; 365 if (n > 3) 366 cache[2] = cache[3]; 367 if (n > 4) 368 cache[3] = cache[4]; 369 if (n > 5) 370 cache[4] = cache[5]; 371 if (n > 6) 372 cache[5] = cache[6]; 373 if (n > 7) 374 cache[6] = cache[7]; 375 cache[n - 1] = t; 376 #endif 377 } 378 379 static __inline__ 380 Bool bm_cache_lookup(struct bitmap* const bm, const UWord a1, 381 struct bitmap2** bm2) 382 { 383 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 384 tl_assert(bm); 385 tl_assert(bm2); 386 #endif 387 388 #if DRD_BITMAP_N_CACHE_ELEM > 8 389 #error Please update the code below. 390 #endif 391 #if DRD_BITMAP_N_CACHE_ELEM >= 1 392 if (a1 == bm->cache[0].a1) 393 { 394 *bm2 = bm->cache[0].bm2; 395 return True; 396 } 397 #endif 398 #if DRD_BITMAP_N_CACHE_ELEM >= 2 399 if (a1 == bm->cache[1].a1) 400 { 401 *bm2 = bm->cache[1].bm2; 402 return True; 403 } 404 #endif 405 #if DRD_BITMAP_N_CACHE_ELEM >= 3 406 if (a1 == bm->cache[2].a1) 407 { 408 *bm2 = bm->cache[2].bm2; 409 bm_cache_rotate(bm->cache, 3); 410 return True; 411 } 412 #endif 413 #if DRD_BITMAP_N_CACHE_ELEM >= 4 414 if (a1 == bm->cache[3].a1) 415 { 416 *bm2 = bm->cache[3].bm2; 417 bm_cache_rotate(bm->cache, 4); 418 return True; 419 } 420 #endif 421 #if DRD_BITMAP_N_CACHE_ELEM >= 5 422 if (a1 == bm->cache[4].a1) 423 { 424 *bm2 = bm->cache[4].bm2; 425 bm_cache_rotate(bm->cache, 5); 426 return True; 427 } 428 #endif 429 #if DRD_BITMAP_N_CACHE_ELEM >= 6 430 if (a1 == bm->cache[5].a1) 431 { 432 *bm2 = bm->cache[5].bm2; 433 bm_cache_rotate(bm->cache, 6); 434 return True; 435 } 436 #endif 437 #if DRD_BITMAP_N_CACHE_ELEM >= 7 438 if (a1 == bm->cache[6].a1) 439 { 440 *bm2 = bm->cache[6].bm2; 441 bm_cache_rotate(bm->cache, 7); 442 return True; 443 } 444 #endif 445 #if DRD_BITMAP_N_CACHE_ELEM >= 8 446 if (a1 == bm->cache[7].a1) 447 { 448 *bm2 = bm->cache[7].bm2; 449 bm_cache_rotate(bm->cache, 8); 450 return True; 451 } 452 #endif 453 *bm2 = 0; 454 return False; 455 } 456 457 static __inline__ 458 void bm_update_cache(struct bitmap* const bm, 459 const UWord a1, 460 struct bitmap2* const bm2) 461 { 462 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 463 tl_assert(bm); 464 #endif 465 466 #if DRD_BITMAP_N_CACHE_ELEM > 8 467 #error Please update the code below. 468 #endif 469 #if DRD_BITMAP_N_CACHE_ELEM >= 8 470 bm->cache[7] = bm->cache[6]; 471 #endif 472 #if DRD_BITMAP_N_CACHE_ELEM >= 7 473 bm->cache[6] = bm->cache[5]; 474 #endif 475 #if DRD_BITMAP_N_CACHE_ELEM >= 6 476 bm->cache[5] = bm->cache[4]; 477 #endif 478 #if DRD_BITMAP_N_CACHE_ELEM >= 5 479 bm->cache[4] = bm->cache[3]; 480 #endif 481 #if DRD_BITMAP_N_CACHE_ELEM >= 4 482 bm->cache[3] = bm->cache[2]; 483 #endif 484 #if DRD_BITMAP_N_CACHE_ELEM >= 3 485 bm->cache[2] = bm->cache[1]; 486 #endif 487 #if DRD_BITMAP_N_CACHE_ELEM >= 2 488 bm->cache[1] = bm->cache[0]; 489 #endif 490 bm->cache[0].a1 = a1; 491 bm->cache[0].bm2 = bm2; 492 } 493 494 /** 495 * Look up the address a1 in bitmap bm and return a pointer to a potentially 496 * shared second level bitmap. The bitmap where the returned pointer points 497 * at may not be modified by the caller. 498 * 499 * @param a1 client address shifted right by ADDR_LSB_BITS. 500 * @param bm bitmap pointer. 501 */ 502 static __inline__ 503 const struct bitmap2* bm2_lookup(struct bitmap* const bm, const UWord a1) 504 { 505 struct bitmap2* bm2; 506 507 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 508 tl_assert(bm); 509 #endif 510 511 if (! bm_cache_lookup(bm, a1, &bm2)) 512 { 513 bm2 = VG_(OSetGen_Lookup)(bm->oset, &a1); 514 bm_update_cache(bm, a1, bm2); 515 } 516 return bm2; 517 } 518 519 /** 520 * Look up the address a1 in bitmap bm and return a pointer to a second 521 * level bitmap that is not shared and hence may be modified. 522 * 523 * @param a1 client address shifted right by ADDR_LSB_BITS. 524 * @param bm bitmap pointer. 525 */ 526 static __inline__ 527 struct bitmap2* 528 bm2_lookup_exclusive(struct bitmap* const bm, const UWord a1) 529 { 530 struct bitmap2* bm2; 531 532 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 533 tl_assert(bm); 534 #endif 535 536 if (! bm_cache_lookup(bm, a1, &bm2)) 537 { 538 bm2 = VG_(OSetGen_Lookup)(bm->oset, &a1); 539 } 540 541 return bm2; 542 } 543 544 /** Clear the content of the second-level bitmap. */ 545 static __inline__ 546 void bm2_clear(struct bitmap2* const bm2) 547 { 548 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 549 tl_assert(bm2); 550 #endif 551 VG_(memset)(&bm2->bm1, 0, sizeof(bm2->bm1)); 552 } 553 554 /** 555 * Insert an uninitialized second level bitmap for the address a1. 556 * 557 * @param bm bitmap pointer. 558 * @param a1 client address shifted right by ADDR_LSB_BITS. 559 * 560 * @note bitmap2::recalc isn't initialized here on purpose. 561 */ 562 static __inline__ 563 struct bitmap2* bm2_insert(struct bitmap* const bm, const UWord a1) 564 { 565 struct bitmap2* bm2; 566 567 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 568 tl_assert(bm); 569 #endif 570 571 s_bitmap2_creation_count++; 572 573 bm2 = VG_(OSetGen_AllocNode)(bm->oset, sizeof(*bm2)); 574 bm2->addr = a1; 575 VG_(OSetGen_Insert)(bm->oset, bm2); 576 577 bm_update_cache(bm, a1, bm2); 578 579 return bm2; 580 } 581 582 static __inline__ 583 struct bitmap2* bm2_insert_copy(struct bitmap* const bm, 584 struct bitmap2* const bm2) 585 { 586 struct bitmap2* bm2_copy; 587 588 bm2_copy = bm2_insert(bm, bm2->addr); 589 VG_(memcpy)(&bm2_copy->bm1, &bm2->bm1, sizeof(bm2->bm1)); 590 return bm2_copy; 591 } 592 593 /** 594 * Look up the address a1 in bitmap bm, and insert it if not found. 595 * The returned second level bitmap may not be modified. 596 * 597 * @param bm bitmap pointer. 598 * @param a1 client address shifted right by ADDR_LSB_BITS. 599 */ 600 static __inline__ 601 struct bitmap2* bm2_lookup_or_insert(struct bitmap* const bm, const UWord a1) 602 { 603 struct bitmap2* bm2; 604 605 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 606 tl_assert(bm); 607 #endif 608 609 if (bm_cache_lookup(bm, a1, &bm2)) 610 { 611 if (bm2 == 0) 612 { 613 bm2 = bm2_insert(bm, a1); 614 bm2_clear(bm2); 615 } 616 } 617 else 618 { 619 bm2 = VG_(OSetGen_Lookup)(bm->oset, &a1); 620 if (! bm2) 621 { 622 bm2 = bm2_insert(bm, a1); 623 bm2_clear(bm2); 624 } 625 bm_update_cache(bm, a1, bm2); 626 } 627 return bm2; 628 } 629 630 /** 631 * Look up the address a1 in bitmap bm, and insert it if not found. 632 * The returned second level bitmap may be modified. 633 * 634 * @param a1 client address shifted right by ADDR_LSB_BITS. 635 * @param bm bitmap pointer. 636 */ 637 static __inline__ 638 struct bitmap2* bm2_lookup_or_insert_exclusive(struct bitmap* const bm, 639 const UWord a1) 640 { 641 return bm2_lookup_or_insert(bm, a1); 642 } 643 644 static __inline__ 645 void bm2_remove(struct bitmap* const bm, const UWord a1) 646 { 647 struct bitmap2* bm2; 648 649 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 650 tl_assert(bm); 651 #endif 652 653 bm2 = VG_(OSetGen_Remove)(bm->oset, &a1); 654 VG_(OSetGen_FreeNode)(bm->oset, bm2); 655 656 bm_update_cache(bm, a1, NULL); 657 } 658 659 static __inline__ 660 void bm_access_aligned_load(struct bitmap* const bm, 661 const Addr a1, const SizeT size) 662 { 663 struct bitmap2* bm2; 664 665 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 666 tl_assert(bm); 667 #endif 668 669 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(a1)); 670 bm0_set_range(bm2->bm1.bm0_r, 671 (a1 >> ADDR_IGNORED_BITS) & ADDR_LSB_MASK, 672 SCALED_SIZE(size)); 673 } 674 675 static __inline__ 676 void bm_access_aligned_store(struct bitmap* const bm, 677 const Addr a1, const SizeT size) 678 { 679 struct bitmap2* bm2; 680 681 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 682 tl_assert(bm); 683 #endif 684 685 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(a1)); 686 bm0_set_range(bm2->bm1.bm0_w, 687 (a1 >> ADDR_IGNORED_BITS) & ADDR_LSB_MASK, 688 SCALED_SIZE(size)); 689 } 690 691 static __inline__ 692 Bool bm_aligned_load_has_conflict_with(struct bitmap* const bm, 693 const Addr a, const SizeT size) 694 { 695 const struct bitmap2* bm2; 696 697 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 698 tl_assert(bm); 699 #endif 700 701 bm2 = bm2_lookup(bm, address_msb(a)); 702 return (bm2 703 && bm0_is_any_set(bm2->bm1.bm0_w, 704 address_lsb(a), 705 SCALED_SIZE(size))); 706 } 707 708 static __inline__ 709 Bool bm_aligned_store_has_conflict_with(struct bitmap* const bm, 710 const Addr a, const SizeT size) 711 { 712 const struct bitmap2* bm2; 713 714 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 715 tl_assert(bm); 716 #endif 717 718 bm2 = bm2_lookup(bm, address_msb(a)); 719 if (bm2) 720 { 721 if (bm0_is_any_set(bm2->bm1.bm0_r, address_lsb(a), SCALED_SIZE(size)) 722 | bm0_is_any_set(bm2->bm1.bm0_w, address_lsb(a), SCALED_SIZE(size))) 723 { 724 return True; 725 } 726 } 727 return False; 728 } 729 730 #endif /* __DRD_BITMAP_H */ 731