1 /* 2 This file is part of drd, a thread error detector. 3 4 Copyright (C) 2006-2017 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_THREAD_BITMAP_H 26 #define __DRD_THREAD_BITMAP_H 27 28 29 #include "drd_bitmap.h" 30 #include "drd_thread.h" /* running_thread_get_segment() */ 31 #include "pub_drd_bitmap.h" 32 33 34 static __inline__ 35 Bool bm_access_load_1_triggers_conflict(const Addr a1) 36 { 37 DRD_(bm_access_load_1)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1); 38 return DRD_(bm_load_1_has_conflict_with)(DRD_(thread_get_conflict_set)(), 39 a1); 40 } 41 42 static __inline__ 43 Bool bm_access_load_2_triggers_conflict(const Addr a1) 44 { 45 if ((a1 & 1) == 0) 46 { 47 bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 2); 48 return bm_aligned_load_has_conflict_with(DRD_(thread_get_conflict_set)(), 49 a1, 2); 50 } 51 else 52 { 53 DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), 54 a1, a1 + 2, eLoad); 55 return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(), 56 a1, a1 + 2, eLoad); 57 } 58 } 59 60 static __inline__ 61 Bool bm_access_load_4_triggers_conflict(const Addr a1) 62 { 63 if ((a1 & 3) == 0) 64 { 65 bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 4); 66 return bm_aligned_load_has_conflict_with(DRD_(thread_get_conflict_set)(), 67 a1, 4); 68 } 69 else 70 { 71 DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), 72 a1, a1 + 4, eLoad); 73 return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(), 74 a1, a1 + 4, eLoad); 75 } 76 } 77 78 static __inline__ 79 Bool bm_access_load_8_triggers_conflict(const Addr a1) 80 { 81 if ((a1 & 7) == 0) 82 { 83 bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 8); 84 return bm_aligned_load_has_conflict_with(DRD_(thread_get_conflict_set)(), 85 a1, 8); 86 } 87 else if ((a1 & 3) == 0) 88 { 89 bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1 + 0, 4); 90 bm_access_aligned_load(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1 + 4, 4); 91 return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(), 92 a1, a1 + 8, eLoad); 93 } 94 else 95 { 96 DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), 97 a1, a1 + 8, eLoad); 98 return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(), 99 a1, a1 + 8, eLoad); 100 } 101 } 102 103 static __inline__ 104 Bool bm_access_load_triggers_conflict(const Addr a1, const Addr a2) 105 { 106 DRD_(bm_access_range_load)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, a2); 107 return DRD_(bm_load_has_conflict_with)(DRD_(thread_get_conflict_set)(), 108 a1, a2); 109 } 110 111 static __inline__ 112 Bool bm_access_store_1_triggers_conflict(const Addr a1) 113 { 114 DRD_(bm_access_store_1)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1); 115 return DRD_(bm_store_1_has_conflict_with)(DRD_(thread_get_conflict_set)(), 116 a1); 117 } 118 119 static __inline__ 120 Bool bm_access_store_2_triggers_conflict(const Addr a1) 121 { 122 if ((a1 & 1) == 0) 123 { 124 bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 2); 125 return bm_aligned_store_has_conflict_with(DRD_(thread_get_conflict_set)(), 126 a1, 2); 127 } 128 else 129 { 130 DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), 131 a1, a1 + 2, eStore); 132 return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(), 133 a1, a1 + 2, eStore); 134 } 135 } 136 137 static __inline__ 138 Bool bm_access_store_4_triggers_conflict(const Addr a1) 139 { 140 if ((a1 & 3) == 0) 141 { 142 bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 4); 143 return bm_aligned_store_has_conflict_with(DRD_(thread_get_conflict_set)(), 144 a1, 4); 145 } 146 else 147 { 148 DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), 149 a1, a1 + 4, eStore); 150 return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(), 151 a1, a1 + 4, eStore); 152 } 153 } 154 155 static __inline__ 156 Bool bm_access_store_8_triggers_conflict(const Addr a1) 157 { 158 if ((a1 & 7) == 0) 159 { 160 bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, 8); 161 return bm_aligned_store_has_conflict_with(DRD_(thread_get_conflict_set)(), 162 a1, 8); 163 } 164 else if ((a1 & 3) == 0) 165 { 166 bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), 167 a1 + 0, 4); 168 bm_access_aligned_store(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), 169 a1 + 4, 4); 170 return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(), 171 a1, a1 + 8, eStore); 172 } 173 else 174 { 175 DRD_(bm_access_range)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), 176 a1, a1 + 8, eStore); 177 return DRD_(bm_has_conflict_with)(DRD_(thread_get_conflict_set)(), 178 a1, a1 + 8, eStore); 179 } 180 } 181 182 static __inline__ 183 Bool bm_access_store_triggers_conflict(const Addr a1, const Addr a2) 184 { 185 DRD_(bm_access_range_store)(DRD_(sg_bm)(DRD_(running_thread_get_segment)()), a1, a2); 186 return DRD_(bm_store_has_conflict_with)(DRD_(thread_get_conflict_set)(), 187 a1, a2); 188 } 189 190 #endif // __DRD_THREAD_BITMAP_H 191