2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-20 02:32:19 +00:00

fiber removed

This commit is contained in:
Oliver Kowalke
2011-10-25 15:03:08 +02:00
parent f850757dc8
commit af9f12d83c
29 changed files with 0 additions and 3320 deletions

View File

@@ -1,14 +0,0 @@
// 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)
#ifndef BOOST_FIBER_H
#define BOOST_FIBER_H
#include <boost/fiber/asym_fiber.hpp>
#include <boost/fiber/exceptions.hpp>
#include <boost/fiber/sym_fiber.hpp>
#endif // BOOST_FIBER_H

View File

@@ -1,228 +0,0 @@
// 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)
#ifndef BOOST_FIBERS_ASYM_FIBER_H
#define BOOST_FIBERS_ASYM_FIBER_H
#include <cstddef>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/preprocessor/repetition.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/asym_fiber_base.hpp>
#include <boost/fiber/detail/asym_fiber_object.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
# if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4251)
# endif
namespace boost {
namespace fibers {
class BOOST_FIBER_DECL asym_fiber
{
private:
struct dummy {};
BOOST_COPYABLE_AND_MOVABLE( asym_fiber);
detail::asym_fiber_base::ptr impl_;
static detail::asym_fiber_base::ptr make_fiber_(
void( * fn)(), std::size_t stacksize, bool do_return)
{
return detail::asym_fiber_base::ptr(
do_return
? new detail::asym_fiber_object< void(*)() >( fn, stacksize, detail::asym_fiber_base::do_return)
: new detail::asym_fiber_object< void(*)() >( fn, stacksize, detail::asym_fiber_base::do_not_return) );
}
#ifdef BOOST_MSVC
template< typename Fn >
static detail::asym_fiber_base::ptr make_fiber_(
Fn & fn, std::size_t stacksize, bool do_return)
{
return detail::asym_fiber_base::ptr(
do_return
? new detail::asym_fiber_object< Fn >( fn, stacksize, detail::asym_fiber_base::do_return)
: new detail::asym_fiber_object< Fn >( fn, stacksize, detail::asym_fiber_base::do_not_return) );
}
#else
template< typename Fn >
static detail::asym_fiber_base::ptr make_fiber_(
Fn fn, std::size_t stacksize, bool do_return)
{
return detail::asym_fiber_base::ptr(
do_return
? new detail::asym_fiber_object< Fn >( fn, stacksize, detail::asym_fiber_base::do_return)
: new detail::asym_fiber_object< Fn >( fn, stacksize, detail::asym_fiber_base::do_not_return) );
}
#endif
template< typename Fn >
static detail::asym_fiber_base::ptr make_fiber__(
BOOST_RV_REF( Fn) fn, std::size_t stacksize, bool do_return)
{
return detail::asym_fiber_base::ptr(
do_return
? new detail::asym_fiber_object< Fn >( fn, stacksize, detail::asym_fiber_base::do_return)
: new detail::asym_fiber_object< Fn >( fn, stacksize, detail::asym_fiber_base::do_not_return) );
}
public:
static std::size_t max_stacksize;
static std::size_t min_stacksize;
static std::size_t default_stacksize;
class id;
asym_fiber();
#ifdef BOOST_MSVC
template< typename Fn >
asym_fiber( Fn & fn, std::size_t stacksize, bool do_return = true) :
impl_( make_fiber_( fn, stacksize, do_return) )
{}
#else
template< typename Fn >
asym_fiber( Fn fn, std::size_t stacksize, bool do_return = true) :
impl_( make_fiber_( fn, stacksize, do_return) )
{}
#endif
template< typename Fn >
asym_fiber( BOOST_RV_REF( Fn) fn, std::size_t stacksize, bool do_return = true) :
impl_( make_fiber__( fn, stacksize, do_return) )
{}
#define BOOST_FIBERS_ASYM_FIBER_ARG(z, n, unused) \
BOOST_PP_CAT(A, n) BOOST_PP_CAT(a, n)
#define BOOST_ENUM_FIBERS_ASYM_FIBER_ARGS(n) BOOST_PP_ENUM(n, BOOST_FIBERS_ASYM_FIBER_ARG, ~)
#define BOOST_FIBERS_ASYM_FIBER_CTOR(z, n, unused) \
template< typename Fn, BOOST_PP_ENUM_PARAMS(n, typename A) > \
asym_fiber( Fn fn, BOOST_ENUM_FIBERS_ASYM_FIBER_ARGS(n), std::size_t stacksize, bool do_return = true) : \
impl_( \
make_fiber_( \
boost::bind( boost::type< void >(), fn, BOOST_PP_ENUM_PARAMS(n, a) ), \
stacksize, do_return) ) \
{} \
#ifndef BOOST_FIBERS_ASYM_MAX_ARITY
#define BOOST_FIBERS_ASYM_MAX_ARITY 10
#endif
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_FIBERS_ASYM_MAX_ARITY, BOOST_FIBERS_ASYM_FIBER_CTOR, ~)
#undef BOOST_FIBERS_ASYM_MAY_ARITY
#undef BOOST_FIBERS_ASYM_FIBER_ARG
#undef BOOST_FIBERS_ASYM_FIBER_ARGS
#undef BOOST_FIBERS_ASYM_FIBER_CTOR
asym_fiber( asym_fiber const& other);
asym_fiber & operator=( BOOST_COPY_ASSIGN_REF( asym_fiber) other);
asym_fiber( BOOST_RV_REF( asym_fiber) other);
asym_fiber & operator=( BOOST_RV_REF( asym_fiber) other);
typedef detail::asym_fiber_base::ptr::unspecified_bool_type unspecified_bool_type;
operator unspecified_bool_type() const;
bool operator!() const;
void swap( asym_fiber & other);
id get_id() const;
bool operator==( asym_fiber const& other) const;
bool operator!=( asym_fiber const& other) const;
void run();
void yield();
bool finished() const;
};
class BOOST_FIBER_DECL asym_fiber::id
{
private:
friend class asym_fiber;
boost::uint64_t id_;
explicit id( detail::asym_fiber_base::ptr const& info) :
id_( reinterpret_cast< boost::uint64_t >( info.get() ) )
{}
public:
id() :
id_( 0)
{}
bool operator==( id const& other) const
{ return id_ == other.id_; }
bool operator!=( id const& other) const
{ return id_ != other.id_; }
bool operator<( id const& other) const
{ return id_ < other.id_; }
bool operator>( id const& other) const
{ return other.id_ < id_; }
bool operator<=( id const& other) const
{ return !( other.id_ < id_); }
bool operator>=( id const& other) const
{ return ! ( id_ < other.id_); }
template< typename charT, class traitsT >
friend std::basic_ostream< charT, traitsT > &
operator<<( std::basic_ostream< charT, traitsT > & os, id const& other)
{
if ( 0 != other.id_) return os << other.id_;
else return os << "{not-a-fiber}";
}
};
inline
void swap( asym_fiber & l, asym_fiber & r)
{ return l.swap( r); }
}
using fibers::asym_fiber;
}
# if defined(BOOST_MSVC)
# pragma warning(pop)
# endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_ASYM_FIBER_H

View File

@@ -1,92 +0,0 @@
// 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)
#ifndef BOOST_FIBERS_DETAIL_ASYM_FIBER_BASE_H
#define BOOST_FIBERS_DETAIL_ASYM_FIBER_BASE_H
#include <cstddef>
#include <stack>
#include <boost/config.hpp>
#include <boost/context/all.hpp>
#include <boost/function.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4251)
#pragma warning(disable:4275)
#endif
namespace boost {
namespace fibers {
namespace detail {
BOOST_FIBER_DECL void trampoline_asym( void *);
class BOOST_FIBER_DECL asym_fiber_base : private noncopyable
{
public:
typedef intrusive_ptr< asym_fiber_base > ptr;
struct do_not_return_t {};
struct do_return_t {};
static do_not_return_t do_not_return;
static do_return_t do_return;
friend BOOST_FIBER_DECL void trampoline_asym( void * vp);
friend inline void intrusive_ptr_add_ref( asym_fiber_base * p)
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( asym_fiber_base * p)
{ if ( --p->use_count_ == 0) delete p; }
asym_fiber_base( std::size_t stacksize, do_not_return_t);
asym_fiber_base( std::size_t stacksize, do_return_t);
virtual ~asym_fiber_base() {}
void run();
void yield();
void set_finished();
bool get_finished() const;
protected:
virtual void exec() = 0;
private:
unsigned int use_count_;
bool finished_;
context<> caller_;
context<> callee_;
};
}}}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_ASYM_FIBER_BASE_H

View File

@@ -1,125 +0,0 @@
// 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)
#ifndef BOOST_FIBERS_DETAIL_ASYM_FIBER_OBJECT_H
#define BOOST_FIBERS_DETAIL_ASYM_FIBER_OBJECT_H
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/asym_fiber_base.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
namespace detail {
template< typename Fn >
class asym_fiber_object : public asym_fiber_base
{
private:
Fn fn_;
asym_fiber_object( asym_fiber_object &);
asym_fiber_object & operator=( asym_fiber_object const&);
public:
asym_fiber_object( Fn fn, std::size_t stacksize, do_return_t v) :
asym_fiber_base( stacksize, v),
fn_( fn)
{}
asym_fiber_object( Fn fn, std::size_t stacksize, do_not_return_t v) :
asym_fiber_base( stacksize, v),
fn_( fn)
{}
void exec()
{ fn_(); }
};
template< typename Fn >
class asym_fiber_object< BOOST_RV_REF( Fn) > : public asym_fiber_base
{
private:
Fn fn_;
asym_fiber_object( asym_fiber_object &);
asym_fiber_object & operator=( asym_fiber_object const&);
public:
asym_fiber_object( BOOST_RV_REF( Fn) fn, std::size_t stacksize, do_return_t v) :
asym_fiber_base( stacksize, v),
fn_( fn)
{}
asym_fiber_object( BOOST_RV_REF( Fn) fn, std::size_t stacksize, do_not_return_t v) :
asym_fiber_base( stacksize, v),
fn_( fn)
{}
void exec()
{ fn_(); }
};
template< typename Fn >
class asym_fiber_object< reference_wrapper< Fn > > : public asym_fiber_base
{
private:
Fn & fn_;
asym_fiber_object( asym_fiber_object &);
asym_fiber_object & operator=( asym_fiber_object const&);
public:
asym_fiber_object( reference_wrapper< Fn > fn, std::size_t stacksize, do_return_t v) :
asym_fiber_base( stacksize, v),
fn_( fn)
{}
asym_fiber_object( reference_wrapper< Fn > fn, std::size_t stacksize, do_not_return_t v) :
asym_fiber_base( stacksize, v),
fn_( fn)
{}
void exec()
{ fn_(); }
};
template< typename Fn >
class asym_fiber_object< const reference_wrapper< Fn > > : public asym_fiber_base
{
private:
Fn & fn_;
asym_fiber_object( asym_fiber_object &);
asym_fiber_object & operator=( asym_fiber_object const&);
public:
asym_fiber_object( const reference_wrapper< Fn > fn, std::size_t stacksize, do_return_t v) :
asym_fiber_base( stacksize, v),
fn_( fn)
{}
void exec()
{ fn_(); }
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_ASYM_FIBER_OBJECT_H

View File

@@ -1,33 +0,0 @@
// 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)
// this file is based on config.hpp of boost.thread
#ifndef BOOST_FIBERS_DETAIL_CONFIG_H
#define BOOST_FIBERS_DETAIL_CONFIG_H
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FIBER_DYN_LINK)
# if defined(BOOST_FIBER_SOURCE)
# define BOOST_FIBER_DECL BOOST_SYMBOL_EXPORT
# else
# define BOOST_FIBER_DECL BOOST_SYMBOL_IMPORT
# endif
#else
# define BOOST_FIBER_DECL
#endif
#if ! defined(BOOST_FIBER_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FIBER_NO_LIB)
# define BOOST_LIB_NAME boost_fiber
# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FIBER_DYN_LINK)
# define BOOST_DYN_LINK
# endif
# include <boost/config/auto_link.hpp>
#endif
#endif // BOOST_FIBERS_DETAIL_CONFIG_H

View File

@@ -1,84 +0,0 @@
// 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)
#ifndef BOOST_FIBERS_DETAIL_SYM_FIBER_BASE_H
#define BOOST_FIBERS_DETAIL_SYM_FIBER_BASE_H
#include <cstddef>
#include <stack>
#include <boost/config.hpp>
#include <boost/context/all.hpp>
#include <boost/function.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4251)
#pragma warning(disable:4275)
#endif
namespace boost {
namespace fibers {
namespace detail {
BOOST_FIBER_DECL void trampoline_sym( void *);
class BOOST_FIBER_DECL sym_fiber_base : private noncopyable
{
public:
typedef intrusive_ptr< sym_fiber_base > ptr;
friend BOOST_FIBER_DECL void trampoline_sym( void * vp);
friend inline void intrusive_ptr_add_ref( sym_fiber_base * p)
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( sym_fiber_base * p)
{ if ( --p->use_count_ == 0) delete p; }
sym_fiber_base();
sym_fiber_base( std::size_t stacksize);
sym_fiber_base( std::size_t stacksize, sym_fiber_base & nxt);
virtual ~sym_fiber_base() {}
void switch_to( sym_fiber_base & other);
void set_finished();
bool get_finished() const;
protected:
virtual void exec() = 0;
private:
unsigned int use_count_;
bool finished_;
context<> ctx_;
};
}}}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_SYM_FIBER_BASE_H

View File

@@ -1,145 +0,0 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software Licenseersion 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_FIBERS_DETAIL_SYM_FIBER_OBJECT_H
#define BOOST_FIBERS_DETAIL_SYM_FIBER_OBJECT_H
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/sym_fiber_base.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
namespace detail {
class sym_fiber_dummy : public sym_fiber_base
{
private:
sym_fiber_dummy( sym_fiber_dummy &);
sym_fiber_dummy & operator=( sym_fiber_dummy const&);
public:
sym_fiber_dummy() :
sym_fiber_base()
{}
void exec()
{ BOOST_ASSERT( false && "should not be invoked"); }
};
template< typename Fn >
class sym_fiber_object : public sym_fiber_base
{
private:
Fn fn_;
sym_fiber_object( sym_fiber_object &);
sym_fiber_object & operator=( sym_fiber_object const&);
public:
sym_fiber_object( Fn fn, std::size_t stacksize) :
sym_fiber_base( stacksize),
fn_( fn)
{}
sym_fiber_object( Fn fn, std::size_t stacksize, sym_fiber_base & nxt) :
sym_fiber_base( stacksize, nxt),
fn_( fn)
{}
void exec()
{ fn_(); }
};
template< typename Fn >
class sym_fiber_object< BOOST_RV_REF( Fn) > : public sym_fiber_base
{
private:
Fn fn_;
sym_fiber_object( sym_fiber_object &);
sym_fiber_object & operator=( sym_fiber_object const&);
public:
sym_fiber_object( BOOST_RV_REF( Fn) fn, std::size_t stacksize) :
sym_fiber_base( stacksize),
fn_( fn)
{}
sym_fiber_object( BOOST_RV_REF( Fn) fn, std::size_t stacksize, sym_fiber_base & nxt) :
sym_fiber_base( stacksize, nxt),
fn_( fn)
{}
void exec()
{ fn_(); }
};
template< typename Fn >
class sym_fiber_object< reference_wrapper< Fn > > : public sym_fiber_base
{
private:
Fn & fn_;
sym_fiber_object( sym_fiber_object &);
sym_fiber_object & operator=( sym_fiber_object const&);
public:
sym_fiber_object( reference_wrapper< Fn > fn, std::size_t stacksize) :
sym_fiber_base( stacksize),
fn_( fn)
{}
sym_fiber_object( reference_wrapper< Fn > fn, std::size_t stacksize, sym_fiber_base & nxt) :
sym_fiber_base( stacksize, nxt),
fn_( fn)
{}
void exec()
{ fn_(); }
};
template< typename Fn >
class sym_fiber_object< const reference_wrapper< Fn > > : public sym_fiber_base
{
private:
Fn & fn_;
sym_fiber_object( sym_fiber_object &);
sym_fiber_object & operator=( sym_fiber_object const&);
public:
sym_fiber_object( const reference_wrapper< Fn > fn, std::size_t stacksize) :
sym_fiber_base( stacksize),
fn_( fn)
{}
sym_fiber_object( const reference_wrapper< Fn > fn, std::size_t stacksize, sym_fiber_base & nxt) :
sym_fiber_base( stacksize, nxt),
fn_( fn)
{}
void exec()
{ fn_(); }
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_DETAIL_SYM_FIBER_OBJECT_H

View File

@@ -1,38 +0,0 @@
// 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)
#ifndef BOOST_FIBERS_EXCEPTIONS_H
#define BOOST_FIBERS_EXCEPTIONS_H
#include <stdexcept>
#include <string>
#include <boost/config.hpp>
#include <boost/fiber/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
class BOOST_FIBER_DECL fiber_moved : public std::logic_error
{
public:
fiber_moved() :
std::logic_error("fiber moved")
{}
};
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_EXCEPTIONS_H

View File

@@ -1,276 +0,0 @@
// 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)
#ifndef BOOST_FIBERS_SYM_FIBER_H
#define BOOST_FIBERS_SYM_FIBER_H
#include <cstddef>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/preprocessor/repetition.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/sym_fiber_base.hpp>
#include <boost/fiber/detail/sym_fiber_object.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
# if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4251)
# endif
namespace boost {
namespace fibers {
class BOOST_FIBER_DECL sym_fiber
{
private:
struct dummy {};
BOOST_COPYABLE_AND_MOVABLE( sym_fiber);
detail::sym_fiber_base::ptr impl_;
sym_fiber( detail::sym_fiber_base::ptr const& impl);
static detail::sym_fiber_base::ptr make_fiber_(
void( * fn)(), std::size_t stacksize)
{
return detail::sym_fiber_base::ptr(
new detail::sym_fiber_object< void(*)() >( fn, stacksize) );
}
static detail::sym_fiber_base::ptr make_fiber_( void( * fn)(),
std::size_t stacksize, detail::sym_fiber_base::ptr & nxt)
{
return detail::sym_fiber_base::ptr(
new detail::sym_fiber_object< void(*)() >( fn, stacksize, * nxt) );
}
#ifdef BOOST_MSVC
template< typename Fn >
static detail::sym_fiber_base::ptr make_fiber_(
Fn & fn, std::size_t stacksize)
{
return detail::sym_fiber_base::ptr(
new detail::sym_fiber_object< Fn >( fn, stacksize) );
}
template< typename Fn >
static detail::sym_fiber_base::ptr make_fiber_(
Fn & fn, std::size_t stacksize, detail::sym_fiber_base::ptr & nxt)
{
return detail::sym_fiber_base::ptr(
new detail::sym_fiber_object< Fn >( fn, stacksize, * nxt) );
}
#else
template< typename Fn >
static detail::sym_fiber_base::ptr make_fiber_(
Fn fn, std::size_t stacksize)
{
return detail::sym_fiber_base::ptr(
new detail::sym_fiber_object< Fn >( fn, stacksize) );
}
template< typename Fn >
static detail::sym_fiber_base::ptr make_fiber_(
Fn fn, std::size_t stacksize, detail::sym_fiber_base::ptr & nxt)
{
return detail::sym_fiber_base::ptr(
new detail::sym_fiber_object< Fn >( fn, stacksize, * nxt) );
}
#endif
template< typename Fn >
static detail::sym_fiber_base::ptr make_fiber__(
BOOST_RV_REF( Fn) fn, std::size_t stacksize)
{
return detail::sym_fiber_base::ptr(
new detail::sym_fiber_object< Fn >( fn, stacksize) );
}
template< typename Fn >
static detail::sym_fiber_base::ptr make_fiber__( BOOST_RV_REF( Fn) fn,
std::size_t stacksize, detail::sym_fiber_base::ptr & nxt)
{
return detail::sym_fiber_base::ptr(
new detail::sym_fiber_object< Fn >( fn, stacksize, * nxt) );
}
public:
static std::size_t max_stacksize;
static std::size_t min_stacksize;
static std::size_t default_stacksize;
static sym_fiber from_current_context();
class id;
sym_fiber();
#ifdef BOOST_MSVC
template< typename Fn >
sym_fiber( Fn & fn, std::size_t stacksize) :
impl_( make_fiber_( fn, stacksize) )
{}
template< typename Fn >
sym_fiber( Fn & fn, std::size_t stacksize, sym_fiber & nxt) :
impl_( make_fiber_( fn, stacksize, nxt.impl_) )
{}
#else
template< typename Fn >
sym_fiber( Fn fn, std::size_t stacksize) :
impl_( make_fiber_( fn, stacksize) )
{}
template< typename Fn >
sym_fiber( Fn fn, std::size_t stacksize, sym_fiber & nxt) :
impl_( make_fiber_( fn, stacksize, nxt.impl_) )
{}
#endif
template< typename Fn >
sym_fiber( BOOST_RV_REF( Fn) fn, std::size_t stacksize) :
impl_( make_fiber__( fn, stacksize) )
{}
template< typename Fn >
sym_fiber( BOOST_RV_REF( Fn) fn, std::size_t stacksize, sym_fiber & nxt) :
impl_( make_fiber__( fn, stacksize, nxt.impl_) )
{}
#define BOOST_FIBERS_SYM_FIBER_ARG(z, n, unused) \
BOOST_PP_CAT(A, n) BOOST_PP_CAT(a, n)
#define BOOST_ENUM_FIBERS_SYM_FIBER_ARGS(n) BOOST_PP_ENUM(n, BOOST_FIBERS_SYM_FIBER_ARG, ~)
#define BOOST_FIBERS_SYM_FIBER_CTOR(z, n, unused) \
template< typename Fn, BOOST_PP_ENUM_PARAMS(n, typename A) > \
sym_fiber( Fn fn, BOOST_ENUM_FIBERS_SYM_FIBER_ARGS(n), std::size_t stacksize) : \
impl_( \
make_fiber_( \
boost::bind( boost::type< void >(), fn, BOOST_PP_ENUM_PARAMS(n, a) ), \
stacksize) ) \
{} \
\
template< typename Fn, BOOST_PP_ENUM_PARAMS(n, typename A) > \
sym_fiber( Fn fn, BOOST_ENUM_FIBERS_SYM_FIBER_ARGS(n), std::size_t stacksize, sym_fiber & nxt) : \
impl_( \
make_fiber_( \
boost::bind( boost::type< void >(), fn, BOOST_PP_ENUM_PARAMS(n, a) ), \
stacksize, nxt.impl_) ) \
{} \
#ifndef BOOST_FIBERS_SYM_MAX_ARITY
#define BOOST_FIBERS_SYM_MAX_ARITY 10
#endif
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_FIBERS_SYM_MAX_ARITY, BOOST_FIBERS_SYM_FIBER_CTOR, ~)
#undef BOOST_FIBERS_SYM_MAY_ARITY
#undef BOOST_FIBERS_SYM_FIBER_ARG
#undef BOOST_FIBERS_SYM_FIBER_ARGS
#undef BOOST_FIBERS_SYM_FIBER_CTOR
sym_fiber( sym_fiber const& other);
sym_fiber & operator=( BOOST_COPY_ASSIGN_REF( sym_fiber) other);
sym_fiber( BOOST_RV_REF( sym_fiber) other);
sym_fiber & operator=( BOOST_RV_REF( sym_fiber) other);
typedef detail::sym_fiber_base::ptr::unspecified_bool_type unspecified_bool_type;
operator unspecified_bool_type() const;
bool operator!() const;
void swap( sym_fiber & other);
id get_id() const;
bool operator==( sym_fiber const& other) const;
bool operator!=( sym_fiber const& other) const;
void switch_to( sym_fiber & other);
bool finished() const;
};
class BOOST_FIBER_DECL sym_fiber::id
{
private:
friend class sym_fiber;
boost::uint64_t id_;
explicit id( detail::sym_fiber_base::ptr const& info) :
id_( reinterpret_cast< boost::uint64_t >( info.get() ) )
{}
public:
id() :
id_( 0)
{}
bool operator==( id const& other) const
{ return id_ == other.id_; }
bool operator!=( id const& other) const
{ return id_ != other.id_; }
bool operator<( id const& other) const
{ return id_ < other.id_; }
bool operator>( id const& other) const
{ return other.id_ < id_; }
bool operator<=( id const& other) const
{ return !( other.id_ < id_); }
bool operator>=( id const& other) const
{ return ! ( id_ < other.id_); }
template< typename charT, class traitsT >
friend std::basic_ostream< charT, traitsT > &
operator<<( std::basic_ostream< charT, traitsT > & os, id const& other)
{
if ( 0 != other.id_) return os << other.id_;
else return os << "{not-a-fiber}";
}
};
inline
void swap( sym_fiber & l, sym_fiber & r)
{ return l.swap( r); }
}
using fibers::sym_fiber;
}
# if defined(BOOST_MSVC)
# pragma warning(pop)
# endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_FIBERS_SYM_FIBER_H

View File

@@ -1,31 +0,0 @@
# Boost.fiber Library Build Jamfile
# 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)
import feature ;
import modules ;
import toolset ;
project boost/fiber
: source-location ../src
: requirements
<dependency>../../context/build//context.hpp
: usage-requirements
<link>shared:<define>BOOST_FIBER_DYN_LINK=1
;
lib boost_fiber
: asym_fiber.cpp
sym_fiber.cpp
detail/asym_fiber_base.cpp
detail/sym_fiber_base.cpp
../../context/build//boost_context
: <link>shared:<define>BOOST_FIBER_DYN_LINK=1
:
: <link>shared:<library>../../context/build//boost_context
;
boost-install boost_fiber ;

View File

@@ -1,33 +0,0 @@
# (C) Copyright 2008 Anthony Williams
#
# 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)
path-constant boost-images : ../../../doc/src/images ;
xml fiber : fiber.qbk ;
boostbook standalone
:
fiber
:
# HTML options first:
# Use graphics not text for navigation:
<xsl:param>navig.graphics=1
# How far down we chunk nested sections, basically all of them:
<xsl:param>chunk.section.depth=3
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=1
# How far down sections get TOC's
<xsl:param>toc.section.depth=10
# Max depth in each TOC:
<xsl:param>toc.max.depth=3
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=10
# Path for links to Boost:
<xsl:param>boost.root=../../../..
# Path for libraries index:
<xsl:param>boost.libraries=../../../../libs/libraries.htm
# Use the main Boost stylesheet:
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
;

View File

@@ -1,425 +0,0 @@
[/
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
]
[section:asym_fiber_management Asymmetric Fiber]
[heading Synopsis]
Each __asym_fiber__ class represents a user-space context of execution. Objects of
type __asym_fiber__ are characterized by providing three basic operations: __create__
(constructor), __resume__ (__fiber_run__) and __suspend__ (__fiber_yield__).
The constructor of __asym_fiber__ accepts a function which acts as the main body
of the fiber. Creating a fiber doesn't start its execution. The fiber begins
in suspended state with its __continuation_point__ set to the first instruction in
its main body.
Invoking __fiber_run__ starts the execution at its saved __continuation_point__
(activate the fiber) and runs until the fiber gets suspended or returns from fibers
main function. In both cases the control is transfered back to the invoker.
When a fiber returns from its main function the fiber is said to be finished and can
not be futher resumed.
If a fiber gets suspended its __continuation_point__ is saved so that the next time
the fiber is resumed, its execution will continue at the exact point where it was
suspended.
__asym_fiber__ supports copy- and move-semantics.
boost::asym_fiber f1; // not-a-fiber
void fn()
{
boost::asym_fiber f2( some_fn, boost::asym_fiber::default_stacksize);
std::cout << f2.get_id() << std::endl;
f2.run();
}
[note If fibers are migrated between threads the code called by a fiber must not
use thread-local-storage.]
[heading Creating]
A new fiber is launched by passing an object of a callable type that can be
invoked with no parameters to the constructor. The object is then copied into
internal storage, and invoked on the newly-created fiber. If the object must
not (or cannot) be copied, then `boost::ref` can be used to pass in a reference
to the function object. In this case, the user of __boost_fiber__ must ensure
that the referred-to object outlives the newly-created fiber.
struct callable
{ void operator()(); };
boost::asym_fiber copies_are_safe()
{
callable x;
return boost::asym_fiber( x);
} // x is destroyed, but the newly-created fiber has a copy, so this is OK
boost::asym_fiber oops()
{
callable x;
return boost::asym_fiber( boost::ref( x), boost::asym_fiber::default_stacksize);
} // x is destroyed, but the newly-created fiber still has a reference
// this leads to undefined behaviour
If you wish to construct an instance of __asym_fiber__ with a function or callable
object that requires arguments to be supplied, this can be done by passing
additional arguments to the __asym_fiber__ constructor:
void find_the_question( int the_answer);
boost::asym_fiber deep_thought_2(
find_the_question, 42, boost::asym_fiber::default_stacksize);
The arguments are ['copied] into the internal fiber structure: if a reference
is required, use `boost::ref`, just as for references to callable functions.
[caution Functions passed to the __asym_fiber__ must not throw exceptions.]
If the main function of __asym_fiber__ returns the fiber returns to the
__continuation_point__ which has invoked the fiber. If desired the application
will terminate if the last constructor argument is set to `false` and fibers
main function returns.
[heading Control Transfer]
__asym_fiber__ has two operations to transfer the execution between different
fibers. The __continuation_point__ of the fiber ist started/resumed if
__fiber_run__ is invoked.
If the fiber decides to give the execution control back to its caller
__fiber_yield__ must be called.
// create `my_fiber` which will execute `my_function()`
boost::asym_fiber my_fiber( my_function, boost::asym_fiber:default_stacksize);
// jump to execution context of `my_fiber`
// run `my_function`
my_fiber.run();
// this section will be entered if `my_function()` calls
// `my_fiber.yield()`
[heading Fiber IDs]
Objects of class __asym_fiber_id__ can be used to identify fibers. Each running fiber
has a unique ID obtainable from the corresponding __asym_fiber__ by calling
__asym_get_id__ member function. Objects of class __asym_fiber_id__ can be copied, and
used as keys in associative containers: the full range of comparison operators
is provided. Fiber IDs can also be written to an output stream using the stream
insertion operator, though the output format is unspecified.
Each instance of __asym_fiber_id__ either refers to some fiber, or __not_a_fiber__.
Instances that refer to __not_a_fiber__ compare equal to each other, but not
equal to any instances that refer to an actual fiber.
The comparison operators on __asym_fiber_id__ yield a total order for every non-equal
fiber ID.
[heading Example]
The example below demonstrates that the function `fn` is executed in the context
of the fiber `f` and the local state of `fn` is preserved (value of `i` in the
for loop).
boost::asym_fiber f;
void fn( int n)
{
for ( int i = 0; i < n; ++i)
{
std::cout << i << " iteration" << std::endl;
// jump back to main
// value of i will be preserved
f.yield();
// if we return from f.yield()
// f.run() was called again
}
}
int main()
{
f = boost::asym_fiber( fn, 5);
std::cout << "start" << std::endl;
while ( ! f.finished() )
f.run(); // jump to context of fn()
std::cout << "finish" << std::endl;
return EXIT_SUCCESS;
}
[section:asym_fiber Class `asym_fiber`]
#include <boost/fiber/asym_fiber.hpp>
class asym_fiber
{
public:
static std::size_t max_stacksize;
static std::size_t min_stacksize;
static std::size_t default_stacksize; // 256 kB
asym_fiber();
template< typename Fn >
explicit asym_fiber( Fn fn, std::size_t stacksize, bool do_return = true);
template< typename Fn, typename A1, typename A2,... >
asym_fiber( Fn fn, A1 a1, A2 a2,..., std::size_t stacksize, bool do_return = true);
asym_fiber( asym_fiber const& other);
asym_fiber & operator=( asym_fiber const& other);
// move support
template< typename Fn >
explicit asym_fiber( Fn && fn, std::size_t stacksize, bool do_return = true);
asym_fiber( asym_fiber && other);
asym_fiber & operator=( asym_fiber && other);
operator unspecified-bool-type() const;
bool operator!() const;
void swap( asym_fiber & other);
id get_id() const;
bool operator==( asym_fiber const&) const;
bool operator!=( asym_fiber const&) const;
void run();
void yield();
bool finished() const;
};
void swap( asym_fiber & lhs, asym_fiber & rhs);
[section:default_constructor `asym_fiber()`]
[variablelist
[[Effects:] [Constructs a __asym_fiber__ instance that refers to __not_a_fiber__.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:callable_constructor_stack `template< typename Fn > asym_fiber( Fn fn, std::size_t stacksize, bool do_return)`]
[variablelist
[[Effects:] [`fn` is copied into storage managed internally by the fiber, that
copy is invoked on a newly-created fiber. If last argument is
`true` the execution context returns to caller after `fn` finished.]]
[[Postconditions:] [`*this` refers to the newly created fiber.]]
[[Throws:] [__bad_alloc__.]]
]
[endsect]
[section:multiple_argument_constructor `template< typename Fn, typename A1, typename A2,... > fiber( Fn fn, A1 a1, A2 a2,..., std::size_t stacksize, bool do_return)`]
[variablelist
[[Preconditions:] [`Fn` and each `A`n must by copyable or movable.]]
[[Effects:] [As if `asym_fiber( boost::bind( fn, a1, a2,...) )`. Consequently,
`fn` and each `a`n are copied into internal storage for access by the new fiber.
If last argument is `true` the execution context returns to caller after `fn`
finished.]]
[[Postconditions:] [`*this` refers to the newly created fiber.]]
[[Throws:] [__bad_alloc__]]
[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be
specified in addition to the function `fn`.]]
]
[endsect]
[section:get_id `asym_fiber::id get_id() const`]
[variablelist
[[Returns:] [If `*this` refers to a fiber, an instance of __asym_fiber_id__ that
represents that fiber. Otherwise returns a default-constructed __asym_fiber_id__.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:run `void run()`]
[variablelist
[[Effects:] [Save current execution context (caller) and jump to execution
context of `*this`.]]
[[Throws:] [__fiber_moved__ if `*this` is __not_a_fiber__.]]
]
[endsect]
[section:yield `void yield()`]
[variablelist
[[Effects:] [Save execution context of `*this` and jump back to callers
execution context.]]
[[Throws:] [__fiber_moved__ if `*this` is __not_a_fiber__.]]
]
[endsect]
[section:finished `bool finished() const`]
[variablelist
[[Effects:] [Returns `true` if fiber has finished.]]
[[Throws:] [__fiber_moved__ if `*this` is __not_a_fiber__.]]
]
[endsect]
[section:unspec_operator `operator unspecified-bool-type() const`]
[variablelist
[[Returns:] [If `*this` refers to a fiber, the function returns true. Otherwise
false.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:not_operator `bool operator!() const`]
[variablelist
[[Returns:] [If `*this` refers not to a fiber, the function returns true.
Otherwise false.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:equals `bool operator==( asym_fiber const& other) const`]
[variablelist
[[Returns:] [`get_id()==other.get_id()`]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:not_equals `bool operator!=( asym_fiber const& other) const`]
[variablelist
[[Returns:] [`get_id()!=other.get_id()`]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:swap `void swap( asym_fiber & other)`]
[variablelist
[[Effects:] [Exchanges the fibers associated with `*this` and `other`, so
`*this` is associated with the fiber associated with `other` prior to the call,
and vice-versa.]]
[[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()`
prior to the call. `other.get_id()` returns the same value as `this->get_id()`
prior to the call.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:non_member_swap Non-member function `swap()`]
#include <boost/fiber/asym_fiber.hpp>
void swap( asym_fiber & lhs, asym_fiber & rhs);
[variablelist
[[Effects:] [[link fiber.asym_fiber_management.asym_fiber.swap
`lhs.swap( rhs)`].]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:id Class `boost::asym_fiber::id`]
#include <boost/fiber/fiber.hpp>
class asym_fiber::id
{
public:
id();
bool operator==( id const& y) const;
bool operator!=( id const& y) const;
bool operator<( id const& y) const;
bool operator>( id const& y) const;
bool operator<=( id const& y) const;
bool operator>=( id const& y) const;
template< typename charT, typename traitsT >
friend std::basic_ostream< charT, traitsT > &
operator<<( std::basic_ostream<charT, traitsT > & os, id const& x);
};
[section:constructor `id()`]
[variablelist
[[Effects:] [Constructs a __asym_fiber_id__ instance that represents
__not_a_fiber__.]]
[[Throws:] [Nothing]]
]
[endsect]
[section:is_equal `bool operator==( id const& y) const`]
[variablelist
[[Returns:] [`true` if `*this` and `y` both represent the same fiber of
execution, or both represent __not_a_fiber__, `false` otherwise.]]
[[Throws:] [Nothing]]
]
[endsect]
[section:not_equal `bool operator!=( id const& y) const`]
[variablelist
[[Returns:] [`true` if `*this` and `y` represent different fibers of execution,
or one represents a fiber of execution, and the other represent __not_a_fiber__,
`false` otherwise.]]
[[Throws:] [Nothing]]
]
[endsect]
[section:less_than `bool operator<( id const& y) const`]
[variablelist
[[Returns:] [`true` if `*this!=y` is `true` and the implementation-defined total
order of __asym_fiber_id__ values places `*this` before `y`, `false` otherwise.]]
[[Throws:] [Nothing]]
[[Note:] [A __asym_fiber_id__ instance representing __not_a_fiber__ will always
compare less than an instance representing a fiber of
execution.]]
]
[endsect]
[section:greater_than `bool operator>( id const& y) const`]
[variablelist
[[Returns:] [`y<*this`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:less_than_or_equal `bool operator<=( id const& y) const`]
[variablelist
[[Returns:] [`!(y<*this)`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:greater_than_or_equal `bool operator>=( id const& y) const`]
[variablelist
[[Returns:] [`!(*this<y)`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:stream_out Non-member template function `operator<<`]
template< typename charT, typename traitsT >
friend std::basic_ostream< charT, traitsT > &
operator<<( std::basic_ostream<charT, traitsT > & os, id const& x);
[variablelist
[[Effects:] [Writes a representation of the __asym_fiber_id__ instance `x` to
the stream `os`, such that the representation of two instances of
__asym_fiber_id__ `a` and `b` is the same if `a==b`, and different if `a!=b`.]]
[[Returns:] [`os`]]
]
[endsect]
[endsect]
[endsect]
[endsect]

View File

@@ -1,53 +0,0 @@
[/
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
]
[article Fiber
[quickbook 1.4]
[authors [Kowalke, Oliver]]
[copyright 2009 Oliver Kowalke]
[purpose C++ Library providing an symmetric and asymmetric continuation framework]
[category text]
[license
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])
]
]
[def __boost_context__ [*Boost.Context]]
[def __boost_fiber__ [*Boost.Fiber]]
[def __boost_move__ [*Boost.Move]]
[def __blocked__ ['blocked]]
[def __continuation_point__ ['continuation point]]
[def __fiber_id__ ['fiber-id]]
[def __not_a_fiber__ ['not-a-fiber]]
[def __create__ ['create]]
[def __resume__ ['resume]]
[def __suspend__ ['suspend]]
[def __yield__ ['yield]]
[def __asym_get_id__ `boost::asym_fiber::get_id()`]
[def __fiber_run__ `boost::asym_fiber::run()`]
[def __fiber_switch_to__ `boost::sym_fiber::switch_to()`]
[def __fiber_yield__ `boost::asym_fiber::yield()`]
[def __sym_get_id__ `boost::sym_fiber::get_id()`]
[def __asym_fiber__ `boost::asym_fiber`]
[def __asym_fiber_id__ `boost::asym_fiber::id`]
[def __bad_alloc__ `std::bad_alloc`]
[def __fcontext__ `fcontext_t`]
[def __fiber_moved__ `boost::fibers::fiber_moved`]
[def __sym_fiber__ `boost::sym_fiber`]
[def __sym_fiber_id__ `boost::sym_fiber::id`]
[def __ucontext__ `ucontext_t`]
[include overview.qbk]
[include asym_fiber_ref.qbk]
[include sym_fiber_ref.qbk]

View File

@@ -1,36 +0,0 @@
index.html
fiber/overview.html
fiber/asym_fiber_management.html
fiber/asym_fiber_management/asym_fiber.html
fiber/asym_fiber_management/asym_fiber/default_constructor.html
fiber/asym_fiber_management/asym_fiber/callable_constructor_stack.html
fiber/asym_fiber_management/asym_fiber/multiple_argument_constructor.html
fiber/asym_fiber_management/asym_fiber/get_id.html
fiber/asym_fiber_management/asym_fiber/run.html
fiber/asym_fiber_management/asym_fiber/yield.html
fiber/asym_fiber_management/asym_fiber/finished.html
fiber/asym_fiber_management/asym_fiber/unspec_operator.html
fiber/asym_fiber_management/asym_fiber/not_operator.html
fiber/asym_fiber_management/asym_fiber/equals.html
fiber/asym_fiber_management/asym_fiber/not_equals.html
fiber/asym_fiber_management/asym_fiber/swap.html
fiber/asym_fiber_management/asym_fiber/non_member_swap.html
fiber/asym_fiber_management/asym_fiber/id.html
fiber/sym_fiber_management.html
fiber/sym_fiber_management/sym_fiber.html
fiber/sym_fiber_management/sym_fiber/create.html
fiber/sym_fiber_management/sym_fiber/default_constructor.html
fiber/sym_fiber_management/sym_fiber/callable_constructor_stack1.html
fiber/sym_fiber_management/sym_fiber/callable_constructor_stack2.html
fiber/sym_fiber_management/sym_fiber/multiple_argument_constructor1.html
fiber/sym_fiber_management/sym_fiber/multiple_argument_constructor2.html
fiber/sym_fiber_management/sym_fiber/get_id.html
fiber/sym_fiber_management/sym_fiber/switch_to.html
fiber/sym_fiber_management/sym_fiber/finished.html
fiber/sym_fiber_management/sym_fiber/unspec_operator.html
fiber/sym_fiber_management/sym_fiber/not_operator.html
fiber/sym_fiber_management/sym_fiber/equals.html
fiber/sym_fiber_management/sym_fiber/not_equals.html
fiber/sym_fiber_management/sym_fiber/swap.html
fiber/sym_fiber_management/sym_fiber/non_member_swap.html
fiber/sym_fiber_management/sym_fiber/id.html

View File

@@ -1,67 +0,0 @@
[/
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
]
[section:overview Overview]
__boost_fiber__ provides an framework utilizing lightweight threads of execution
- also known as user-space threads, microthreads or fibers. The API contains
classes and functions to manage fibers.
A fiber is able to store the current execution state, including all registers
and CPU flags, the instruction pointer, and the stack pointer and later restore
this state (on behalf of __boost_context__). The idea is to have multiple
execution paths running on a single thread using a sort of cooperative
scheduling (threads are preemptively scheduled) - the running fiber decides
explicitly when its yields to allow another fiber to run (fiber switching).
Fibers are less expensive than threads because the kernel doesn't know anything
about fibers - no kernel transitions are required for scheduling (done in the
user-space).
A context switch between threads costs usally thousends of CPU cycles on x86
compared to a fiber switch with few hundreds of cycles.
A fiber can only run on a single thread at any point in time but may be migrated
between threads. Because a thread can run many different fibers during its life
cycle the name ['fiber] was choosen.
Beside fibers a conceptualy equivalent constructs are coroutines. A coroutine
can be seen as a language-level construct while a fiber is a system-level
construct.
It is characteristic for a fiber that local data of a fiber persist between
successive calls of the (symmetric or asymetric) control transfer operations.
The __boost_fiber__ framework provides stackfull fiber implementations allowing
to suspend and resume the execution from within nested functions.
[caution The documentation from __boost_context__ is relevant too.]
In order to use the classes and functions described here, you can either include
the specific headers specified by the descriptions of each class or function, or
include the master library header:
#include <boost/fiber/all.hpp>
which includes all the other headers in turn.
Used namespaces is:
namespace boost::fibers
[warning This library is ['not] an official Boost library]
__boost_fiber__ depends uppon __boost_context__ and
__boost_move__.
[heading How to build and install]
* download the sources from
[@http://www.boost-consulting.com/vault/index.php?directory=Concurrent%20Programming Boost Vault]
* extract the archive into the boost-source directory
* call ['bjam] (take the different build options of __boost_context__ into acount)
[endsect]

View File

@@ -1,475 +0,0 @@
[/
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
]
[section:sym_fiber_management Symmetric Fiber]
[heading Synopsis]
Each __sym_fiber__ class represents a user-space context of execution. Objects of
type __sym_fiber__ are characterized by providing two basic operations: __create__
(constructor) and __suspend__ (__fiber_switch_to__).
The constructor of __sym_fiber__ accepts a function which acts as the main body
of the fiber. Creating a fiber doesn't start its execution. The fiber begins
in suspended state with its __continuation_point__ set to the first instruction in
its main body.
It is characeristic for symmetric fibers to provide a single control-transfer operation
(__fiber_switch_to__) allowing to pass the control explicitly among themself.
The __continuation_point__ of the fiber which initiates the control transfer will be
saved so that the next time the cotnrol is transfered back its execution will continue
at the exact point where it was suspended.
When a fiber returns from its main function the fiber is said to be finished and can
not be futher resumed. If a fibers main function returns and the fiber was not linked
against another one, the application terminates.
__sym_fiber__ supports copy- and move-semantics.
boost::sym_fiber f1; // not-a-fiber
void fn()
{
boost::sym_fiber f2( some_fn, boost::sym_fiber::default_stacksize);
std::cout << f2.get_id() << std::endl;
f2.run();
}
[note If fibers are migrated between threads the code called by a fiber must not
use thread-local-storage.]
[heading Creating]
A new fiber is created by passing an object of a callable type that can be
invoked with no parameters to the constructor. The object is then copied into
internal storage, and invoked on the newly-created fiber. If the object must not
(or cannot) be copied, then `boost::ref` can be used to pass in a reference to
the function object. In this case, the user of __boost_fiber__ must ensure that
the referred-to object outlives the newly-created fiber.
struct callable
{ void operator()(); };
boost::sym_fiber copies_are_safe()
{
callable x;
return boost::sym_fiber( x);
} // x is destroyed, but the newly-created fiber has a copy, so this is OK
boost::sym_fiber oops()
{
callable x;
return boost::sym_fiber( boost::ref( x), boost::sym_fiber::default_stacksize);
} // x is destroyed, but the newly-created fiber still has a reference
// this leads to undefined behaviour
If you wish to construct an instance of __sym_fiber__ with a function or callable
object that requires arguments to be supplied, this can be done by passing
additional arguments to the __sym_fiber__ constructor:
void find_the_question( int the_answer);
boost::sym_fiber deep_thought_2(
find_the_question, 42, boost::sym_fiber::default_stacksize);
The arguments are ['copied] into the internal fiber structure: if a reference
is required, use `boost::ref`, just as for references to callable functions.
[caution Functions passed to the __sym_fiber__ must not throw exceptions.]
[heading Control Transfer]
__sym_fiber__ provides only one operation to transfer the execution control
between different fibers. This allows the symmetric fibers to transfer the
execution control among themselfs (chain of fiber invocations). The
__continuation_point__ of the `other` fiber is started/resumed if
__fiber_switch_to__ is called with `other` as its argument.
// create `current_fiber` which represent the current execution context
boost::sym_fiber current_fiber( boost::sym_fiber::from_current-context() );
// create `my_fiber` which will execute `my_function()`
boost::sym_fiber my_fiber( my_function, boost::sym_fiber:default_stacksize);
// jump to execution context of `my_fiber`
// run `my_function`
current_fiber.switch_to( my_fiber);
// this section will be entered if `my_function()` calls
// `my_fiber.switch_to( current_fiber)`
[heading Linking against other Fiber]
If the main function of a symmetric fiber returns the application terminates.
If desired it is possible to link to another fiber which will be executed after
a fiber is finished. For this purpose the constructor takes a __sym_fiber__ as
last argument.
// create `current_fiber` which represent the current execution context
boost::sym_fiber current_fiber( boost::sym_fiber::from_current-context() );
// create `my_fiber` which will execute `my_function()` and link
// against `current_fiber` which will be resumed after `my_function()` returns
boost::sym_fiber my_fiber( my_function, boost::sym_fiber:default_stacksize, current_fiber);
// jump to execution context of `my_fiber`
// run `my_function`
current_fiber.switch_to( my_fiber);
// this section will be entered if `my_function()` returns
...
[heading Fiber IDs]
Objects of class __sym_fiber_id__ can be used to identify fibers. Each running fiber
has a unique ID obtainable from the corresponding __sym_fiber__ by calling
__sym_get_id__ member function. Objects of class __sym_fiber_id__ can be copied, and
used as keys in associative containers: the full range of comparison operators
is provided. Fiber IDs can also be written to an output stream using the stream
insertion operator, though the output format is unspecified.
Each instance of __sym_fiber_id__ either refers to some fiber, or __not_a_fiber__.
Instances that refer to __not_a_fiber__ compare equal to each other, but not
equal to any instances that refer to an actual fiber.
The comparison operators on __sym_fiber_id__ yield a total order for every non-equal
fiber ID.
[heading Example]
The example below demonstrates that the function `fn` is executed in the context
of the fiber `f` and the local state of `fn` is preserved (value of `i` in the
for loop).
boost::sym_fiber f, current;
void fn( int n)
{
for ( int i = 0; i < n; ++i)
{
std::cout << i << " iteration" << std::endl;
// jump back to main
// value of i will be preserved
f.switch_to( current);
// if we return from f.switch_to( current)
// current.switch_to( f) was called again
}
}
int main()
{
current = boost::sym_fiber::from_current_context();
f = boost::sym_fiber( fn, 5, current);
std::cout << "start" << std::endl;
while ( ! f.finished() )
current.switch_to( f); // jump to context of fn()
std::cout << "finish" << std::endl;
return EXIT_SUCCESS;
}
[section:sym_fiber Class `sym_fiber`]
#include <boost/fiber/sym_fiber.hpp>
class sym_fiber
{
public:
static std::size_t max_stacksize;
static std::size_t min_stacksize;
static std::size_t default_stacksize; // 256 kB
static sym_fiber from_current_cotnext();
sym_fiber();
template< typename Fn >
explicit sym_fiber( Fn fn, std::size_t stacksize);
template< typename Fn >
explicit sym_fiber( Fn fn, std::size_t stacksize, sym_fiber & nxt);
template< typename Fn, typename A1, typename A2,... >
sym_fiber( Fn fn, A1 a1, A2 a2,..., std::size_t stacksize);
template< typename Fn, typename A1, typename A2,... >
sym_fiber( Fn fn, A1 a1, A2 a2,..., std::size_t stacksize, sym_fiber & nxt);
sym_fiber( sym_fiber const& other);
sym_fiber & operator=( sym_fiber const& other);
// move support
template< typename Fn >
explicit sym_fiber( Fn && fn, std::size_t stacksize);
template< typename Fn >
explicit sym_fiber( Fn && fn, std::size_t stacksize, sym_fiber & nxt);
sym_fiber( sym_fiber && other);
sym_fiber & operator=( sym_fiber && other);
operator unspecified-bool-type() const;
bool operator!() const;
void swap( sym_fiber & other);
id get_id() const;
bool operator==( sym_fiber const&) const;
bool operator!=( sym_fiber const&) const;
void switch_to( sym_fiber & other);
bool finished() const;
};
void swap( sym_fiber & lhs, sym_fiber & rhs);
[section:create `static sym_fiber from_current_context()`]
[variablelist
[[Effects:] [Creates a fiber attached to current execution context.
The fiber doesn't manage the stack.]]
[[Postconditions:] [`*this` refers to the newly created fiber.]]
[[Throws:] [__bad_alloc__.]]
]
[endsect]
[section:default_constructor `sym_fiber()`]
[variablelist
[[Effects:] [Constructs a __sym_fiber__ instance that refers to __not_a_fiber__.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:callable_constructor_stack1 `template< typename Fn > sym_fiber( Fn fn, std::size_t stacksize)`]
[variablelist
[[Effects:] [`fn` is copied into storage managed internally by the fiber, that
copy is invoked on a newly-created fiber.]]
[[Postconditions:] [`*this` refers to the newly created fiber.]]
[[Throws:] [__bad_alloc__.]]
]
[endsect]
[section:callable_constructor_stack2 `template< typename Fn > sym_fiber( Fn fn, std::size_t stacksize, sym_fiber & other)`]
[variablelist
[[Effects:] [`fn` is copied into storage managed internally by the fiber, that
copy is invoked on a newly-created fiber. If `fn` returns `nxt` will be invoked.]]
[[Postconditions:] [`*this` refers to the newly created fiber.]]
[[Throws:] [__bad_alloc__.]]
]
[endsect]
[section:multiple_argument_constructor1 `template< typename Fn, typename A1, typename A2,... > fiber( Fn fn, A1 a1, A2 a2,..., std::size_t stacksize)`]
[variablelist
[[Preconditions:] [`Fn` and each `A`n must by copyable or movable.]]
[[Effects:] [As if `sym_fiber( boost::bind( fn, a1, a2,...) )`. Consequently,
`fn` and each `a`n are copied into internal storage for access by the new fiber.]]
[[Postconditions:] [`*this` refers to the newly created fiber.]]
[[Throws:] [__bad_alloc__]]
[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be
specified in addition to the function `fn`.]]
]
[endsect]
[section:multiple_argument_constructor2 `template< typename Fn, typename A1, typename A2,... > fiber( Fn fn, A1 a1, A2 a2,..., std::size_t stacksize, sym_fiber & nxt)`]
[variablelist
[[Preconditions:] [`Fn` and each `A`n must by copyable or movable.]]
[[Effects:] [As if `sym_fiber( boost::bind( fn, a1, a2,...) )`. Consequently,
`fn` and each `a`n are copied into internal storage for access by the new fiber.
If `fn` returns `nxt` will be invoked automatically.]]
[[Postconditions:] [`*this` refers to the newly created fiber.]]
[[Throws:] [__bad_alloc__]]
[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be
specified in addition to the function `fn`.]]
]
[endsect]
[section:get_id `sym_fiber::id get_id() const`]
[variablelist
[[Returns:] [If `*this` refers to a fiber, an instance of __sym_fiber_id__ that
represents that fiber. Otherwise returns a default-constructed __sym_fiber_id__.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:switch_to `void switch_to( sym_fiber& other)`]
[variablelist
[[Preconditions:] [`other` and `*this` are not a __not_a_fiber__.]]
[[Effects:] [Save current execution context and transfer execution control to
`other`.]]
[[Throws:] [__fiber_moved__ if `*this` or `other` are __not_a_fiber__.]]
]
[endsect]
[section:finished `bool finished() const`]
[variablelist
[[Effects:] [Returns `true` if fiber has finished.]]
[[Throws:] [__fiber_moved__ if `*this` is __not_a_fiber__.]]
]
[endsect]
[section:unspec_operator `operator unspecified-bool-type() const`]
[variablelist
[[Returns:] [If `*this` refers to a fiber, the function returns true. Otherwise
false.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:not_operator `bool operator!() const`]
[variablelist
[[Returns:] [If `*this` refers not to a fiber, the function returns true.
Otherwise false.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:equals `bool operator==( sym_fiber const& other) const`]
[variablelist
[[Returns:] [`get_id()==other.get_id()`]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:not_equals `bool operator!=( sym_fiber const& other) const`]
[variablelist
[[Returns:] [`get_id()!=other.get_id()`]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:swap `void swap( sym_fiber & other)`]
[variablelist
[[Effects:] [Exchanges the fibers associated with `*this` and `other`, so
`*this` is associated with the fiber associated with `other` prior to the call,
and vice-versa.]]
[[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()`
prior to the call. `other.get_id()` returns the same value as `this->get_id()`
prior to the call.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:non_member_swap Non-member function `swap()`]
#include <boost/fiber/sym_fiber.hpp>
void swap( sym_fiber & lhs, sym_fiber & rhs);
[variablelist
[[Effects:] [[link fiber.sym_fiber_management.sym_fiber.swap
`lhs.swap( rhs)`].]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:id Class `boost::sym_fiber::id`]
#include <boost/fiber/fiber.hpp>
class sym_fiber::id
{
public:
id();
bool operator==( id const& y) const;
bool operator!=( id const& y) const;
bool operator<( id const& y) const;
bool operator>( id const& y) const;
bool operator<=( id const& y) const;
bool operator>=( id const& y) const;
template< typename charT, typename traitsT >
friend std::basic_ostream< charT, traitsT > &
operator<<( std::basic_ostream<charT, traitsT > & os, id const& x);
};
[section:constructor `id()`]
[variablelist
[[Effects:] [Constructs a __sym_fiber_id__ instance that represents
__not_a_fiber__.]]
[[Throws:] [Nothing]]
]
[endsect]
[section:is_equal `bool operator==( id const& y) const`]
[variablelist
[[Returns:] [`true` if `*this` and `y` both represent the same fiber of
execution, or both represent __not_a_fiber__, `false` otherwise.]]
[[Throws:] [Nothing]]
]
[endsect]
[section:not_equal `bool operator!=( id const& y) const`]
[variablelist
[[Returns:] [`true` if `*this` and `y` represent different fibers of execution,
or one represents a fiber of execution, and the other represent __not_a_fiber__,
`false` otherwise.]]
[[Throws:] [Nothing]]
]
[endsect]
[section:less_than `bool operator<( id const& y) const`]
[variablelist
[[Returns:] [`true` if `*this!=y` is `true` and the implementation-defined total
order of __sym_fiber_id__ values places `*this` before `y`, `false` otherwise.]]
[[Throws:] [Nothing]]
[[Note:] [A __sym_fiber_id__ instance representing __not_a_fiber__ will alws
compare less than an instance representing a fiber of
execution.]]
]
[endsect]
[section:greater_than `bool operator>( id const& y) const`]
[variablelist
[[Returns:] [`y<*this`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:less_than_or_equal `bool operator<=( id const& y) const`]
[variablelist
[[Returns:] [`!(y<*this)`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:greater_than_or_equal `bool operator>=( id const& y) const`]
[variablelist
[[Returns:] [`!(*this<y)`]]
[[Throws:] [Nothing]]
]
[endsect]
[section:stream_out Non-member template function `operator<<`]
template< typename charT, typename traitsT >
friend std::basic_ostream< charT, traitsT > &
operator<<( std::basic_ostream<charT, traitsT > & os, id const& x);
[variablelist
[[Effects:] [Writes a representation of the __sym_fiber_id__ instance `x` to
the stream `os`, such that the representation of two instances of
__sym_fiber_id__ `a` and `b` is the same if `a==b`, and different if `a!=b`.]]
[[Returns:] [`os`]]
]
[endsect]
[endsect]
[endsect]
[endsect]

View File

@@ -1,24 +0,0 @@
# Boost.Fiber Library Examples Jamfile
# 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)
# For more information, see http://www.boost.org/
project boost/fiber/example
: requirements
<dependency>../../context/build//context.hpp
<library>../build//boost_fiber
<library>/boost/context//boost_context
<library>/boost/thread//boost_thread
<link>static
<threading>multi
;
exe asym_fiber : asym_fiber.cpp ;
exe asym_fiber_mt : asym_fiber_mt.cpp ;
exe sym_fiber : sym_fiber.cpp ;
exe sym_fiber_mt : sym_fiber_mt.cpp ;
exe stack : stack.cpp ;

View File

@@ -1,47 +0,0 @@
#include <cstdlib>
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/fiber/all.hpp>
int value = 0;
boost::asym_fiber gf;
inline
void fn( std::string const& str, int n)
{
for ( int i = 0; i < n; ++i)
{
std::cout << "asymmetric fiber " << gf.get_id() << ": increment value from " << value << " to ";
++value;
std::cout << value << std::endl;
gf.yield();
}
}
int main()
{
try
{
int n = 5;
gf = boost::asym_fiber( fn, "abc", n, boost::asym_fiber::default_stacksize);
std::cout << "start" << std::endl;
while ( ! gf.finished() )
{
gf.run();
std::cout << value << " iteration" << std::endl;
}
std::cout << "finish" << std::endl;
return EXIT_SUCCESS;
}
catch ( std::exception const& e)
{ std::cerr << "exception: " << e.what() << std::endl; }
catch (...)
{ std::cerr << "unhandled exception" << std::endl; }
return EXIT_FAILURE;
}

View File

@@ -1,76 +0,0 @@
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/fiber/all.hpp>
int value = 0;
boost::asym_fiber gf;
void increment_value_fn()
{
while ( true)
{
std::stringstream ss;
ss << boost::this_thread::get_id();
std::cout << "thread " << ss.str() << ": increment value from " << value << " to ";
++value;
std::cout << value << std::endl;
gf.yield();
}
}
void increment( int k, int n)
{
for ( int i = k; i < n; ++i)
gf.run();
}
void fn_first( int k, int n, boost::barrier & b)
{
std::stringstream ss;
ss << boost::this_thread::get_id();
std::cout << "thread " << ss.str() << " executes fiber " << gf.get_id() << std::endl;
increment( k, n);
b.wait();
}
void fn_last( int k, int n, boost::barrier & b)
{
b.wait();
std::stringstream ss;
ss << boost::this_thread::get_id();
std::cout << "thread " << ss.str() << " executes fiber " << gf.get_id() << std::endl;
increment( k, n);
}
int main()
{
try
{
std::cout << "start" << std::endl;
value = 0;
gf = boost::asym_fiber( increment_value_fn, boost::asym_fiber::default_stacksize);
boost::barrier b( 2);
boost::thread t1( fn_first, 0, 5, boost::ref( b) );
boost::thread t2( fn_last, 5, 8, boost::ref( b) );
t1.join();
t2.join();
std::cout << "finish" << std::endl;
return EXIT_SUCCESS;
}
catch ( std::exception const& e)
{ std::cerr << "exception: " << e.what() << std::endl; }
catch (...)
{ std::cerr << "unhandled exception" << std::endl; }
return EXIT_FAILURE;
}

View File

@@ -1,21 +0,0 @@
#include <cstdlib>
#include <iostream>
#include <boost/fiber/all.hpp>
int main()
{
try
{
std::cout << "max stack-size: " << boost::asym_fiber::max_stacksize / 1024 << " kB\n";
std::cout << "min stack-size: " << boost::asym_fiber::min_stacksize / 1024 << " kB\n";
std::cout << "default stack-size: " << boost::asym_fiber::default_stacksize / 1024 << " kB\n";
return EXIT_SUCCESS;
}
catch ( std::exception const& e)
{ std::cerr << "exception: " << e.what() << std::endl; }
catch (...)
{ std::cerr << "unhandled exception" << std::endl; }
return EXIT_FAILURE;
}

View File

@@ -1,49 +0,0 @@
#include <cstdlib>
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/fiber/all.hpp>
int value = 0;
boost::sym_fiber gf1;
boost::sym_fiber gf2;
inline
void fn( std::string const& str, int n)
{
for ( int i = 0; i < n; ++i)
{
std::cout << "symmetric fiber " << gf2.get_id() << ": increment value from " << value << " to ";
++value;
std::cout << value << std::endl;
gf2.switch_to( gf1);
}
}
int main()
{
try
{
int n = 5;
gf1 = boost::sym_fiber::from_current_context();
gf2 = boost::sym_fiber( fn, "abc", n, boost::sym_fiber::default_stacksize, gf1);
std::cout << "start" << std::endl;
while ( ! gf2.finished() )
{
gf1.switch_to( gf2);
std::cout << value << " iteration" << std::endl;
}
std::cout << "finish" << std::endl;
return EXIT_SUCCESS;
}
catch ( std::exception const& e)
{ std::cerr << "exception: " << e.what() << std::endl; }
catch (...)
{ std::cerr << "unhandled exception" << std::endl; }
return EXIT_FAILURE;
}

View File

@@ -1,78 +0,0 @@
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/fiber/all.hpp>
int value = 0;
boost::sym_fiber gf1;
boost::sym_fiber gf2;
void increment_value_fn()
{
while ( true)
{
std::stringstream ss;
ss << boost::this_thread::get_id();
std::cout << "thread " << ss.str() << ": increment value from " << value << " to ";
++value;
std::cout << value << std::endl;
gf2.switch_to( gf1);
}
}
void increment( int k, int n)
{
gf1 = boost::sym_fiber::from_current_context();
for ( int i = k; i < n; ++i)
gf1.switch_to( gf2);
}
void fn_first( int k, int n, boost::barrier & b)
{
std::stringstream ss;
ss << boost::this_thread::get_id();
std::cout << "thread " << ss.str() << " executes fiber " << gf2.get_id() << std::endl;
increment( k, n);
b.wait();
}
void fn_last( int k, int n, boost::barrier & b)
{
b.wait();
std::stringstream ss;
ss << boost::this_thread::get_id();
std::cout << "thread " << ss.str() << " executes fiber " << gf2.get_id() << std::endl;
increment( k, n);
}
int main()
{
try
{
std::cout << "start" << std::endl;
value = 0;
gf2 = boost::sym_fiber( increment_value_fn, boost::sym_fiber::default_stacksize);
boost::barrier b( 2);
boost::thread t1( fn_first, 0, 5, boost::ref( b) );
boost::thread t2( fn_last, 5, 8, boost::ref( b) );
t1.join();
t2.join();
std::cout << "finish" << std::endl;
return EXIT_SUCCESS;
}
catch ( std::exception const& e)
{ std::cerr << "exception: " << e.what() << std::endl; }
catch (...)
{ std::cerr << "unhandled exception" << std::endl; }
return EXIT_FAILURE;
}

View File

@@ -1,107 +0,0 @@
// 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)
#define BOOST_FIBER_SOURCE
#include <boost/fiber/asym_fiber.hpp>
#include <csignal>
#include <boost/config.hpp>
#include <boost/context/detail/stack_helper.hpp>
#include <boost/fiber/exceptions.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
std::size_t asym_fiber::max_stacksize = boost::contexts::detail::stack_helper::maximal_stacksize();
std::size_t asym_fiber::min_stacksize = boost::contexts::detail::stack_helper::minimal_stacksize();
std::size_t asym_fiber::default_stacksize = 256 * 1024;
asym_fiber::asym_fiber() :
impl_()
{}
asym_fiber::asym_fiber( asym_fiber const& other) :
impl_( other.impl_)
{}
asym_fiber &
asym_fiber::operator=( BOOST_COPY_ASSIGN_REF( asym_fiber) other)
{
asym_fiber tmp( other);
swap( tmp);
return * this;
}
asym_fiber::asym_fiber( BOOST_RV_REF( asym_fiber) other) :
impl_()
{ swap( other); }
asym_fiber &
asym_fiber::operator=( BOOST_RV_REF( asym_fiber) other)
{
asym_fiber tmp( boost::move( other) );
swap( tmp);
return * this;
}
asym_fiber::operator unspecified_bool_type() const
{ return impl_; }
bool
asym_fiber::operator!() const
{ return ! impl_; }
bool
asym_fiber::operator==( asym_fiber const& other) const
{ return get_id() == other.get_id(); }
bool
asym_fiber::operator!=( asym_fiber const& other) const
{ return !( get_id() == other.get_id() ); }
void
asym_fiber::swap( asym_fiber & other)
{ impl_.swap( other.impl_); }
asym_fiber::id
asym_fiber::get_id() const
{ return asym_fiber::id( impl_); }
void
asym_fiber::run()
{
if ( ! impl_) throw fiber_moved();
BOOST_ASSERT( ! impl_->get_finished() && "fiber already finished");
impl_->run();
}
void
asym_fiber::yield()
{
if ( ! impl_) throw fiber_moved();
BOOST_ASSERT( ! impl_->get_finished() && "fiber already finished");
impl_->yield();
}
bool
asym_fiber::finished() const
{
if ( ! impl_) throw fiber_moved();
return impl_->get_finished();
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif

View File

@@ -1,82 +0,0 @@
// 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)
#define BOOST_FIBER_SOURCE
#include <boost/fiber/detail/asym_fiber_base.hpp>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
# if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4355)
# endif
namespace boost {
namespace fibers {
namespace detail {
BOOST_FIBER_DECL void trampoline_asym( void * vp)
{
BOOST_ASSERT( vp);
detail::asym_fiber_base * self(
static_cast< detail::asym_fiber_base * >( vp) );
try
{
self->exec();
self->set_finished();
}
catch (...)
{ BOOST_ASSERT( false && "exeception from fiber-function"); }
}
asym_fiber_base::do_not_return_t asym_fiber_base::do_not_return;
asym_fiber_base::do_return_t asym_fiber_base::do_return;
asym_fiber_base::asym_fiber_base( std::size_t stacksize, do_not_return_t) :
use_count_( 0),
finished_( false),
caller_(),
callee_( trampoline_asym, this, protected_stack( stacksize) )
{}
asym_fiber_base::asym_fiber_base( std::size_t stacksize, do_return_t) :
use_count_( 0),
finished_( false),
caller_(),
callee_( trampoline_asym, caller_, this, protected_stack( stacksize) )
{}
void
asym_fiber_base::run()
{ caller_.jump_to( callee_); }
void
asym_fiber_base::yield()
{ callee_.jump_to( caller_); }
void
asym_fiber_base::set_finished()
{ finished_ = true; }
bool
asym_fiber_base::get_finished() const
{ return finished_; }
}}}
# if defined(BOOST_MSVC)
# pragma warning(pop)
# endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif

View File

@@ -1,79 +0,0 @@
// 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)
#define BOOST_FIBER_SOURCE
#include <boost/fiber/detail/sym_fiber_base.hpp>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
# if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4355)
# endif
namespace boost {
namespace fibers {
namespace detail {
BOOST_FIBER_DECL void trampoline_sym( void * vp)
{
BOOST_ASSERT( vp);
detail::sym_fiber_base * self(
static_cast< detail::sym_fiber_base * >( vp) );
try
{
self->exec();
self->set_finished();
}
catch (...)
{ BOOST_ASSERT( false && "exeception from fiber-function"); }
}
sym_fiber_base::sym_fiber_base() :
use_count_( 0),
finished_( false),
ctx_()
{}
sym_fiber_base::sym_fiber_base( std::size_t stacksize) :
use_count_( 0),
finished_( false),
ctx_( trampoline_sym, this, protected_stack( stacksize) )
{}
sym_fiber_base::sym_fiber_base( std::size_t stacksize, sym_fiber_base & nxt) :
use_count_( 0),
finished_( false),
ctx_( trampoline_sym, nxt.ctx_, this, protected_stack( stacksize) )
{}
void
sym_fiber_base::switch_to( sym_fiber_base & other)
{ ctx_.jump_to( other.ctx_); }
void
sym_fiber_base::set_finished()
{ finished_ = true; }
bool
sym_fiber_base::get_finished() const
{ return finished_; }
}}}
# if defined(BOOST_MSVC)
# pragma warning(pop)
# endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif

View File

@@ -1,108 +0,0 @@
// 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)
#define BOOST_FIBER_SOURCE
#include <boost/fiber/sym_fiber.hpp>
#include <csignal>
#include <boost/config.hpp>
#include <boost/context/detail/stack_helper.hpp>
#include <boost/fiber/exceptions.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace fibers {
std::size_t sym_fiber::max_stacksize = boost::contexts::detail::stack_helper::maximal_stacksize();
std::size_t sym_fiber::min_stacksize = boost::contexts::detail::stack_helper::minimal_stacksize();
std::size_t sym_fiber::default_stacksize = 256 * 1024;
sym_fiber
sym_fiber::from_current_context()
{ return sym_fiber( new detail::sym_fiber_dummy() ); }
sym_fiber::sym_fiber() :
impl_()
{}
sym_fiber::sym_fiber( detail::sym_fiber_base::ptr const& impl) :
impl_( impl)
{}
sym_fiber::sym_fiber( sym_fiber const& other) :
impl_( other.impl_)
{}
sym_fiber &
sym_fiber::operator=( BOOST_COPY_ASSIGN_REF( sym_fiber) other)
{
sym_fiber tmp( other);
swap( tmp);
return * this;
}
sym_fiber::sym_fiber( BOOST_RV_REF( sym_fiber) other) :
impl_()
{ swap( other); }
sym_fiber &
sym_fiber::operator=( BOOST_RV_REF( sym_fiber) other)
{
sym_fiber tmp( boost::move( other) );
swap( tmp);
return * this;
}
sym_fiber::operator unspecified_bool_type() const
{ return impl_; }
bool
sym_fiber::operator!() const
{ return ! impl_; }
bool
sym_fiber::operator==( sym_fiber const& other) const
{ return get_id() == other.get_id(); }
bool
sym_fiber::operator!=( sym_fiber const& other) const
{ return !( get_id() == other.get_id() ); }
void
sym_fiber::swap( sym_fiber & other)
{ impl_.swap( other.impl_); }
sym_fiber::id
sym_fiber::get_id() const
{ return sym_fiber::id( impl_); }
void
sym_fiber::switch_to( sym_fiber & other)
{
if ( ! impl_ || ! other) throw fiber_moved();
BOOST_ASSERT( ! impl_->get_finished() && "fiber already finished");
BOOST_ASSERT( ! other.finished() && "fiber already finished");
impl_->switch_to( * other.impl_);
}
bool
sym_fiber::finished() const
{
if ( ! impl_) throw fiber_moved();
return impl_->get_finished();
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif

View File

@@ -1,31 +0,0 @@
# Boost.fiber Library Tests Jamfile
# 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)
import testing ;
project boost/fiber/test
: requirements
<dependency>../../context/build//context.hpp
<library>../../test/build//boost_unit_test_framework
<library>/boost/context//boost_context
<library>/boost/fiber//boost_fiber
<library>/boost/thread//boost_thread
<link>static
<threading>multi
;
rule test ( source )
{
return
[ run $(source).cpp ]
;
}
test-suite fiber :
[ test test_asym_fiber ]
[ test test_sym_fiber ]
;

View File

@@ -1,228 +0,0 @@
// 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 <sstream>
#include <string>
#include <boost/assert.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/all.hpp>
int value;
boost::asym_fiber gf;
void zero_args_fn()
{}
void one_args_fn( int)
{}
void two_args_fn( int, std::string const&)
{}
void set_value_fn( int i)
{ value = i; }
void increment_value_fn()
{
while ( true)
{
++value;
gf.yield();
}
}
struct X
{
void operator()()
{}
};
struct Y
{
void operator()( int i)
{}
};
void increment( int k, int n)
{
for ( int i = k; i < n; ++i)
{
gf.run();
BOOST_CHECK_EQUAL( i + 1, value);
}
}
void fn_first( int k, int n, boost::barrier & b)
{
increment( k, n);
b.wait();
}
void fn_last( int k, int n, boost::barrier & b)
{
b.wait();
increment( k, n);
}
void test_case_1()
{
X x;
boost::asym_fiber f1( & X::operator(), x, boost::asym_fiber::default_stacksize);
BOOST_CHECK( f1);
Y y;
boost::asym_fiber f2( & Y::operator(), y, 7, boost::asym_fiber::default_stacksize);
BOOST_CHECK( f2);
}
void test_case_2()
{
boost::asym_fiber f1( one_args_fn, 10, boost::asym_fiber::default_stacksize);
boost::asym_fiber f2;
BOOST_CHECK( f1);
BOOST_CHECK( ! f2);
}
void test_case_3()
{
boost::asym_fiber f1( zero_args_fn, boost::asym_fiber::default_stacksize);
boost::asym_fiber f2( one_args_fn, 1, boost::asym_fiber::default_stacksize);
boost::asym_fiber f3( two_args_fn, 1, "abc", boost::asym_fiber::default_stacksize);
}
void test_case_4()
{
boost::asym_fiber f1( zero_args_fn, boost::asym_fiber::default_stacksize);
f1 = boost::asym_fiber( zero_args_fn, boost::asym_fiber::default_stacksize);
boost::asym_fiber f2( one_args_fn, 1, boost::asym_fiber::default_stacksize);
f2 = boost::asym_fiber( one_args_fn, 1, boost::asym_fiber::default_stacksize);
}
void test_case_5()
{
boost::asym_fiber f1( one_args_fn, 10, boost::asym_fiber::default_stacksize);
BOOST_CHECK( f1);
boost::asym_fiber f2( boost::move( f1) );
BOOST_CHECK( ! f1);
BOOST_CHECK( f2);
boost::asym_fiber f3;
BOOST_CHECK( ! f3);
f3 = f2;
BOOST_CHECK( f3);
BOOST_CHECK_EQUAL( f2, f3);
}
void test_case_6()
{
boost::asym_fiber f1( zero_args_fn, boost::asym_fiber::default_stacksize);
boost::asym_fiber f2( zero_args_fn, boost::asym_fiber::default_stacksize);
boost::asym_fiber f3;
BOOST_CHECK( f1);
BOOST_CHECK( f2);
BOOST_CHECK( ! f3);
BOOST_CHECK( f1 != f2);
BOOST_CHECK( f1 != f3);
BOOST_CHECK( f2 != f3);
std::ostringstream os1;
os1 << f1.get_id();
std::ostringstream os2;
os2 << f2.get_id();
std::ostringstream os3;
os3 << f3.get_id();
std::string not_a_fiber("{not-a-fiber}");
BOOST_CHECK( os1.str() != os2.str() );
BOOST_CHECK( os1.str() != os3.str() );
BOOST_CHECK( os2.str() != os3.str() );
BOOST_CHECK( os1.str() != not_a_fiber);
BOOST_CHECK( os2.str() != not_a_fiber);
BOOST_CHECK( os3.str() == not_a_fiber);
}
void test_case_7()
{
boost::asym_fiber f1( zero_args_fn, boost::asym_fiber::default_stacksize);
boost::asym_fiber f2( zero_args_fn, boost::asym_fiber::default_stacksize);
boost::asym_fiber::id id1 = f1.get_id();
boost::asym_fiber::id id2 = f2.get_id();
f1.swap( f2);
BOOST_CHECK_EQUAL( f1.get_id(), id2);
BOOST_CHECK_EQUAL( f2.get_id(), id1);
}
void test_case_8()
{
value = 0;
boost::asym_fiber f( set_value_fn, 7, boost::asym_fiber::default_stacksize);
BOOST_CHECK_EQUAL( 0, value);
f.run();
BOOST_CHECK_EQUAL( 7, value);
}
void test_case_9()
{
value = 0;
gf = boost::asym_fiber( increment_value_fn, boost::asym_fiber::default_stacksize);
BOOST_CHECK_EQUAL( 0, value);
for ( int i = 0; i < 7; ++i)
{
gf.run();
BOOST_CHECK_EQUAL( i + 1, value);
}
}
void test_case_10()
{
value = 0;
gf = boost::asym_fiber( increment_value_fn, boost::asym_fiber::default_stacksize);
BOOST_CHECK_EQUAL( 0, value);
boost::barrier b( 2);
boost::thread t1( fn_first, 0, 5, boost::ref( b) );
boost::thread t2( fn_last, 5, 7, boost::ref( b) );
t1.join();
t2.join();
BOOST_CHECK_EQUAL( 7, value);
}
boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
{
boost::unit_test::test_suite * test =
BOOST_TEST_SUITE("Boost.Fiber: fiber test suite");
test->add( BOOST_TEST_CASE( & test_case_1) );
test->add( BOOST_TEST_CASE( & test_case_2) );
test->add( BOOST_TEST_CASE( & test_case_3) );
test->add( BOOST_TEST_CASE( & test_case_4) );
test->add( BOOST_TEST_CASE( & test_case_5) );
test->add( BOOST_TEST_CASE( & test_case_6) );
test->add( BOOST_TEST_CASE( & test_case_7) );
test->add( BOOST_TEST_CASE( & test_case_8) );
test->add( BOOST_TEST_CASE( & test_case_9) );
test->add( BOOST_TEST_CASE( & test_case_10) );
return test;
}

View File

@@ -1,235 +0,0 @@
// 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 <sstream>
#include <string>
#include <boost/assert.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/all.hpp>
int value;
boost::sym_fiber gf1;
boost::sym_fiber gf2;
void zero_args_fn()
{}
void one_args_fn( int)
{}
void two_args_fn( int, std::string const&)
{}
void set_value_fn( int i)
{
value = i;
gf2.switch_to( gf1);
}
void increment_value_fn()
{
while ( true)
{
++value;
gf2.switch_to( gf1);
}
}
struct X
{
void operator()()
{}
};
struct Y
{
void operator()( int i)
{}
};
void increment( int k, int n)
{
gf1 = boost::sym_fiber::from_current_context();
for ( int i = k; i < n; ++i)
{
gf1.switch_to( gf2);
BOOST_CHECK_EQUAL( i + 1, value);
}
}
void fn_first( int k, int n, boost::barrier & b)
{
increment( k, n);
b.wait();
}
void fn_last( int k, int n, boost::barrier & b)
{
b.wait();
increment( k, n);
}
void test_case_1()
{
X x;
boost::sym_fiber f1( & X::operator(), x, boost::sym_fiber::default_stacksize);
BOOST_CHECK( f1);
Y y;
boost::sym_fiber f2( & Y::operator(), y, 7, boost::sym_fiber::default_stacksize);
BOOST_CHECK( f2);
}
void test_case_2()
{
boost::sym_fiber f1( one_args_fn, 10, boost::sym_fiber::default_stacksize);
boost::sym_fiber f2;
BOOST_CHECK( f1);
BOOST_CHECK( ! f2);
}
void test_case_3()
{
boost::sym_fiber f1( zero_args_fn, boost::sym_fiber::default_stacksize);
boost::sym_fiber f2( one_args_fn, 1, boost::sym_fiber::default_stacksize);
boost::sym_fiber f3( two_args_fn, 1, "abc", boost::sym_fiber::default_stacksize);
}
void test_case_4()
{
boost::sym_fiber f1( zero_args_fn, boost::sym_fiber::default_stacksize);
f1 = boost::sym_fiber( zero_args_fn, boost::sym_fiber::default_stacksize);
boost::sym_fiber f2( one_args_fn, 1, boost::sym_fiber::default_stacksize);
f2 = boost::sym_fiber( one_args_fn, 1, boost::sym_fiber::default_stacksize);
}
void test_case_5()
{
boost::sym_fiber f1( one_args_fn, 10, boost::sym_fiber::default_stacksize);
BOOST_CHECK( f1);
boost::sym_fiber f2( boost::move( f1) );
BOOST_CHECK( ! f1);
BOOST_CHECK( f2);
boost::sym_fiber f3;
BOOST_CHECK( ! f3);
f3 = f2;
BOOST_CHECK( f3);
BOOST_CHECK_EQUAL( f2, f3);
}
void test_case_6()
{
boost::sym_fiber f1( zero_args_fn, boost::sym_fiber::default_stacksize);
boost::sym_fiber f2( zero_args_fn, boost::sym_fiber::default_stacksize);
boost::sym_fiber f3;
BOOST_CHECK( f1);
BOOST_CHECK( f2);
BOOST_CHECK( ! f3);
BOOST_CHECK( f1 != f2);
BOOST_CHECK( f1 != f3);
BOOST_CHECK( f2 != f3);
std::ostringstream os1;
os1 << f1.get_id();
std::ostringstream os2;
os2 << f2.get_id();
std::ostringstream os3;
os3 << f3.get_id();
std::string not_a_fiber("{not-a-fiber}");
BOOST_CHECK( os1.str() != os2.str() );
BOOST_CHECK( os1.str() != os3.str() );
BOOST_CHECK( os2.str() != os3.str() );
BOOST_CHECK( os1.str() != not_a_fiber);
BOOST_CHECK( os2.str() != not_a_fiber);
BOOST_CHECK( os3.str() == not_a_fiber);
}
void test_case_7()
{
boost::sym_fiber f1( zero_args_fn, boost::sym_fiber::default_stacksize);
boost::sym_fiber f2( zero_args_fn, boost::sym_fiber::default_stacksize);
boost::sym_fiber::id id1 = f1.get_id();
boost::sym_fiber::id id2 = f2.get_id();
f1.swap( f2);
BOOST_CHECK_EQUAL( f1.get_id(), id2);
BOOST_CHECK_EQUAL( f2.get_id(), id1);
}
void test_case_8()
{
value = 0;
gf1 = boost::sym_fiber::from_current_context();
gf2 = boost::sym_fiber( set_value_fn, 7, boost::sym_fiber::default_stacksize);
BOOST_CHECK_EQUAL( 0, value);
gf1.switch_to( gf2);
BOOST_CHECK_EQUAL( 7, value);
}
void test_case_9()
{
value = 0;
gf1 = boost::sym_fiber::from_current_context();
gf2 = boost::sym_fiber( increment_value_fn, boost::sym_fiber::default_stacksize);
BOOST_CHECK_EQUAL( 0, value);
for ( int i = 0; i < 7; ++i)
{
gf1.switch_to( gf2);
BOOST_CHECK_EQUAL( i + 1, value);
}
}
void test_case_10()
{
value = 0;
gf2 = boost::sym_fiber( increment_value_fn, boost::sym_fiber::default_stacksize);
BOOST_CHECK_EQUAL( 0, value);
boost::barrier b( 2);
boost::thread t1( fn_first, 0, 5, boost::ref( b) );
boost::thread t2( fn_last, 5, 7, boost::ref( b) );
t1.join();
t2.join();
BOOST_CHECK_EQUAL( 7, value);
}
boost::unit_test::test_suite * init_unit_test_suite( int, char* [])
{
boost::unit_test::test_suite * test =
BOOST_TEST_SUITE("Boost.Fiber: fiber test suite");
test->add( BOOST_TEST_CASE( & test_case_1) );
test->add( BOOST_TEST_CASE( & test_case_2) );
test->add( BOOST_TEST_CASE( & test_case_3) );
test->add( BOOST_TEST_CASE( & test_case_4) );
test->add( BOOST_TEST_CASE( & test_case_5) );
test->add( BOOST_TEST_CASE( & test_case_6) );
test->add( BOOST_TEST_CASE( & test_case_7) );
test->add( BOOST_TEST_CASE( & test_case_8) );
test->add( BOOST_TEST_CASE( & test_case_9) );
test->add( BOOST_TEST_CASE( & test_case_10) );
return test;
}