@@ -45,18 +45,22 @@ struct Element : ElementFeatures...
45
45
template <typename Element, std::size_t Count>
46
46
struct RingBufferStateBase
47
47
{
48
- // protected:
48
+ protected:
49
49
using ElementType = typename Element::ElementType;
50
50
51
51
enum : std::size_t
52
52
{
53
- COUNT = Count,
54
53
COUNT_MASK = Count - 1 ,
55
54
};
56
55
57
56
std::array<CacheAlignedAndPaddedObject<Element>, Count> elements{};
58
57
59
58
public:
59
+ enum : std::size_t
60
+ {
61
+ COUNT = Count,
62
+ };
63
+
60
64
static_assert (Count > 0 && !(COUNT_MASK & Count), " Count should be a power of two." );
61
65
};
62
66
@@ -85,6 +89,7 @@ struct MultiProducerTypeTraits
85
89
template <typename BaseType>
86
90
struct Behavior : BaseType
87
91
{
92
+ private:
88
93
CacheAlignedAndPaddedObject<std::atomic_size_t > end{std::size_t (0 )};
89
94
90
95
public:
@@ -126,6 +131,7 @@ struct MultiProducerTypeTraits
126
131
template <typename BaseType, typename = Private::CountInt64CompatibilityCheck<BaseType::COUNT>>
127
132
struct SharedState : BaseType
128
133
{
134
+ protected:
129
135
CacheAlignedAndPaddedObject<std::atomic<std::int64_t >> push_task_count{static_cast <std::int64_t >(BaseType::COUNT)};
130
136
};
131
137
@@ -185,6 +191,7 @@ struct MultiConsumerTypeTraits
185
191
template <typename BaseType, typename = Private::CountInt64CompatibilityCheck<BaseType::COUNT>>
186
192
struct SharedState : BaseType
187
193
{
194
+ protected:
188
195
CacheAlignedAndPaddedObject<std::atomic<std::int64_t >> pop_task_count{std::int64_t {0 }};
189
196
};
190
197
@@ -203,6 +210,7 @@ struct SingleProducerTypeTraits
203
210
struct State
204
211
{
205
212
std::size_t pushed_task_count{0 };
213
+ std::size_t local_push_task_count{BaseType::COUNT};
206
214
std::size_t end{0 };
207
215
};
208
216
@@ -214,8 +222,13 @@ struct SingleProducerTypeTraits
214
222
template <typename ... Args>
215
223
bool push (Args &&... args)
216
224
{
217
- if (BaseType::push_task_count.load (std::memory_order_acquire) == state.pushed_task_count )
218
- return false ;
225
+ if (state.local_push_task_count == state.pushed_task_count )
226
+ {
227
+ const auto stack_local_push_task_count = BaseType::push_task_count.load (std::memory_order_acquire);
228
+ if (state.local_push_task_count == stack_local_push_task_count)
229
+ return false ;
230
+ state.local_push_task_count = stack_local_push_task_count;
231
+ }
219
232
220
233
state.pushed_task_count ++;
221
234
@@ -238,6 +251,7 @@ struct SingleProducerTypeTraits
238
251
template <typename BaseType>
239
252
struct SharedState : BaseType
240
253
{
254
+ protected:
241
255
CacheAlignedAndPaddedObject<std::atomic_size_t > push_task_count{BaseType::COUNT};
242
256
};
243
257
@@ -248,14 +262,14 @@ struct SingleProducerTypeTraits
248
262
249
263
struct SingleConsumerTypeTraits
250
264
{
251
-
252
265
template <typename BaseType>
253
266
struct Behavior : BaseType
254
267
{
255
268
private:
256
269
struct State
257
270
{
258
271
std::size_t popped_task_count{0 };
272
+ std::size_t local_pop_task_count{0 };
259
273
std::size_t begin{0 };
260
274
};
261
275
@@ -266,8 +280,13 @@ struct SingleConsumerTypeTraits
266
280
267
281
OptionalType<ElementType> pop ()
268
282
{
269
- if (BaseType::pop_task_count.load (std::memory_order_acquire) == state.popped_task_count )
270
- return OptionalType<ElementType>{};
283
+ if (state.local_pop_task_count == state.popped_task_count )
284
+ {
285
+ const auto stack_local_pop_task_count = BaseType::pop_task_count.load (std::memory_order_acquire);
286
+ if (state.local_pop_task_count == stack_local_pop_task_count)
287
+ return OptionalType<ElementType>{};
288
+ state.local_pop_task_count = stack_local_pop_task_count;
289
+ }
271
290
272
291
state.popped_task_count ++;
273
292
@@ -293,6 +312,7 @@ struct SingleConsumerTypeTraits
293
312
template <typename BaseType>
294
313
struct SharedState : BaseType
295
314
{
315
+ protected:
296
316
CacheAlignedAndPaddedObject<std::atomic_size_t > pop_task_count{std::size_t {0 }};
297
317
};
298
318
0 commit comments