boost.atomic: ppc fix
[boost_lockfree.git] / libs / lockfree / test / stack_test.cpp
blobd4b68e91c7f3ec6ae3a335f4d29d2fd89a28333b
1 #include <climits>
2 #define BOOST_TEST_DYN_LINK
3 #define BOOST_TEST_MAIN
4 #include <boost/test/unit_test.hpp>
6 #include "test_helpers.hpp"
8 #include <boost/lockfree/stack.hpp>
10 #include <boost/thread.hpp>
11 #include <iostream>
14 BOOST_AUTO_TEST_CASE( simple_stack_test )
16 boost::lockfree::stack<long> stk;
18 stk.push(1);
19 stk.push(2);
20 long out;
21 BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 2);
22 BOOST_REQUIRE(stk.pop(out)); BOOST_REQUIRE_EQUAL(out, 1);
23 BOOST_REQUIRE(!stk.pop(out));
25 stk.push_unsafe(1);
26 stk.push_unsafe(2);
27 BOOST_REQUIRE(stk.pop_unsafe(out)); BOOST_REQUIRE_EQUAL(out, 2);
28 BOOST_REQUIRE(stk.pop_unsafe(out)); BOOST_REQUIRE_EQUAL(out, 1);
29 BOOST_REQUIRE(!stk.pop_unsafe(out));
33 using namespace boost;
34 using namespace std;
36 template <typename freelist_t>
37 struct stack_tester
39 static const unsigned int buckets = 1<<10;
40 static const long node_count = 200000;
41 static const int reader_threads = 4;
42 static const int writer_threads = 4;
44 static_hashed_set<long, buckets> data;
45 boost::array<std::set<long>, buckets> returned;
47 boost::lockfree::detail::atomic<int> push_count, pop_count;
49 boost::lockfree::stack<long, freelist_t> stk;
51 stack_tester(void):
52 push_count(0), pop_count(0)
54 stk.reserve(128);
57 void add_items(void)
59 for (long i = 0; i != node_count; ++i)
61 long id = generate_id<long>();
63 bool inserted = data.insert(id);
64 assert(inserted);
66 while(stk.push(id) == false)
67 thread::yield();
68 ++push_count;
72 boost::atomic<bool> running;
74 void get_items(void)
76 for (;;)
78 long id;
80 bool got = stk.pop(id);
81 if (got)
83 bool erased = data.erase(id);
84 assert(erased);
85 ++pop_count;
87 else
88 if (not running.load())
89 return;
93 void run(void)
95 BOOST_WARN(stk.is_lock_free());
97 running.store(true);
99 thread_group writer;
100 thread_group reader;
102 BOOST_REQUIRE(stk.empty());
104 for (int i = 0; i != reader_threads; ++i)
105 reader.create_thread(boost::bind(&stack_tester::get_items, this));
107 for (int i = 0; i != writer_threads; ++i)
108 writer.create_thread(boost::bind(&stack_tester::add_items, this));
110 using namespace std;
111 cout << "threads created" << endl;
113 writer.join_all();
115 cout << "writer threads joined, waiting for readers" << endl;
117 running = false;
118 reader.join_all();
120 cout << "reader threads joined" << endl;
122 BOOST_REQUIRE_EQUAL(data.count_nodes(), 0);
123 BOOST_REQUIRE(stk.empty());
125 BOOST_REQUIRE_EQUAL(push_count, pop_count);
126 BOOST_REQUIRE_EQUAL(push_count, writer_threads * node_count);
130 BOOST_AUTO_TEST_CASE( stack_test_caching )
132 stack_tester<boost::lockfree::caching_freelist_t> tester;
133 tester.run();
136 BOOST_AUTO_TEST_CASE( stack_test_static )
138 stack_tester<boost::lockfree::static_freelist_t> tester;
139 tester.run();