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_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__
bm_access_load_1_triggers_conflict(const Addr a1)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__
bm_access_load_2_triggers_conflict(const Addr a1)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__
bm_access_load_4_triggers_conflict(const Addr a1)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__
bm_access_load_8_triggers_conflict(const Addr a1)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__
bm_access_load_triggers_conflict(const Addr a1,const Addr a2)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__
bm_access_store_1_triggers_conflict(const Addr a1)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__
bm_access_store_2_triggers_conflict(const Addr a1)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__
bm_access_store_4_triggers_conflict(const Addr a1)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__
bm_access_store_8_triggers_conflict(const Addr a1)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__
bm_access_store_triggers_conflict(const Addr a1,const Addr a2)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