1 //  Copyright (C) 2011 Tim Blechmann
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See
4 //  accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt)
6 
7 
8 #include <boost/thread.hpp>
9 #include <boost/lockfree/stack.hpp>
10 
11 #define BOOST_TEST_MAIN
12 #ifdef BOOST_LOCKFREE_INCLUDE_TESTS
13 #include <boost/test/included/unit_test.hpp>
14 #else
15 #include <boost/test/unit_test.hpp>
16 #endif
17 
18 #include "test_helpers.hpp"
19 
BOOST_AUTO_TEST_CASE(simple_stack_test)20 BOOST_AUTO_TEST_CASE( simple_stack_test )
21 {
22     boost::lockfree::stack<long> stk(128);
23 
24     stk.push(1);
25     stk.push(2);
26     long out;
27     BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 2);
28     BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 1);
29     BOOST_REQUIRE(!stk.pop(out));
30 }
31 
BOOST_AUTO_TEST_CASE(unsafe_stack_test)32 BOOST_AUTO_TEST_CASE( unsafe_stack_test )
33 {
34     boost::lockfree::stack<long> stk(128);
35 
36     stk.unsynchronized_push(1);
37     stk.unsynchronized_push(2);
38     long out;
39     BOOST_REQUIRE(stk.unsynchronized_pop(out)); BOOST_REQUIRE_EQUAL(out, 2);
40     BOOST_REQUIRE(stk.unsynchronized_pop(out)); BOOST_REQUIRE_EQUAL(out, 1);
41     BOOST_REQUIRE(!stk.unsynchronized_pop(out));
42 }
43 
BOOST_AUTO_TEST_CASE(ranged_push_test)44 BOOST_AUTO_TEST_CASE( ranged_push_test )
45 {
46     boost::lockfree::stack<long> stk(128);
47 
48     long data[2] = {1, 2};
49 
50     BOOST_REQUIRE_EQUAL(stk.push(data, data + 2), data + 2);
51 
52     long out;
53     BOOST_REQUIRE(stk.unsynchronized_pop(out)); BOOST_REQUIRE_EQUAL(out, 2);
54     BOOST_REQUIRE(stk.unsynchronized_pop(out)); BOOST_REQUIRE_EQUAL(out, 1);
55     BOOST_REQUIRE(!stk.unsynchronized_pop(out));
56 }
57 
BOOST_AUTO_TEST_CASE(ranged_unsynchronized_push_test)58 BOOST_AUTO_TEST_CASE( ranged_unsynchronized_push_test )
59 {
60     boost::lockfree::stack<long> stk(128);
61 
62     long data[2] = {1, 2};
63 
64     BOOST_REQUIRE_EQUAL(stk.unsynchronized_push(data, data + 2), data + 2);
65 
66     long out;
67     BOOST_REQUIRE(stk.unsynchronized_pop(out)); BOOST_REQUIRE_EQUAL(out, 2);
68     BOOST_REQUIRE(stk.unsynchronized_pop(out)); BOOST_REQUIRE_EQUAL(out, 1);
69     BOOST_REQUIRE(!stk.unsynchronized_pop(out));
70 }
71 
BOOST_AUTO_TEST_CASE(fixed_size_stack_test)72 BOOST_AUTO_TEST_CASE( fixed_size_stack_test )
73 {
74     boost::lockfree::stack<long, boost::lockfree::capacity<128> > stk;
75 
76     stk.push(1);
77     stk.push(2);
78     long out;
79     BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 2);
80     BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 1);
81     BOOST_REQUIRE(!stk.pop(out));
82     BOOST_REQUIRE(stk.empty());
83 }
84 
BOOST_AUTO_TEST_CASE(fixed_size_stack_test_exhausted)85 BOOST_AUTO_TEST_CASE( fixed_size_stack_test_exhausted )
86 {
87     boost::lockfree::stack<long, boost::lockfree::capacity<2> > stk;
88 
89     stk.push(1);
90     stk.push(2);
91     BOOST_REQUIRE(!stk.push(3));
92     long out;
93     BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 2);
94     BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 1);
95     BOOST_REQUIRE(!stk.pop(out));
96     BOOST_REQUIRE(stk.empty());
97 }
98 
BOOST_AUTO_TEST_CASE(bounded_stack_test_exhausted)99 BOOST_AUTO_TEST_CASE( bounded_stack_test_exhausted )
100 {
101     boost::lockfree::stack<long> stk(2);
102 
103     stk.bounded_push(1);
104     stk.bounded_push(2);
105     BOOST_REQUIRE(!stk.bounded_push(3));
106     long out;
107     BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 2);
108     BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 1);
109     BOOST_REQUIRE(!stk.pop(out));
110     BOOST_REQUIRE(stk.empty());
111 }
112 
BOOST_AUTO_TEST_CASE(stack_consume_one_test)113 BOOST_AUTO_TEST_CASE( stack_consume_one_test )
114 {
115     boost::lockfree::stack<int> f(64);
116 
117     BOOST_WARN(f.is_lock_free());
118     BOOST_REQUIRE(f.empty());
119 
120     f.push(1);
121     f.push(2);
122 
123 #ifdef BOOST_NO_CXX11_LAMBDAS
124     bool success1 = f.consume_one(test_equal(2));
125     bool success2 = f.consume_one(test_equal(1));
126 #else
127     bool success1 = f.consume_one([] (int i) {
128         BOOST_REQUIRE_EQUAL(i, 2);
129     });
130 
131     bool success2 = f.consume_one([] (int i) {
132         BOOST_REQUIRE_EQUAL(i, 1);
133     });
134 #endif
135 
136     BOOST_REQUIRE(success1);
137     BOOST_REQUIRE(success2);
138 
139     BOOST_REQUIRE(f.empty());
140 }
141 
BOOST_AUTO_TEST_CASE(stack_consume_all_test)142 BOOST_AUTO_TEST_CASE( stack_consume_all_test )
143 {
144     boost::lockfree::stack<int> f(64);
145 
146     BOOST_WARN(f.is_lock_free());
147     BOOST_REQUIRE(f.empty());
148 
149     f.push(1);
150     f.push(2);
151 
152 #ifdef BOOST_NO_CXX11_LAMBDAS
153     size_t consumed = f.consume_all(dummy_functor());
154 #else
155     size_t consumed = f.consume_all([] (int i) {
156     });
157 #endif
158 
159     BOOST_REQUIRE_EQUAL(consumed, 2u);
160 
161     BOOST_REQUIRE(f.empty());
162 }
163 
164 
BOOST_AUTO_TEST_CASE(reserve_test)165 BOOST_AUTO_TEST_CASE( reserve_test )
166 {
167     typedef boost::lockfree::stack< void* > memory_stack;
168 
169     memory_stack ms(1);
170     ms.reserve(1);
171     ms.reserve_unsafe(1);
172 }
173