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 | |
20 | BOOST_AUTO_TEST_CASE( simple_stack_test ) |
21 | { |
22 | boost::lockfree::stack<long> stk(128); |
23 | |
24 | stk.push(v: 1); |
25 | stk.push(v: 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 | |
32 | BOOST_AUTO_TEST_CASE( unsafe_stack_test ) |
33 | { |
34 | boost::lockfree::stack<long> stk(128); |
35 | |
36 | stk.unsynchronized_push(v: 1); |
37 | stk.unsynchronized_push(v: 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 | |
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 | |
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 | |
72 | BOOST_AUTO_TEST_CASE( fixed_size_stack_test ) |
73 | { |
74 | boost::lockfree::stack<long, boost::lockfree::capacity<128> > stk; |
75 | |
76 | stk.push(v: 1); |
77 | stk.push(v: 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 | |
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(v: 1); |
90 | stk.push(v: 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 | |
99 | BOOST_AUTO_TEST_CASE( bounded_stack_test_exhausted ) |
100 | { |
101 | boost::lockfree::stack<long> stk(2); |
102 | |
103 | stk.bounded_push(v: 1); |
104 | stk.bounded_push(v: 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 | |
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(v: 1); |
121 | f.push(v: 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(f: [] (int i) { |
128 | BOOST_REQUIRE_EQUAL(i, 2); |
129 | }); |
130 | |
131 | bool success2 = f.consume_one(f: [] (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 | |
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(v: 1); |
150 | f.push(v: 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(f: [] (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( stack_consume_all_atomic_test ) |
165 | { |
166 | boost::lockfree::stack<int> f(64); |
167 | |
168 | BOOST_WARN(f.is_lock_free()); |
169 | BOOST_REQUIRE(f.empty()); |
170 | |
171 | f.push(v: 1); |
172 | f.push(v: 2); |
173 | f.push(v: 3); |
174 | |
175 | #ifdef BOOST_NO_CXX11_LAMBDAS |
176 | size_t consumed = f.consume_all_atomic(dummy_functor()); |
177 | #else |
178 | size_t consumed = f.consume_all_atomic(f: [] (int i) { |
179 | }); |
180 | #endif |
181 | |
182 | BOOST_REQUIRE_EQUAL(consumed, 3u); |
183 | |
184 | BOOST_REQUIRE(f.empty()); |
185 | } |
186 | |
187 | |
188 | BOOST_AUTO_TEST_CASE( stack_consume_all_atomic_reversed_test ) |
189 | { |
190 | boost::lockfree::stack<int> f(64); |
191 | |
192 | BOOST_WARN(f.is_lock_free()); |
193 | BOOST_REQUIRE(f.empty()); |
194 | |
195 | f.push(v: 1); |
196 | f.push(v: 2); |
197 | f.push(v: 3); |
198 | |
199 | #ifdef BOOST_NO_CXX11_LAMBDAS |
200 | size_t consumed = f.consume_all_atomic_reversed(dummy_functor()); |
201 | #else |
202 | size_t consumed = f.consume_all_atomic_reversed(f: [] (int i) { |
203 | }); |
204 | #endif |
205 | |
206 | BOOST_REQUIRE_EQUAL(consumed, 3u); |
207 | |
208 | BOOST_REQUIRE(f.empty()); |
209 | } |
210 | |
211 | |
212 | BOOST_AUTO_TEST_CASE( reserve_test ) |
213 | { |
214 | typedef boost::lockfree::stack< void* > memory_stack; |
215 | |
216 | memory_stack ms(1); |
217 | ms.reserve(n: 1); |
218 | ms.reserve_unsafe(n: 1); |
219 | } |
220 | |