10
10
11
11
// *****************************************************************
12
12
// Enable/disable debug instrumentation and statistics printing here
13
- constexpr inline auto debug_instrumentation = false ;
13
+ constexpr inline auto debug_instrumentation = true ;
14
+
15
+ // Try with/without m_o_relaxed
16
+ #define M_O_RELAXED , std::memory_order_relaxed
17
+ #define M_O_RELAXED_NOCOMMA std::memory_order_relaxed
18
+ // #define M_O_RELAXED
19
+ // #define M_O_RELAXED_NOCOMMA
14
20
// *****************************************************************
15
21
16
22
#include < algorithm>
@@ -125,7 +131,7 @@ class extrinsic_storage {
125
131
auto find_or_insert (void * pobj) noexcept -> Value* {
126
132
if constexpr (debug_instrumentation) {
127
133
// m_o_relaxed is enough, inc order doesn't matter for totals
128
- instrument_access_count.fetch_add (1 , std::memory_order_relaxed );
134
+ instrument_access_count.fetch_add (1 M_O_RELAXED );
129
135
}
130
136
return lookup (pobj, lookup_mode::find_or_insert);
131
137
}
@@ -136,7 +142,7 @@ class extrinsic_storage {
136
142
auto find (void * pobj) noexcept -> Value* {
137
143
if constexpr (debug_instrumentation) {
138
144
// m_o_relaxed is enough, inc order doesn't matter for totals
139
- instrument_access_count.fetch_add (1 , std::memory_order_relaxed );
145
+ instrument_access_count.fetch_add (1 M_O_RELAXED );
140
146
}
141
147
return lookup (pobj, lookup_mode::find);
142
148
}
@@ -147,7 +153,7 @@ class extrinsic_storage {
147
153
auto erase (void * pobj) noexcept -> void {
148
154
if constexpr (debug_instrumentation) {
149
155
// m_o_relaxed is enough, inc order doesn't matter for totals
150
- instrument_erase_count.fetch_add (1 , std::memory_order_relaxed );
156
+ instrument_erase_count.fetch_add (1 M_O_RELAXED );
151
157
}
152
158
lookup (pobj, lookup_mode::erase);
153
159
}
@@ -202,7 +208,7 @@ class extrinsic_storage {
202
208
assert ( 0 <= hash && hash < Buckets );
203
209
if constexpr (debug_instrumentation) {
204
210
// m_o_relaxed is enough, inc order doesn't matter for totals
205
- instrument_bucket_access[hash].fetch_add (1 , std::memory_order_relaxed );
211
+ instrument_bucket_access[hash].fetch_add (1 M_O_RELAXED );
206
212
}
207
213
208
214
// 1. If we find key==pobj, we're done
@@ -212,9 +218,9 @@ class extrinsic_storage {
212
218
// (*) m_o_relaxed is enough, equality means we own the slot
213
219
// and so this thread already has exclusive access to *pobj
214
220
// and its .values data
215
- if (pchunk->keys [i].load (std::memory_order_relaxed ) == pobj) {
221
+ if (pchunk->keys [i].load (M_O_RELAXED_NOCOMMA ) == pobj) {
216
222
if (mode == lookup_mode::erase) {
217
- pchunk->keys [i].store (nullptr , std::memory_order_relaxed );
223
+ pchunk->keys [i].store (nullptr M_O_RELAXED );
218
224
return nullptr ;
219
225
}
220
226
// Else
@@ -225,7 +231,7 @@ class extrinsic_storage {
225
231
// it is first set to non-null, and if a new chunk(s) was just
226
232
// concurrently added by a different thread then that new
227
233
// chunk(s) cannot contain an entry for pobj
228
- pchunk = pchunk->next .load (std::memory_order_relaxed );
234
+ pchunk = pchunk->next .load (M_O_RELAXED_NOCOMMA );
229
235
}
230
236
231
237
// 2. Otherwise, if we're not allowed to insert we're done
@@ -234,7 +240,7 @@ class extrinsic_storage {
234
240
if constexpr (debug_instrumentation) {
235
241
if (mode == lookup_mode::erase) {
236
242
// m_o_relaxed is enough, inc order doesn't matter for totals
237
- instrument_erase_fail_count.fetch_add (1 , std::memory_order_relaxed );
243
+ instrument_erase_fail_count.fetch_add (1 M_O_RELAXED );
238
244
}
239
245
}
240
246
return nullptr ;
@@ -249,22 +255,22 @@ class extrinsic_storage {
249
255
void * null = nullptr ;
250
256
if (
251
257
// m_o_relaxed is enough for this first load...
252
- pchunk->keys [i].load (std::memory_order_relaxed ) == nullptr
258
+ pchunk->keys [i].load (M_O_RELAXED_NOCOMMA ) == nullptr
253
259
// ... because it's just a best-effort optimization to
254
260
// avoid this maybe-unneeded c_e_weak (which is safely SC)
255
261
&& pchunk->keys [i].compare_exchange_weak ( null, pobj )
256
262
) {
257
263
if constexpr (debug_instrumentation) {
258
264
// m_o_relaxed is enough, inc order doesn't matter for totals
259
- instrument_insert_count.fetch_add (1 , std::memory_order_relaxed );
265
+ instrument_insert_count.fetch_add (1 M_O_RELAXED );
260
266
}
261
267
return &pchunk->values [i];
262
268
}
263
269
}
264
270
// (*) m_o_relaxed is enough here, because if a new chunk(s)
265
271
// was just concurrently added by a different thread then we'll
266
272
// just add an extra chunk which is fine
267
- if ( pchunk->next .load (std::memory_order_relaxed ) == nullptr ) {
273
+ if ( pchunk->next .load (M_O_RELAXED_NOCOMMA ) == nullptr ) {
268
274
break ;
269
275
}
270
276
pchunk = pchunk->next .load ();
@@ -290,7 +296,7 @@ class extrinsic_storage {
290
296
291
297
if constexpr (debug_instrumentation) {
292
298
// m_o_relaxed is enough, inc order doesn't matter for totals
293
- instrument_alloc_count.fetch_add (1 , std::memory_order_relaxed );
299
+ instrument_alloc_count.fetch_add (1 M_O_RELAXED );
294
300
}
295
301
return ret;
296
302
}
0 commit comments