mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-02 08:52:07 +00:00
some checks, tests
This commit is contained in:
@@ -37,6 +37,8 @@ fiber_base::fiber_base( context::fcontext_t * callee, bool preserve_fpu) :
|
||||
void
|
||||
fiber_base::resume()
|
||||
{
|
||||
BOOST_ASSERT( is_running() );
|
||||
|
||||
context::jump_fcontext( & caller_, callee_, 0, preserve_fpu() );
|
||||
|
||||
if ( has_exception() ) rethrow();
|
||||
@@ -47,6 +49,8 @@ fiber_base::suspend()
|
||||
{
|
||||
context::jump_fcontext( callee_, & caller_, 0, preserve_fpu() );
|
||||
|
||||
BOOST_ASSERT( is_running() );
|
||||
|
||||
if ( unwind_requested() ) throw forced_unwind();
|
||||
}
|
||||
|
||||
|
||||
@@ -216,6 +216,7 @@ round_robin::migrate_to( fiber const& f_)
|
||||
{
|
||||
detail::fiber_base::ptr_t f = detail::scheduler::extract( f_);
|
||||
BOOST_ASSERT( f);
|
||||
BOOST_ASSERT( ! f->is_running() );
|
||||
BOOST_ASSERT( ! f->is_terminated() );
|
||||
|
||||
wqueue_.push_back( f);
|
||||
|
||||
@@ -34,4 +34,5 @@ test-suite fibers :
|
||||
[ fiber-test test_futures ]
|
||||
[ fiber-test test_then ]
|
||||
[ fiber-test test_round_robin ]
|
||||
# [ fiber-test test_fiber_steeling ]
|
||||
;
|
||||
|
||||
124
test/test_fiber_steeling.cpp
Normal file
124
test/test_fiber_steeling.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
|
||||
// Copyright Oliver Kowalke 2009.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/atomic.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include <boost/fiber/all.hpp>
|
||||
|
||||
#define MAXCOUNT 50
|
||||
|
||||
boost::atomic< bool > fini( false);
|
||||
boost::fibers::round_robin * other_ds = 0;
|
||||
|
||||
boost::fibers::shared_future< int > fibonacci( int n);
|
||||
|
||||
int fibonacci_( int n)
|
||||
{
|
||||
boost::this_fiber::yield();
|
||||
|
||||
int res = 1;
|
||||
|
||||
if ( 0 != n && 1 != n)
|
||||
{
|
||||
boost::fibers::shared_future< int > f1 = fibonacci( n - 1);
|
||||
boost::fibers::shared_future< int > f2 = fibonacci( n - 2);
|
||||
|
||||
res = f1.get() + f2.get();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
boost::fibers::shared_future< int > fibonacci( int n)
|
||||
{
|
||||
boost::fibers::packaged_task<int> pt(
|
||||
boost::bind( fibonacci_, n) );
|
||||
boost::fibers::shared_future<int> f(pt.get_future());
|
||||
boost::fibers::fiber( boost::move(pt) ).detach();
|
||||
return f;
|
||||
}
|
||||
|
||||
void create_fibers( int n)
|
||||
{
|
||||
int res = fibonacci( n).get();
|
||||
|
||||
fprintf(stderr, "fibonacci(%d) == %d\n", n, res);
|
||||
}
|
||||
|
||||
void fn_create_fibers( boost::fibers::round_robin * ds, boost::barrier * b, int n)
|
||||
{
|
||||
boost::fibers::scheduling_algorithm( ds);
|
||||
|
||||
b->wait();
|
||||
|
||||
boost::fibers::fiber f1(
|
||||
boost::bind( create_fibers, n) );
|
||||
boost::fibers::fiber f2(
|
||||
boost::bind( create_fibers, n) );
|
||||
|
||||
f1.join();
|
||||
f2.join();
|
||||
|
||||
fini = true;
|
||||
}
|
||||
|
||||
void fn_steel_fibers( boost::fibers::round_robin * other_ds, boost::barrier * b, int * count)
|
||||
{
|
||||
BOOST_ASSERT( other_ds);
|
||||
boost::fibers::round_robin ds;
|
||||
boost::fibers::scheduling_algorithm( & ds);
|
||||
|
||||
b->wait();
|
||||
|
||||
while ( ! fini)
|
||||
{
|
||||
boost::fibers::fiber f( other_ds->steel_from() );
|
||||
if ( f)
|
||||
{
|
||||
++( * count);
|
||||
ds.migrate_to( f);
|
||||
while ( boost::fibers::run() );
|
||||
}
|
||||
f.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void test_migrate_fiber()
|
||||
{
|
||||
for ( int i = 0; i < MAXCOUNT; ++i) {
|
||||
fini = false;
|
||||
int n = 10, count = 0;
|
||||
|
||||
boost::fibers::round_robin * ds = new boost::fibers::round_robin();
|
||||
boost::barrier b( 2);
|
||||
boost::thread t1( boost::bind( fn_create_fibers, ds, &b, n) );
|
||||
boost::thread t2( boost::bind( fn_steel_fibers, ds, &b, &count) );
|
||||
|
||||
t1.join();
|
||||
t2.join();
|
||||
|
||||
fprintf(stderr, "stolen fibers == %d\n", count);
|
||||
fprintf(stderr, "%d. finished\n", i);
|
||||
delete ds;
|
||||
}
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
|
||||
{
|
||||
boost::unit_test::test_suite * test =
|
||||
BOOST_TEST_SUITE("Boost.Fiber: round_robin test suite");
|
||||
|
||||
test->add( BOOST_TEST_CASE( & test_migrate_fiber) );
|
||||
|
||||
return test;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ void lazy_generate( boost::barrier * b, int * value)
|
||||
|
||||
boost::xtime xt;
|
||||
boost::xtime_get(&xt, boost::TIME_UTC_);
|
||||
xt.nsec += 50000000 ; // 50ms
|
||||
xt.nsec += 150000000 ; // 150ms
|
||||
//xt.sec += 1; //1 second
|
||||
boost::this_thread::sleep( xt);
|
||||
|
||||
@@ -77,6 +77,7 @@ void interrupt_join_fiber( boost::barrier * b, int * value, bool * interrupted)
|
||||
}
|
||||
catch ( boost::fibers::fiber_interrupted const&)
|
||||
{ * interrupted = true; }
|
||||
//fprintf(stderr, "interrupt_join_fiber() returned\n");
|
||||
}
|
||||
|
||||
void running( boost::barrier * b, int * value)
|
||||
@@ -419,99 +420,6 @@ void test_two_waiter_notify_all()
|
||||
}
|
||||
}
|
||||
|
||||
boost::fibers::shared_future< int > fibonacci( int n);
|
||||
|
||||
int fibonacci_( int n)
|
||||
{
|
||||
boost::this_fiber::yield();
|
||||
|
||||
int res = 1;
|
||||
|
||||
if ( 0 != n && 1 != n)
|
||||
{
|
||||
boost::fibers::shared_future< int > f1 = fibonacci( n - 1);
|
||||
boost::fibers::shared_future< int > f2 = fibonacci( n - 2);
|
||||
|
||||
res = f1.get() + f2.get();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
boost::fibers::shared_future< int > fibonacci( int n)
|
||||
{
|
||||
boost::fibers::packaged_task<int> pt(
|
||||
boost::bind( fibonacci_, n) );
|
||||
boost::fibers::shared_future<int> f(pt.get_future());
|
||||
boost::fibers::fiber( boost::move(pt) ).detach();
|
||||
return f;
|
||||
}
|
||||
|
||||
void create_fibers( int n)
|
||||
{
|
||||
int res = fibonacci( n).get();
|
||||
|
||||
fprintf(stderr, "fibonacci(%d) == %d\n", n, res);
|
||||
}
|
||||
|
||||
void fn_create_fibers( boost::fibers::round_robin * ds, boost::barrier * b, int n)
|
||||
{
|
||||
boost::fibers::scheduling_algorithm( ds);
|
||||
|
||||
b->wait();
|
||||
|
||||
boost::fibers::fiber f1(
|
||||
boost::bind( create_fibers, n) );
|
||||
boost::fibers::fiber f2(
|
||||
boost::bind( create_fibers, n) );
|
||||
|
||||
f1.join();
|
||||
f2.join();
|
||||
|
||||
fini = true;
|
||||
}
|
||||
|
||||
void fn_steel_fibers( boost::fibers::round_robin * other_ds, boost::barrier * b, int * count)
|
||||
{
|
||||
BOOST_ASSERT( other_ds);
|
||||
boost::fibers::round_robin ds;
|
||||
boost::fibers::scheduling_algorithm( & ds);
|
||||
|
||||
b->wait();
|
||||
|
||||
while ( ! fini)
|
||||
{
|
||||
boost::fibers::fiber f( other_ds->steel_from() );
|
||||
if ( f)
|
||||
{
|
||||
++( * count);
|
||||
ds.migrate_to( f);
|
||||
while ( boost::fibers::run() );
|
||||
}
|
||||
f.detach();
|
||||
}
|
||||
}
|
||||
|
||||
void test_migrate_fiber()
|
||||
{
|
||||
for ( int i = 0; i < MAXCOUNT; ++i) {
|
||||
fini = false;
|
||||
int n = 10, count = 0;
|
||||
|
||||
boost::fibers::round_robin * ds = new boost::fibers::round_robin();
|
||||
boost::barrier b( 2);
|
||||
boost::thread t1( boost::bind( fn_create_fibers, ds, &b, n) );
|
||||
boost::thread t2( boost::bind( fn_steel_fibers, ds, &b, &count) );
|
||||
|
||||
t1.join();
|
||||
t2.join();
|
||||
|
||||
fprintf(stderr, "stolen fibers == %d\n", count);
|
||||
fprintf(stderr, "%d. finished\n", i);
|
||||
delete ds;
|
||||
}
|
||||
}
|
||||
|
||||
boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
|
||||
{
|
||||
boost::unit_test::test_suite * test =
|
||||
@@ -519,13 +427,13 @@ boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
|
||||
#if 0
|
||||
test->add( BOOST_TEST_CASE( & test_join_in_fiber_runing) );
|
||||
test->add( BOOST_TEST_CASE( & test_join_in_fiber_terminated) );
|
||||
#endif
|
||||
test->add( BOOST_TEST_CASE( & test_join_in_fiber_interrupted_inside) );
|
||||
#if 0
|
||||
test->add( BOOST_TEST_CASE( & test_join_in_fiber_interrupted_outside) );
|
||||
test->add( BOOST_TEST_CASE( & test_mutex_exclusive) );
|
||||
test->add( BOOST_TEST_CASE( & test_two_waiter_notify_one) );
|
||||
test->add( BOOST_TEST_CASE( & test_two_waiter_notify_all) );
|
||||
#endif
|
||||
test->add( BOOST_TEST_CASE( & test_migrate_fiber) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user