Skip to content

Commit 5b462e1

Browse files
Improve tests and example code.
1 parent b60e5fd commit 5b462e1

6 files changed

+63
-113
lines changed

Example/Benchmark/Source/main.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ std::pair<std::size_t, std::chrono::nanoseconds> run_benchmark(RingType &ring)
1919
for (std::size_t thread_number = 0; thread_number < NumberOfPopperThreads; thread_number++)
2020
{
2121
poppers.emplace_back([&ring]() {
22-
for (std::size_t i = 0; i < PushCount * NumberOfPusherThreads; i++)
23-
while (!ring.pop())
24-
{
25-
}
22+
for (std::size_t i = 0; i < PushCount * NumberOfPusherThreads;)
23+
if (ring.pop())
24+
i++;
2625
});
2726
}
2827

@@ -35,10 +34,9 @@ std::pair<std::size_t, std::chrono::nanoseconds> run_benchmark(RingType &ring)
3534
{
3635
}
3736

38-
for (std::size_t i = 0; i < PushCount * NumberOfPopperThreads; i++)
39-
while (!ring.push(i))
40-
{
41-
}
37+
for (std::size_t i = 0; i < PushCount * NumberOfPopperThreads;)
38+
if (ring.push(i))
39+
i++;
4240
});
4341
}
4442

Test/Source/cache-aligned-and-padded-object-test.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,63 +13,63 @@ struct alignas(Alignment) SizableAlignableObject
1313

1414
TEST(CacheAlignedAndPaddedObjectTest, UnalignedWithUndevisableSizeObject)
1515
{
16-
constexpr std::size_t Alignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT / 2;
17-
constexpr std::size_t Size = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE / 2;
16+
static constexpr std::size_t Alignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT / 2;
17+
static constexpr std::size_t Size = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE / 2;
1818

1919
using UnalignedWithUndevisableSizeObjectType = SizableAlignableObject<Alignment, Size>;
2020
EXPECT_EQ(Alignment, alignof(UnalignedWithUndevisableSizeObjectType));
2121
EXPECT_EQ(Size, sizeof(UnalignedWithUndevisableSizeObjectType));
2222

23-
constexpr std::size_t ExpectedAlignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT;
24-
constexpr std::size_t ExpectedSize = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE;
23+
static constexpr std::size_t ExpectedAlignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT;
24+
static constexpr std::size_t ExpectedSize = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE;
2525
using CacheAlignedAndPaddedObjectType = Iyp::WaitFreeRingBufferUtilities::Details::CacheAlignedAndPaddedObject<UnalignedWithUndevisableSizeObjectType>;
2626
EXPECT_EQ(ExpectedAlignment, alignof(CacheAlignedAndPaddedObjectType));
2727
EXPECT_EQ(ExpectedSize, sizeof(CacheAlignedAndPaddedObjectType));
2828
}
2929

3030
TEST(CacheAlignedAndPaddedObjectTest, UnalignedWithDevisableSizeObject)
3131
{
32-
constexpr std::size_t Alignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT / 2;
33-
constexpr std::size_t Size = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE * 3;
32+
static constexpr std::size_t Alignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT / 2;
33+
static constexpr std::size_t Size = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE * 3;
3434

3535
using UnalignedWithUndevisableSizeObjectType = SizableAlignableObject<Alignment, Size>;
3636
EXPECT_EQ(Alignment, alignof(UnalignedWithUndevisableSizeObjectType));
3737
EXPECT_EQ(Size, sizeof(UnalignedWithUndevisableSizeObjectType));
3838

39-
constexpr std::size_t ExpectedAlignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT;
40-
constexpr std::size_t ExpectedSize = Size;
39+
static constexpr std::size_t ExpectedAlignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT;
40+
static constexpr std::size_t ExpectedSize = Size;
4141
using CacheAlignedAndPaddedObjectType = Iyp::WaitFreeRingBufferUtilities::Details::CacheAlignedAndPaddedObject<UnalignedWithUndevisableSizeObjectType>;
4242
EXPECT_EQ(ExpectedAlignment, alignof(CacheAlignedAndPaddedObjectType));
4343
EXPECT_EQ(ExpectedSize, sizeof(CacheAlignedAndPaddedObjectType));
4444
}
4545

4646
TEST(CacheAlignedAndPaddedObjectTest, DISABLED_AlignedWithUndevisableSizeObject)
4747
{
48-
constexpr std::size_t Alignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT;
49-
constexpr std::size_t Size = (Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE / 2) * 3;
48+
static constexpr std::size_t Alignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT;
49+
static constexpr std::size_t Size = (Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE / 2) * 3;
5050

5151
using UnalignedWithUndevisableSizeObjectType = SizableAlignableObject<Alignment, Size>;
5252
EXPECT_EQ(Alignment, alignof(UnalignedWithUndevisableSizeObjectType));
5353
EXPECT_EQ(Size, sizeof(UnalignedWithUndevisableSizeObjectType));
5454

55-
constexpr std::size_t ExpectedAlignment = Alignment;
56-
constexpr std::size_t ExpectedSize = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE * 2;
55+
static constexpr std::size_t ExpectedAlignment = Alignment;
56+
static constexpr std::size_t ExpectedSize = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE * 2;
5757
using CacheAlignedAndPaddedObjectType = Iyp::WaitFreeRingBufferUtilities::Details::CacheAlignedAndPaddedObject<UnalignedWithUndevisableSizeObjectType>;
5858
EXPECT_EQ(ExpectedAlignment, alignof(CacheAlignedAndPaddedObjectType));
5959
EXPECT_EQ(ExpectedSize, sizeof(CacheAlignedAndPaddedObjectType));
6060
}
6161

6262
TEST(CacheAlignedAndPaddedObjectTest, AlignedWithDevisableSizeObject)
6363
{
64-
constexpr std::size_t Alignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT;
65-
constexpr std::size_t Size = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE * 3;
64+
static constexpr std::size_t Alignment = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_ALIGNMENT;
65+
static constexpr std::size_t Size = Iyp::WaitFreeRingBufferUtilities::Details::CACHE_LINE_SIZE * 3;
6666

6767
using UnalignedWithUndevisableSizeObjectType = SizableAlignableObject<Alignment, Size>;
6868
EXPECT_EQ(Alignment, alignof(UnalignedWithUndevisableSizeObjectType));
6969
EXPECT_EQ(Size, sizeof(UnalignedWithUndevisableSizeObjectType));
7070

71-
constexpr std::size_t ExpectedAlignment = Alignment;
72-
constexpr std::size_t ExpectedSize = Size;
71+
static constexpr std::size_t ExpectedAlignment = Alignment;
72+
static constexpr std::size_t ExpectedSize = Size;
7373
using CacheAlignedAndPaddedObjectType = Iyp::WaitFreeRingBufferUtilities::Details::CacheAlignedAndPaddedObject<UnalignedWithUndevisableSizeObjectType>;
7474
EXPECT_EQ(ExpectedAlignment, alignof(CacheAlignedAndPaddedObjectType));
7575
EXPECT_EQ(ExpectedSize, sizeof(CacheAlignedAndPaddedObjectType));

Test/Source/multi-producer-multi-consumer-test.cpp

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ namespace Iyp
1010
{
1111
namespace MultiProducerMultiConsumerRingBufferTest
1212
{
13-
constexpr static std::size_t RingSize = 4096;
13+
static constexpr std::size_t RingSize = 4096;
14+
static constexpr std::size_t NumberOfTries = 4096;
1415
using TestRingBufferType = WaitFreeRingBufferUtilities::RingBuffer<std::size_t,
1516
WaitFreeRingBufferUtilities::AccessRequirements::MULTI_CONSUMER |
1617
WaitFreeRingBufferUtilities::AccessRequirements::MULTI_PRODUCER,
1718
RingSize>;
1819

1920
TEST(MultiProducerMultiConsumerRingBufferTest, EmptyAndFullRingTest)
2021
{
21-
constexpr std::size_t NumberOfTries = 256;
22-
2322
TestRingBufferType ring;
2423

2524
EXPECT_FALSE(ring.pop());
@@ -40,8 +39,6 @@ TEST(MultiProducerMultiConsumerRingBufferTest, EmptyAndFullRingTest)
4039

4140
TEST(MultiProducerMultiConsumerRingBufferTest, PushPopIntegrity)
4241
{
43-
constexpr std::size_t NumberOfTries = 256;
44-
4542
TestRingBufferType ring;
4643

4744
for (std::size_t try_index = 0; try_index < NumberOfTries; try_index++)
@@ -64,8 +61,6 @@ TEST(MultiProducerMultiConsumerRingBufferTest, PushPopIntegrity)
6461

6562
TEST(MultiProducerMultiConsumerRingBufferTest, OrderedPushPop)
6663
{
67-
constexpr std::size_t NumberOfTries = 256;
68-
6964
TestRingBufferType ring;
7065

7166
for (std::size_t try_index = 0; try_index < NumberOfTries; try_index++)
@@ -83,9 +78,8 @@ TEST(MultiProducerMultiConsumerRingBufferTest, OrderedPushPop)
8378

8479
TEST(MultiProducerMultiConsumerRingBufferTest, MultiProducerMultiConsumerPushPopIntergrity)
8580
{
86-
constexpr std::size_t NumberOfTries = 256;
87-
constexpr std::size_t NumberOfPusherThreads = 4;
88-
constexpr std::size_t NumberOfPopperThreads = 4;
81+
static constexpr std::size_t NumberOfPusherThreads = 4;
82+
static constexpr std::size_t NumberOfPopperThreads = 4;
8983

9084
ASSERT_EQ(NumberOfTries % NumberOfPusherThreads, 0);
9185
ASSERT_EQ(NumberOfTries % NumberOfPopperThreads, 0);
@@ -101,37 +95,27 @@ TEST(MultiProducerMultiConsumerRingBufferTest, MultiProducerMultiConsumerPushPop
10195

10296
for (std::size_t thread_number = 0; thread_number < NumberOfPopperThreads; thread_number++)
10397
{
104-
poppers.emplace_back([&ring, &pop_counts, NumberOfTries, NumberOfPopperThreads]() {
98+
poppers.emplace_back([&ring, &pop_counts]() {
10599
for (std::size_t try_index = 0; try_index < NumberOfTries / NumberOfPopperThreads; try_index++)
106-
{
107-
for (std::size_t i = 0; i < RingSize; i++)
100+
for (std::size_t i = 0; i < RingSize;)
108101
{
109-
while (true)
102+
const auto popped_value = ring.pop();
103+
if (popped_value)
110104
{
111-
const auto popped_value = ring.pop();
112-
if (popped_value)
113-
{
114-
pop_counts[*popped_value].fetch_add(1, std::memory_order_relaxed);
115-
break;
116-
}
105+
pop_counts[*popped_value].fetch_add(1, std::memory_order_relaxed);
106+
i++;
117107
}
118108
}
119-
}
120109
});
121110
}
122111

123112
for (std::size_t thread_number = 0; thread_number < NumberOfPusherThreads; thread_number++)
124113
{
125-
pushers.emplace_back([&ring, NumberOfTries, NumberOfPusherThreads]() {
114+
pushers.emplace_back([&ring]() {
126115
for (std::size_t try_index = 0; try_index < NumberOfTries / NumberOfPusherThreads; try_index++)
127-
{
128-
for (std::size_t i = 0; i < RingSize; i++)
129-
{
130-
while (!ring.push(i))
131-
{
132-
}
133-
}
134-
}
116+
for (std::size_t i = 0; i < RingSize;)
117+
if (ring.push(i))
118+
i++;
135119
});
136120
}
137121

Test/Source/multi-producer-single-consumer-test.cpp

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ namespace Iyp
1010
{
1111
namespace MultiProducerSingleConsumerRingBufferTest
1212
{
13-
constexpr static std::size_t RingSize = 4096;
13+
static constexpr std::size_t RingSize = 4096;
14+
static constexpr std::size_t NumberOfTries = 1024;
1415
using TestRingBufferType = WaitFreeRingBufferUtilities::RingBuffer<std::size_t,
1516
WaitFreeRingBufferUtilities::AccessRequirements::SINGLE_CONSUMER |
1617
WaitFreeRingBufferUtilities::AccessRequirements::MULTI_PRODUCER,
1718
RingSize>;
1819

1920
TEST(MultiProducerSingleConsumerRingBufferTest, EmptyAndFullRingTest)
2021
{
21-
constexpr std::size_t NumberOfTries = 256;
22-
2322
TestRingBufferType ring;
2423

2524
EXPECT_FALSE(ring.pop());
@@ -40,8 +39,6 @@ TEST(MultiProducerSingleConsumerRingBufferTest, EmptyAndFullRingTest)
4039

4140
TEST(MultiProducerSingleConsumerRingBufferTest, PushPopIntegrity)
4241
{
43-
constexpr std::size_t NumberOfTries = 256;
44-
4542
TestRingBufferType ring;
4643

4744
for (std::size_t try_index = 0; try_index < NumberOfTries; try_index++)
@@ -64,8 +61,6 @@ TEST(MultiProducerSingleConsumerRingBufferTest, PushPopIntegrity)
6461

6562
TEST(MultiProducerSingleConsumerRingBufferTest, OrderedPushPop)
6663
{
67-
constexpr std::size_t NumberOfTries = 256;
68-
6964
TestRingBufferType ring;
7065

7166
for (std::size_t try_index = 0; try_index < NumberOfTries; try_index++)
@@ -83,48 +78,37 @@ TEST(MultiProducerSingleConsumerRingBufferTest, OrderedPushPop)
8378

8479
TEST(MultiProducerSingleConsumerRingBufferTest, MultiProducerSingleConsumerPushPopIntergrity)
8580
{
86-
constexpr std::size_t NumberOfTries = 256;
87-
constexpr std::size_t NumberOfPusherThreads = 7;
81+
static constexpr std::size_t NumberOfPusherThreads = 7;
8882

8983
std::vector<std::thread> pushers;
9084
std::vector<std::thread> poppers;
9185
TestRingBufferType ring;
9286

93-
std::array<std::atomic_size_t, RingSize> pop_counts;
87+
std::array<std::size_t, RingSize> pop_counts;
9488

9589
for (auto &pop_count : pop_counts)
9690
pop_count = 0;
9791

9892
for (std::size_t thread_number = 0; thread_number < NumberOfPusherThreads; thread_number++)
9993
{
100-
pushers.emplace_back([&ring, NumberOfTries, NumberOfPusherThreads]() {
94+
pushers.emplace_back([&ring]() {
10195
for (std::size_t try_index = 0; try_index < NumberOfTries; try_index++)
102-
{
103-
for (std::size_t i = 0; i < RingSize; i++)
104-
{
105-
while (!ring.push(i))
106-
{
107-
}
108-
}
109-
}
96+
for (std::size_t i = 0; i < RingSize;)
97+
if (ring.push(i))
98+
i++;
11099
});
111100
}
112101

113102
for (std::size_t try_index = 0; try_index < NumberOfTries * NumberOfPusherThreads; try_index++)
114-
{
115-
for (std::size_t i = 0; i < RingSize; i++)
103+
for (std::size_t i = 0; i < RingSize;)
116104
{
117-
while (true)
105+
const auto popped_value = ring.pop();
106+
if (popped_value)
118107
{
119-
const auto popped_value = ring.pop();
120-
if (popped_value)
121-
{
122-
pop_counts[*popped_value].fetch_add(1, std::memory_order_relaxed);
123-
break;
124-
}
108+
pop_counts[*popped_value]++;
109+
i++;
125110
}
126111
}
127-
}
128112

129113
for (auto &pusher : pushers)
130114
pusher.join();

Test/Source/single-producer-multi-consumer-test.cpp

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ namespace Iyp
1010
{
1111
namespace SingleProducerMultiConsumerRingBufferTest
1212
{
13-
constexpr static std::size_t RingSize = 4096;
13+
static constexpr std::size_t RingSize = 4096;
14+
static constexpr std::size_t NumberOfTries = 1024;
1415
using TestRingBufferType = WaitFreeRingBufferUtilities::RingBuffer<std::size_t,
1516
WaitFreeRingBufferUtilities::AccessRequirements::MULTI_CONSUMER |
1617
WaitFreeRingBufferUtilities::AccessRequirements::SINGLE_PRODUCER,
1718
RingSize>;
1819

1920
TEST(SingleProducerMultiConsumerRingBufferTest, EmptyAndFullRingTest)
2021
{
21-
constexpr std::size_t NumberOfTries = 256;
22-
2322
TestRingBufferType ring;
2423

2524
EXPECT_FALSE(ring.pop());
@@ -40,8 +39,6 @@ TEST(SingleProducerMultiConsumerRingBufferTest, EmptyAndFullRingTest)
4039

4140
TEST(SingleProducerMultiConsumerRingBufferTest, PushPopIntegrity)
4241
{
43-
constexpr std::size_t NumberOfTries = 256;
44-
4542
TestRingBufferType ring;
4643

4744
for (std::size_t try_index = 0; try_index < NumberOfTries; try_index++)
@@ -64,8 +61,6 @@ TEST(SingleProducerMultiConsumerRingBufferTest, PushPopIntegrity)
6461

6562
TEST(SingleProducerMultiConsumerRingBufferTest, OrderedPushPop)
6663
{
67-
constexpr std::size_t NumberOfTries = 256;
68-
6964
TestRingBufferType ring;
7065

7166
for (std::size_t try_index = 0; try_index < NumberOfTries; try_index++)
@@ -83,8 +78,7 @@ TEST(SingleProducerMultiConsumerRingBufferTest, OrderedPushPop)
8378

8479
TEST(SingleProducerMultiConsumerRingBufferTest, SingleProducerMultiConsumerPushPopIntergrity)
8580
{
86-
constexpr std::size_t NumberOfTries = 256;
87-
constexpr std::size_t NumberOfPopperThreads = 7;
81+
static constexpr std::size_t NumberOfPopperThreads = 7;
8882

8983
std::vector<std::thread> poppers;
9084
TestRingBufferType ring;
@@ -96,34 +90,24 @@ TEST(SingleProducerMultiConsumerRingBufferTest, SingleProducerMultiConsumerPushP
9690

9791
for (std::size_t thread_number = 0; thread_number < NumberOfPopperThreads; thread_number++)
9892
{
99-
poppers.emplace_back([&ring, &pop_counts, NumberOfTries, NumberOfPopperThreads]() {
93+
poppers.emplace_back([&ring, &pop_counts]() {
10094
for (std::size_t try_index = 0; try_index < NumberOfTries; try_index++)
101-
{
102-
for (std::size_t i = 0; i < RingSize; i++)
95+
for (std::size_t i = 0; i < RingSize;)
10396
{
104-
while (true)
97+
const auto popped_value = ring.pop();
98+
if (popped_value)
10599
{
106-
const auto popped_value = ring.pop();
107-
if (popped_value)
108-
{
109-
pop_counts[*popped_value].fetch_add(1, std::memory_order_relaxed);
110-
break;
111-
}
100+
pop_counts[*popped_value].fetch_add(1, std::memory_order_relaxed);
101+
i++;
112102
}
113103
}
114-
}
115104
});
116105
}
117106

118107
for (std::size_t try_index = 0; try_index < NumberOfTries * NumberOfPopperThreads; try_index++)
119-
{
120-
for (std::size_t i = 0; i < RingSize; i++)
121-
{
122-
while (!ring.push(i))
123-
{
124-
}
125-
}
126-
}
108+
for (std::size_t i = 0; i < RingSize;)
109+
if (ring.push(i))
110+
i++;
127111

128112
for (auto &popper : poppers)
129113
popper.join();

0 commit comments

Comments
 (0)