1 /* Copyright (c) 2008-2010, Google Inc. 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Neither the name of Google Inc. nor the names of its 11 * contributors may be used to endorse or promote products derived from 12 * this software without specific prior written permission. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 // This file is part of ThreadSanitizer, a dynamic data race detector. 28 // Author: Konstantin Serebryany. 29 // Author: Timur Iskhodzhanov. 30 #ifndef TS_SIMPLE_CACHE_ 31 #define TS_SIMPLE_CACHE_ 32 33 #include "ts_util.h" 34 35 // Few simple 'cache' classes. 36 // -------- PtrToBoolCache ------ {{{1 37 // Maps a pointer to a boolean. 38 template <int kSize> 39 class PtrToBoolCache { 40 public: 41 PtrToBoolCache() { 42 Flush(); 43 } 44 void Flush() { 45 memset(this, 0, sizeof(*this)); 46 } 47 void Insert(uintptr_t ptr, bool val) { 48 size_t idx = ptr % kSize; 49 arr_[idx] = ptr; 50 if (val) { 51 bits_[idx / 32] |= 1U << (idx % 32); 52 } else { 53 bits_[idx / 32] &= ~(1U << (idx % 32)); 54 } 55 } 56 bool Lookup(uintptr_t ptr, bool *val) { 57 size_t idx = ptr % kSize; 58 if (arr_[idx] == ptr) { 59 *val = (bits_[idx / 32] >> (idx % 32)) & 1; 60 return true; 61 } 62 return false; 63 } 64 private: 65 uintptr_t arr_[kSize]; 66 uint32_t bits_[(kSize + 31) / 32]; 67 }; 68 69 // -------- IntPairToBoolCache ------ {{{1 70 // Maps two integers to a boolean. 71 // The second integer should be less than 1^31. 72 template <int32_t kSize> 73 class IntPairToBoolCache { 74 public: 75 IntPairToBoolCache() { 76 Flush(); 77 } 78 void Flush() { 79 memset(arr_, 0, sizeof(arr_)); 80 } 81 void Insert(uint32_t a, uint32_t b, bool val) { 82 DCHECK((int32_t)b >= 0); 83 uint32_t i = idx(a, b); 84 if (val) { 85 b |= 1U << 31; 86 } 87 arr_[i * 2 + 0] = a; 88 arr_[i * 2 + 1] = b; 89 } 90 bool Lookup(uint32_t a, uint32_t b, bool *val) { 91 DCHECK((int32_t)b >= 0); 92 uint32_t i = idx(a, b); 93 if (arr_[i * 2] != a) return false; 94 uint32_t maybe_b = arr_[i * 2 + 1]; 95 if (b == (maybe_b & (~(1U << 31)))) { 96 *val = (maybe_b & (1U << 31)) != 0; 97 return true; 98 } 99 return false; 100 } 101 private: 102 uint32_t idx(uint32_t a, uint32_t b) { 103 return (a ^ ((b >> 16) | (b << 16))) % kSize; 104 } 105 uint32_t arr_[kSize * 2]; 106 }; 107 108 // end. {{{1 109 #endif // TS_SIMPLE_CACHE_ 110 // vim:shiftwidth=2:softtabstop=2:expandtab:tw=80 111