Skip to content

Commit 6ad9115

Browse files
committed
Refactor intrusive_stack implementation and tests
1 parent a401d3f commit 6ad9115

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

include/libconcur/intrusive_stack.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,21 @@
1212

1313
LIBCONCUR_NAMESPACE_BEG_
1414

15+
/// \brief Intrusive stack node.
16+
/// \tparam T The type of the value.
1517
template <typename T>
18+
struct intrusive_node {
19+
T value;
20+
std::atomic<intrusive_node *> next;
21+
};
22+
23+
/// \brief Intrusive stack.
24+
/// \tparam T The type of the value.
25+
/// \tparam Node The type of the node.
26+
template <typename T, typename Node = intrusive_node<T>>
1627
class intrusive_stack {
1728
public:
18-
struct node {
19-
T value;
20-
std::atomic<node *> next{nullptr};
21-
};
29+
using node = Node;
2230

2331
private:
2432
std::atomic<node *> top_{nullptr};
@@ -50,8 +58,8 @@ class intrusive_stack {
5058
return nullptr;
5159
}
5260
} while (!top_.compare_exchange_weak(old_top, old_top->next.load(std::memory_order_relaxed)
53-
, std::memory_order_release
54-
, std::memory_order_acquire));
61+
, std::memory_order_release
62+
, std::memory_order_acquire));
5563
return old_top;
5664
}
5765
};

test/concur/test_concur_stack.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ TEST(intrusive_stack, construct) {
1010
}
1111

1212
TEST(intrusive_stack, construct_node) {
13-
concur::intrusive_stack<int>::node n;
13+
concur::intrusive_stack<int>::node n{};
1414
EXPECT_TRUE(n.next.load(std::memory_order_relaxed) == nullptr);
1515
}
1616

@@ -26,18 +26,19 @@ TEST(intrusive_stack, moveable) {
2626

2727
TEST(intrusive_stack, push_one) {
2828
concur::intrusive_stack<int> s;
29-
concur::intrusive_stack<int>::node n;
29+
concur::intrusive_stack<int>::node n{123};
3030
s.push(&n);
3131
EXPECT_FALSE(s.empty());
3232
EXPECT_TRUE(s.top_.load(std::memory_order_relaxed) == &n);
3333
EXPECT_TRUE(n.next.load(std::memory_order_relaxed) == nullptr);
34+
EXPECT_EQ(n.value, 123);
3435
}
3536

3637
TEST(intrusive_stack, push_many) {
3738
concur::intrusive_stack<int> s;
38-
concur::intrusive_stack<int>::node n1;
39-
concur::intrusive_stack<int>::node n2;
40-
concur::intrusive_stack<int>::node n3;
39+
concur::intrusive_stack<int>::node n1{111111};
40+
concur::intrusive_stack<int>::node n2{222222};
41+
concur::intrusive_stack<int>::node n3{333333};
4142
s.push(&n1);
4243
s.push(&n2);
4344
s.push(&n3);
@@ -46,16 +47,20 @@ TEST(intrusive_stack, push_many) {
4647
EXPECT_TRUE(n3.next.load(std::memory_order_relaxed) == &n2);
4748
EXPECT_TRUE(n2.next.load(std::memory_order_relaxed) == &n1);
4849
EXPECT_TRUE(n1.next.load(std::memory_order_relaxed) == nullptr);
50+
EXPECT_EQ(n1.value, 111111);
51+
EXPECT_EQ(n2.value, 222222);
52+
EXPECT_EQ(n3.value, 333333);
4953
}
5054

5155
TEST(intrusive_stack, push_same) {
5256
concur::intrusive_stack<int> s;
53-
concur::intrusive_stack<int>::node n;
57+
concur::intrusive_stack<int>::node n{321};
5458
s.push(&n);
5559
s.push(&n);
5660
EXPECT_FALSE(s.empty());
5761
EXPECT_TRUE(s.top_.load(std::memory_order_relaxed) == &n);
5862
EXPECT_TRUE(n.next.load(std::memory_order_relaxed) == &n);
63+
EXPECT_EQ(n.value, 321);
5964
}
6065

6166
TEST(intrusive_stack, pop_empty) {
@@ -65,19 +70,20 @@ TEST(intrusive_stack, pop_empty) {
6570

6671
TEST(intrusive_stack, pop_one) {
6772
concur::intrusive_stack<int> s;
68-
concur::intrusive_stack<int>::node n;
73+
concur::intrusive_stack<int>::node n{112233};
6974
s.push(&n);
7075
EXPECT_TRUE(s.pop() == &n);
7176
EXPECT_TRUE(s.empty());
7277
EXPECT_TRUE(s.top_.load(std::memory_order_relaxed) == nullptr);
7378
EXPECT_TRUE(n.next.load(std::memory_order_relaxed) == nullptr);
79+
EXPECT_EQ(n.value, 112233);
7480
}
7581

7682
TEST(intrusive_stack, pop_many) {
7783
concur::intrusive_stack<int> s;
78-
concur::intrusive_stack<int>::node n1;
79-
concur::intrusive_stack<int>::node n2;
80-
concur::intrusive_stack<int>::node n3;
84+
concur::intrusive_stack<int>::node n1{111111};
85+
concur::intrusive_stack<int>::node n2{222222};
86+
concur::intrusive_stack<int>::node n3{333333};
8187
s.push(&n1);
8288
s.push(&n2);
8389
s.push(&n3);
@@ -89,4 +95,7 @@ TEST(intrusive_stack, pop_many) {
8995
EXPECT_TRUE(n3.next.load(std::memory_order_relaxed) == &n2);
9096
EXPECT_TRUE(n2.next.load(std::memory_order_relaxed) == &n1);
9197
EXPECT_TRUE(n1.next.load(std::memory_order_relaxed) == nullptr);
98+
EXPECT_EQ(n1.value, 111111);
99+
EXPECT_EQ(n2.value, 222222);
100+
EXPECT_EQ(n3.value, 333333);
92101
}

0 commit comments

Comments
 (0)