]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/test/test_fiber_post.cpp
2 // Copyright Oliver Kowalke 2013.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 // This test is based on the tests of Boost.Thread
14 #include <boost/assert.hpp>
15 #include <boost/test/unit_test.hpp>
17 #include <boost/fiber/all.hpp>
20 std::string value2
= "";
65 moveable( moveable
&& other
) :
72 moveable
& operator=( moveable
&& other
) {
73 if ( this == & other
) return * this;
81 moveable( moveable
const& other
) = delete;
82 moveable
& operator=( moveable
const& other
) = delete;
94 static int alive_count
;
95 static bool was_running
;
102 detachable( detachable
const& g
) :
103 alive_count_( g
.alive_count_
) {
113 BOOST_CHECK_EQUAL(1, alive_count_
);
118 int detachable::alive_count
= 0;
119 bool detachable::was_running
= false;
125 void fn2( int i
, std::string
const& s
) {
132 boost::this_fiber::yield();
134 boost::this_fiber::yield();
136 boost::this_fiber::yield();
138 boost::this_fiber::yield();
140 boost::this_fiber::yield();
145 boost::this_fiber::yield();
149 boost::fibers::fiber
f( boost::fibers::launch::post
, fn4
);
150 BOOST_CHECK( f
.joinable() );
152 BOOST_CHECK( ! f
.joinable() );
155 void test_scheduler_dtor() {
156 boost::fibers::context
* ctx(
157 boost::fibers::context::active() );
161 void test_join_fn() {
164 boost::fibers::fiber
f( boost::fibers::launch::post
, fn1
);
166 BOOST_CHECK_EQUAL( value1
, 1);
171 boost::fibers::fiber
f( boost::fibers::launch::post
, fn2
, 3, "abc");
173 BOOST_CHECK_EQUAL( value1
, 3);
174 BOOST_CHECK_EQUAL( value2
, "abc");
178 void test_join_memfn() {
180 BOOST_CHECK_EQUAL( x
.value
, 0);
181 boost::fibers::fiber( boost::fibers::launch::post
, & X::foo
, std::ref( x
), 3).join();
182 BOOST_CHECK_EQUAL( x
.value
, 3);
185 void test_join_copyable() {
188 BOOST_CHECK( cp
.state
);
189 BOOST_CHECK_EQUAL( value1
, 0);
190 boost::fibers::fiber
f( boost::fibers::launch::post
, cp
);
192 BOOST_CHECK( cp
.state
);
193 BOOST_CHECK_EQUAL( value1
, 3);
196 void test_join_moveable() {
199 BOOST_CHECK( mv
.state
);
200 BOOST_CHECK_EQUAL( value1
, 0);
201 boost::fibers::fiber
f( boost::fibers::launch::post
, std::move( mv
) );
203 BOOST_CHECK( ! mv
.state
);
204 BOOST_CHECK_EQUAL( value1
, 7);
207 void test_join_lambda() {
212 std::string
abc("abc");
213 boost::fibers::fiber
f(
214 boost::fibers::launch::post
, [i
,abc
]() {
219 BOOST_CHECK_EQUAL( value1
, 3);
220 BOOST_CHECK_EQUAL( value2
, "abc");
226 std::string
abc("abc");
227 boost::fibers::fiber
f(
228 boost::fibers::launch::post
, [](int i
, std::string
const& abc
) {
234 BOOST_CHECK_EQUAL( value1
, 3);
235 BOOST_CHECK_EQUAL( value2
, "abc");
239 void test_join_bind() {
244 std::string
abc("abc");
245 boost::fibers::fiber
f(
246 boost::fibers::launch::post
, std::bind(
253 BOOST_CHECK_EQUAL( value1
, 3);
254 BOOST_CHECK_EQUAL( value2
, "abc");
260 std::string
abc("abc");
261 boost::fibers::fiber
f(
262 boost::fibers::launch::post
, std::bind(
263 []( int i
, std::string
& str
) {
270 BOOST_CHECK_EQUAL( value1
, 3);
271 BOOST_CHECK_EQUAL( value2
, "abc");
278 std::string
abc("abc");
279 boost::fibers::fiber
f(
280 boost::fibers::launch::post
, std::bind(
281 []( int i
, std::string
& str
) {
285 std::placeholders::_1
,
286 std::placeholders::_2
290 BOOST_CHECK_EQUAL( value1
, 3);
291 BOOST_CHECK_EQUAL( value2
, "abc");
296 void test_join_in_fiber() {
298 // f spawns an new fiber f' in its fiber-fn
299 // f' yields in its fiber-fn
300 // f joins s' and gets suspended (waiting on s')
301 boost::fibers::fiber
f( boost::fibers::launch::post
, fn5
);
302 BOOST_CHECK( f
.joinable() );
303 // join() resumes f + f' which completes
305 BOOST_CHECK( ! f
.joinable() );
308 void test_move_fiber() {
309 boost::fibers::fiber f1
;
310 BOOST_CHECK( ! f1
.joinable() );
311 boost::fibers::fiber
f2( boost::fibers::launch::post
, fn1
);
312 BOOST_CHECK( f2
.joinable() );
314 BOOST_CHECK( f1
.joinable() );
315 BOOST_CHECK( ! f2
.joinable() );
317 BOOST_CHECK( ! f1
.joinable() );
318 BOOST_CHECK( ! f2
.joinable() );
322 boost::fibers::fiber f1
;
323 boost::fibers::fiber
f2( boost::fibers::launch::post
, fn1
);
324 BOOST_CHECK( ! f1
.joinable() );
325 BOOST_CHECK( f2
.joinable() );
327 BOOST_CHECK_EQUAL( boost::fibers::fiber::id(), f1
.get_id() );
328 BOOST_CHECK( boost::fibers::fiber::id() != f2
.get_id() );
330 boost::fibers::fiber
f3( boost::fibers::launch::post
, fn1
);
331 BOOST_CHECK( f2
.get_id() != f3
.get_id() );
334 BOOST_CHECK( f1
.joinable() );
335 BOOST_CHECK( ! f2
.joinable() );
337 BOOST_CHECK( boost::fibers::fiber::id() != f1
.get_id() );
338 BOOST_CHECK_EQUAL( boost::fibers::fiber::id(), f2
.get_id() );
340 BOOST_CHECK( ! f2
.joinable() );
348 BOOST_CHECK_EQUAL( 0, v1
);
349 BOOST_CHECK_EQUAL( 0, v2
);
350 boost::fibers::fiber
f1( boost::fibers::launch::post
, fn3
, std::ref( v1
) );
351 boost::fibers::fiber
f2( boost::fibers::launch::post
, fn3
, std::ref( v2
) );
354 BOOST_CHECK( ! f1
.joinable() );
355 BOOST_CHECK( ! f2
.joinable() );
356 BOOST_CHECK_EQUAL( 8, v1
);
357 BOOST_CHECK_EQUAL( 8, v2
);
360 void test_sleep_for() {
361 typedef std::chrono::system_clock Clock
;
362 typedef Clock::time_point time_point
;
363 std::chrono::milliseconds
ms(500);
364 time_point t0
= Clock::now();
365 boost::this_fiber::sleep_for(ms
);
366 time_point t1
= Clock::now();
367 std::chrono::nanoseconds ns
= (t1
- t0
) - ms
;
368 std::chrono::nanoseconds err
= ms
/ 100;
369 // The time slept is within 1% of 500ms
370 // This test is spurious as it depends on the time the fiber system switches the fiber
371 BOOST_CHECK((std::max
)(ns
.count(), -ns
.count()) < (err
+std::chrono::milliseconds(1000)).count());
372 //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+std::chrono::milliseconds(1000)).count());
375 void test_sleep_until() {
377 typedef std::chrono::steady_clock Clock
;
378 typedef Clock::time_point time_point
;
379 std::chrono::milliseconds
ms(500);
380 time_point t0
= Clock::now();
381 boost::this_fiber::sleep_until(t0
+ ms
);
382 time_point t1
= Clock::now();
383 std::chrono::nanoseconds ns
= (t1
- t0
) - ms
;
384 std::chrono::nanoseconds err
= ms
/ 100;
385 // The time slept is within 1% of 500ms
386 // This test is spurious as it depends on the time the thread system switches the threads
387 BOOST_CHECK((std::max
)(ns
.count(), -ns
.count()) < (err
+std::chrono::milliseconds(1000)).count());
388 //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+std::chrono::milliseconds(1000)).count());
391 typedef std::chrono::system_clock Clock
;
392 typedef Clock::time_point time_point
;
393 std::chrono::milliseconds
ms(500);
394 time_point t0
= Clock::now();
395 boost::this_fiber::sleep_until(t0
+ ms
);
396 time_point t1
= Clock::now();
397 std::chrono::nanoseconds ns
= (t1
- t0
) - ms
;
398 std::chrono::nanoseconds err
= ms
/ 100;
399 // The time slept is within 1% of 500ms
400 // This test is spurious as it depends on the time the thread system switches the threads
401 BOOST_CHECK((std::max
)(ns
.count(), -ns
.count()) < (err
+std::chrono::milliseconds(1000)).count());
402 //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+std::chrono::milliseconds(1000)).count());
406 void do_wait( boost::fibers::barrier
* b
) {
412 boost::fibers::fiber
f( boost::fibers::launch::post
, (detachable()) );
413 BOOST_CHECK( f
.joinable() );
415 BOOST_CHECK( ! f
.joinable() );
416 boost::this_fiber::sleep_for( std::chrono::milliseconds(250) );
417 BOOST_CHECK( detachable::was_running
);
418 BOOST_CHECK_EQUAL( 0, detachable::alive_count
);
421 boost::fibers::fiber
f( boost::fibers::launch::post
, (detachable()) );
422 BOOST_CHECK( f
.joinable() );
423 boost::this_fiber::yield();
425 BOOST_CHECK( ! f
.joinable() );
426 boost::this_fiber::sleep_for( std::chrono::milliseconds(250) );
427 BOOST_CHECK( detachable::was_running
);
428 BOOST_CHECK_EQUAL( 0, detachable::alive_count
);
432 boost::unit_test::test_suite
* init_unit_test_suite( int, char* []) {
433 boost::unit_test::test_suite
* test
=
434 BOOST_TEST_SUITE("Boost.Fiber: fiber test suite");
436 test
->add( BOOST_TEST_CASE( & test_scheduler_dtor
) );
437 test
->add( BOOST_TEST_CASE( & test_join_fn
) );
438 test
->add( BOOST_TEST_CASE( & test_join_memfn
) );
439 test
->add( BOOST_TEST_CASE( & test_join_copyable
) );
440 test
->add( BOOST_TEST_CASE( & test_join_moveable
) );
441 test
->add( BOOST_TEST_CASE( & test_join_lambda
) );
442 test
->add( BOOST_TEST_CASE( & test_join_bind
) );
443 test
->add( BOOST_TEST_CASE( & test_join_in_fiber
) );
444 test
->add( BOOST_TEST_CASE( & test_move_fiber
) );
445 test
->add( BOOST_TEST_CASE( & test_move_fiber
) );
446 test
->add( BOOST_TEST_CASE( & test_yield
) );
447 test
->add( BOOST_TEST_CASE( & test_sleep_for
) );
448 test
->add( BOOST_TEST_CASE( & test_sleep_until
) );
449 test
->add( BOOST_TEST_CASE( & test_detach
) );