]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/classic/test/owi_mt_tests.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / spirit / classic / test / owi_mt_tests.cpp
1 /*=============================================================================
2 Copyright (c) 2002-2004 Martin Wille
3 http://spirit.sourceforge.net/
4
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9
10 // std::lower_bound seems to perform awfully slow with _GLIBCXX_DEBUG enabled
11 #undef _GLIBCXX_DEBUG
12
13 #include <iostream>
14 #include <boost/config.hpp>
15 #include <boost/core/lightweight_test.hpp>
16
17 #if !defined(BOOST_HAS_THREADS) || defined(DONT_HAVE_BOOST) || defined(BOOST_DISABLE_THREADS)
18 static void skipped()
19 {
20 std::cout << "skipped\n";
21 }
22
23 int
24 main()
25 {
26 skipped();
27 return 0;
28 }
29 #else
30
31 ////////////////////////////////////////////////////////////////////////////////
32
33 static const unsigned long initial_test_size = 5000UL;
34 #if defined(_DEBUG) && (BOOST_MSVC >= 1400)
35 static const unsigned long maximum_test_size = 10000UL;
36 #else
37 static const unsigned long maximum_test_size = 1000000UL;
38 #endif
39
40 ////////////////////////////////////////////////////////////////////////////////
41
42 #undef BOOST_SPIRIT_THREADSAFE
43 #define BOOST_SPIRIT_THREADSAFE
44
45 #include <boost/thread/thread.hpp>
46 #include <boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp>
47 #include <boost/ref.hpp>
48 #include <boost/thread/xtime.hpp>
49 #include <boost/thread/mutex.hpp>
50 #include <boost/thread/lock_types.hpp>
51 #include <vector>
52 #include <algorithm>
53 #include <boost/core/lightweight_test.hpp>
54
55 using BOOST_SPIRIT_CLASSIC_NS::impl::object_with_id;
56
57 struct tag1 {};
58 typedef object_with_id<tag1> class1;
59
60 unsigned long test_size = initial_test_size;
61 boost::xtime start_time;
62
63 template <typename ClassT>
64 struct test_task
65 {
66 test_task() : v(), m(), progress(0) {}
67
68 void operator ()()
69 { // create lots of objects
70 unsigned long i = 0;
71
72 v.reserve(maximum_test_size);
73 do
74 {
75 for (; i<test_size; ++i)
76 v.push_back(new ClassT);
77 }
78 while ( i < increase_test_size(i) );
79 }
80
81 static unsigned long
82 increase_test_size(unsigned long size)
83 {
84 static boost::mutex m;
85 boost::unique_lock<boost::mutex> l(m);
86
87 if (size<test_size || test_size == maximum_test_size)
88 return test_size;
89
90 boost::xtime now;
91 boost::xtime_get(&now, boost::TIME_UTC_);
92 boost::xtime::xtime_sec_t seconds = now.sec - start_time.sec;
93 if (seconds < 4)
94 {
95 test_size *= 2;
96 if (test_size > maximum_test_size)
97 test_size = maximum_test_size;
98 }
99
100 return test_size;
101 }
102
103 std::vector<ClassT*> const &data() const
104 {
105 return v;
106 }
107
108 private:
109 std::vector<ClassT*> v;
110 boost::mutex m;
111 unsigned int progress;
112 };
113
114 template <typename T>
115 class callable_reference_wrapper
116 : public boost::reference_wrapper<T>
117 {
118 public:
119 explicit callable_reference_wrapper(T& t)
120 : boost::reference_wrapper<T>(t)
121 {}
122 inline void operator()() { this->get().operator()(); }
123 };
124
125 template <typename T>
126 callable_reference_wrapper<T>
127 callable_ref(T &t)
128 {
129 return callable_reference_wrapper<T>(t);
130 }
131
132 test_task<class1> test1;
133 test_task<class1> test2;
134 test_task<class1> test3;
135
136
137 template <typename ClassT>
138 void
139 check_ascending(test_task<ClassT> const &t)
140 {
141 typedef typename std::vector<ClassT*>::const_iterator iter;
142 iter p(t.data().begin());
143 iter const e(t.data().end());
144 iter n(p);
145
146 while (++n!=e)
147 {
148 if ((**n).get_object_id()<=(**p).get_object_id())
149 {
150 using namespace std;
151 throw std::runtime_error("object ids out of order");
152 }
153 p = n;
154 }
155 }
156
157 struct less1
158 {
159 bool operator()(class1 const *p, class1 const *q) const
160 {
161 return p->get_object_id() < q->get_object_id();
162 }
163 };
164
165 template <typename ClassT>
166 void
167 check_not_contained_in(
168 test_task<ClassT> const &candidate,
169 test_task<ClassT> const &in
170 )
171 {
172 typedef typename std::vector<ClassT*>::const_iterator iter;
173 iter p(candidate.data().begin());
174 iter const e(candidate.data().end());
175
176 while (p!=e)
177 {
178 iter found = std::lower_bound(in.data().begin(),in.data().end(),*p,less1());
179 if (found!=in.data().end() &&
180 (**found).get_object_id() == (**p).get_object_id())
181 {
182 using namespace std;
183 throw std::runtime_error("object ids not unqiue");
184 }
185 ++p;
186 }
187 }
188
189 void concurrent_creation_of_objects()
190 {
191 {
192 boost::xtime_get(&start_time, boost::TIME_UTC_);
193 boost::thread thread1(callable_ref(test1));
194 boost::thread thread2(callable_ref(test2));
195 boost::thread thread3(callable_ref(test3));
196
197 thread1.join();
198 thread2.join();
199 thread3.join();
200 }
201 }
202
203 void local_uniqueness()
204 {
205
206
207 BOOST_TEST(test1.data().size()==test_size);
208 BOOST_TEST(test2.data().size()==test_size);
209 BOOST_TEST(test3.data().size()==test_size);
210 }
211
212 void local_ordering_and_uniqueness()
213 {
214 // now all objects should have unique ids,
215 // the ids must be ascending within each vector
216 // check for ascending ids
217 check_ascending(test1);
218 check_ascending(test2);
219 check_ascending(test3);
220 }
221
222 void global_uniqueness()
223 {
224 check_not_contained_in(test1,test3);
225 check_not_contained_in(test1,test2);
226 check_not_contained_in(test2,test1);
227 check_not_contained_in(test2,test3);
228 check_not_contained_in(test3,test2);
229 check_not_contained_in(test3,test1);
230 }
231
232 int
233 main()
234 {
235 concurrent_creation_of_objects();
236 local_ordering_and_uniqueness();
237 global_uniqueness();
238 return boost::report_errors();
239 }
240
241 #endif // BOOST_HAS_THREADS
242