2
0
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:
Oliver Kowalke
2013-01-18 17:46:15 +01:00
parent e28cd2c3ff
commit 1e57ade9ac
5 changed files with 134 additions and 96 deletions

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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 ]
;

View 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;
}

View File

@@ -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;
}