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

some doc corrections

This commit is contained in:
Oliver Kowalke
2014-07-21 20:04:38 +02:00
parent 19c66aa610
commit 142dd2cd5b
2 changed files with 101 additions and 379 deletions

View File

@@ -20,12 +20,11 @@
bool operator<( fiber const& l, fiber const& r) noexcept;
void swap( fiber & l, fiber & r) noexcept;
class fiber_group;
class attributes;
struct algorithm;
struct sched_algorithm;
class round_robin;
void set_scheduling_algorithm( algorithm * al)
void set_scheduling_algorithm( sched_algorithm * al)
}
@@ -33,9 +32,12 @@
fibers::id get_id() noexcept;
void yield();
void sleep_until( fibers::clock_type::time_point const& timeout_point);
template< typename TimePoint >
void sleep_until( TimePoint const& timeout_point);
template< typename Rep, typename Period >
void sleep_for( fibers::clock_type::duration< Rep, Period > const& timeout_duration);
void sleep_for( chrono::duration< Rep, Period > const& timeout_duration);
bool thread_affinity() noexcept;
void thread_affinity( bool) noexcept;
void interruption_point();
bool interruption_requested() noexcept;
@@ -210,21 +212,42 @@ operators on __fiber_id__ yield a total order for every non-equal __fiber_id__.
fiber() noexcept;
template< typename Fn >
explicit fiber( Fn fn, attributes const& attr = attributes(),
stack_allocator const& stack_alloc = stack_allocator(),
std::allocator< fiber > const& alloc =
std::allocator< fiber >() );
explicit fiber( Fn fn);
template< typename Fn, typename StackAllocator >
explicit fiber( Fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< fiber > const& alloc =
std::allocator< fiber >() );
template< typename Fn >
fiber( attributes const& attrs, Fn fn);
template< typename Fn, typename StackAllocator, typename Allocator >
explicit fiber( Fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc);
template< typename StackAllocator, typename Fn >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, Fn fn);
template< typename StackAllocator, typename Fn >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, attributes const& attrs, Fn fn);
template< typename Fn >
explicit fiber( Fn && fn);
template< typename Fn >
fiber( attributes const& attrs, Fn && fn);
template< typename StackAllocator, typename Fn >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, Fn && fn);
template< typename StackAllocator, typename Fn >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, attributes const& attrs, Fn && fn);
#ifdef BOOST_FIBERS_USE_VARIADRIC_FIBER
template< typename Fn, class .. Args >
explicit fiber( Fn && fn, Args && ... args);
template< typename Fn, class .. Args >
fiber( attributes const& attrs, Fn && fn, Args && ... args);
template< typename StackAllocator, typename Fn, class .. Args >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, Fn && fn, Args && ... args);
template< typename StackAllocator, typename Fn, class .. Args >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, attributes const& attrs, Fn && fn, Args && ... args);
#endif
~fiber();
@@ -236,7 +259,7 @@ operators on __fiber_id__ yield a total order for every non-equal __fiber_id__.
fiber & operator=( fiber && other) noexcept;
operator safe_bool() const noexcept;
operator bool() const noexcept;
bool operator!() const noexcept;
@@ -277,21 +300,42 @@ operators on __fiber_id__ yield a total order for every non-equal __fiber_id__.
[heading Constructor]
template< typename Fn >
explicit fiber( Fn fn, attributes const& attr = attributes(),
stack_allocator const& stack_alloc = stack_allocator(),
std::allocator< fiber > const& alloc =
std::allocator< fiber >() );
explicit fiber( Fn fn);
template< typename Fn, typename StackAllocator >
explicit fiber( Fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< fiber > const& alloc =
std::allocator< fiber >() );
template< typename Fn >
fiber( attributes const& attrs, Fn fn);
template< typename Fn, typename StackAllocator, typename Allocator >
explicit fiber( Fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc);
template< typename StackAllocator, typename Fn >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, Fn fn);
template< typename StackAllocator, typename Fn >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, attributes const& attrs, Fn fn);
template< typename Fn >
explicit fiber( Fn && fn);
template< typename Fn >
fiber( attributes const& attrs, Fn && fn);
template< typename StackAllocator, typename Fn >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, Fn && fn);
template< typename StackAllocator, typename Fn >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, attributes const& attrs, Fn && fn);
#ifdef BOOST_FIBERS_USE_VARIADRIC_FIBER
template< typename Fn, class .. Args >
explicit fiber( Fn && fn, Args && ... args);
template< typename Fn, class .. Args >
fiber( attributes const& attrs, Fn && fn, Args && ... args);
template< typename StackAllocator, typename Fn, class .. Args >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, Fn && fn, Args && ... args);
template< typename StackAllocator, typename Fn, class .. Args >
fiber( allocator_arg_t, StackAllocator const& stack_alloc, attributes const& attrs, Fn && fn, Args && ... args);
#endif
[variablelist
[[Preconditions:] [`Fn` must be copyable or movable.]]
@@ -460,9 +504,9 @@ an applicable scheduler, a fiber is allowed to migrate across threads.]]
[[See also:] [[ns_function_link this_fiber..thread_affinity]]]
]
[member_heading fiber..operator safe_bool]
[member_heading fiber..operator bool]
operator safe_bool() const noexcept;
operator bool() const noexcept;
[variablelist
[[Returns:] [`true` if `*this` refers to a fiber of execution which has not
@@ -507,7 +551,7 @@ prior to the call.]]
[function_heading set_scheduling_algorithm]
void set_scheduling_algorithm( algorithm* scheduler );
void set_scheduling_algorithm( sched_algorithm* scheduler );
[variablelist
[[Effects:] [Directs __boost_fiber__ to use `scheduler`, which must be a
@@ -532,181 +576,6 @@ ensure that the instance is destroyed on thread termination.)]]
[endsect] [/ section Class fiber]
[#class_fiber_group]
[section:fiber_group Class `fiber_group`]
__fiber_group__ represents a collection of fibers which can be collectively
waited on or interrupted.
__fiber_group__ is neither copyable nor movable.
#include <boost/fiber/fiber_group.hpp>
class fiber_group
{
public:
fiber_group() {}
~fiber_group();
fiber_group( fiber_group const& other) = delete;
fiber_group & operator=( fiber_group const& other) = delete;
bool is_this_fiber_in();
bool is_fiber_in( fiber * f);
template< typename Fn >
fiber * create_fiber( Fn fn, attributes attrs = attributes() );
template< typename Fn, typename StackAllocator >
fiber * create_fiber( Fn fn, attributes attrs,
StackAllocator const& stack_alloc);
template< typename Fn, typename StackAllocator, typename Allocator >
fiber * create_fiber( Fn fn, attributes attrs,
StackAllocator const& stack_alloc,
Allocator const& alloc);
void add_fiber( fiber * f);
void remove_fiber( fiber * f);
void join_all();
void interrupt_all();
std::size_t size() const;
};
[heading Constructor]
fiber_group();
[variablelist
[[Effects:] [Create a new fiber group with no fibers.]]
]
[heading Destructor]
~fiber_group();
[variablelist
[[Effects:] [Destroy `*this` and all __fiber__ objects in the group.]]
]
[member_heading fiber_group..create_fiber]
template< typename Fn >
fiber * create_fiber( Fn fn, attributes attrs = attributes() );
template< typename Fn, typename StackAllocator >
fiber * create_fiber( Fn fn, attributes attrs,
StackAllocator const& stack_alloc);
template< typename Fn, typename StackAllocator, typename Allocator >
fiber * create_fiber( Fn fn, attributes attrs,
StackAllocator const& stack_alloc,
Allocator const& alloc);
[variablelist
[[Effects:] [Create a new __fiber__ object as-if by `new fiber( fn)` and add it
to the group.]]
[[Postcondition:] [`this->size()` is increased by one, the new fiber is running.]]
[[Returns:] [A pointer to the new __fiber__ object.]]
]
[member_heading fiber_group..add_fiber]
void add_fiber( fiber * f);
[variablelist
[[Precondition:] [The expression `delete f` is well-formed and will not result
in undefined behaviour and `is_fiber_in(f) == false`.]]
[[Effects:] [Add __fiber__ object pointed to by `f` to the group.]]
[[Postcondition:] [`this->size()` is increased by one.]]
[[Note:] [Unless the same `f` is later passed to `remove_fiber()`, `*this`
becomes responsible for the lifespan of `*f`. When the `fiber_group` is
destroyed, `*f` will also be destroyed.]]
]
The Precondition implies that `f` must point to a heap __fiber__ object. This
is erroneous:
boost::fibers::fiber_group fg;
{
boost::fibers::fiber f(somefunc);
fg.add_fiber(&f);
} // WRONG!
Instead, use the following:
boost::fibers::fiber_group fg;
{
boost::fibers::fiber* f = new boost::fibers::fiber(somefunc);
fg.add_fiber(f);
} // okay, fg is now responsible for *f
[member_heading fiber_group..remove_fiber]
void remove_fiber( fiber * f);
[variablelist
[[Effects:] [If `f` is a member of the group, remove it without calling
`delete`.]]
[[Postcondition:] [If `f` was a member of the group, `this->size()` is
decreased by one.]]
]
[member_heading fiber_group..join_all]
void join_all();
[variablelist
[[Requires:] [`is_this_fiber_in() == false`.]]
[[Effects:] [Call `join()` on each __fiber__ object in the group.]]
[[Postcondition:] [Every fiber in the group has terminated.]]
[[Note:] [Since __join__ is one of the predefined __interruption_points__,
`join_all()` is also an interruption point.]]
]
[member_heading fiber_group..is_this_fiber_in]
bool is_this_fiber_in();
[variablelist
[[Returns:] [true if there is a fiber `f` in the group such that
`f.get_id() == this_fiber::get_id()`.]]
]
[member_heading fiber_group..is_fiber_in]
bool is_fiber_in( fiber * f);
[variablelist
[[Returns:] [true if there is a fiber `fx` in the group such that
`fx.get_id() == f->get_id()`.]]
]
[member_heading fiber_group..interrupt_all]
void interrupt_all();
[variablelist
[[Effects:] [Call `interrupt()` on each __fiber__ object in the group.]]
]
[member_heading fiber_group..size]
int size();
[variablelist
[[Returns:] [The number of fibers in the group.]]
[[Throws:] [Nothing.]]
]
[endsect] [/ section Class fiber_group]
[#class_attributes]
[section:attributes Class attributes]

View File

@@ -34,169 +34,42 @@ it to [function_link set_scheduling_algorithm].
#include <boost/fiber/algorithm.hpp>
struct algorithm
struct sched_algorithm
{
virtual ~algorithm() {}
virtual ~sched_algorithm() {}
algorithm( algorithm const&) = delete;
algorithm & operator=( algorithm const&) = delete;
virtual void awakened( detail::worker_fiber *) = 0;
virtual void spawn( detail::worker_fiber::ptr_t const&) = 0;
virtual detail::worker_fiber * pick_next() = 0;
virtual void priority( detail::worker_fiber::ptr_t const&, int) noexcept = 0;
virtual void join( detail::worker_fiber::ptr_t const&) = 0;
virtual detail::worker_fiber::ptr_t active() noexcept = 0;
virtual bool run() = 0;
virtual void wait( unique_lock< detail::spinlock > &) = 0;
virtual bool wait_until( clock_type::time_point const&,
unique_lock< detail::spinlock > &) = 0;
template< typename Rep, typename Period >
bool wait_for( chrono::duration< Rep, Period > const&,
unique_lock< detail::spinlock > &);
virtual void yield() = 0;
virtual detail::worker_fiber::id get_main_id() = 0;
virtual detail::fiber_base::ptr_t get_main_fiber() = 0;
virtual void priority( detail::worker_fiber *, int) noexcept = 0;
};
void set_scheduling_algorithm( algorithm *);
void set_scheduling_algorithm( sched_algorithm *);
[member_heading algorithm..spawn]
[member_heading algorithm..awakened]
virtual void spawn( detail::worker_fiber::ptr_t const& f) = 0;
virtual void awakened( detail::worker_fiber * f) = 0;
[variablelist
[[Effects:] [Spawns fiber `f`, e.g. `f` will be entered the first time
or resumed where it was suspended before. Suspends the current fiber.]]
[[Effects:] [Marks fiber `f`, to be ready to run.]]
]
[member_heading algorithm..pick_next]
virtual detail::worker_fiber * pick_next() = 0;
[variablelist
[[Effects:] [Depending on the scheduling algorithm, this function returns the
fiber which has to be resumed next.]]
]
[member_heading algorithm..priority]
virtual void priority( detail::worker_fiber::ptr_t const& f, int p) noexcept = 0;
virtual void priority( detail::worker_fiber *, int) noexcept = 0;
[variablelist
[[Effects:] [Sets priority `p` for fiber `f`. Interpretation of "priority"
is entirely up to the subclass.]]
[[Throws:] [Nothing]]
]
[member_heading algorithm..join]
virtual void join( detail::worker_fiber::ptr_t const& f) = 0;
[variablelist
[[Effects:] [Suspends the current fiber until fiber `f` terminates.]]
]
[member_heading algorithm..active]
virtual detail::worker_fiber::ptr_t active() noexcept = 0;
[variablelist
[[Returns:] [The active fiber, or a null-pointer if the current
execution context is not a fiber managed by this __algo__ instance.]]
[[Note:] [While the initial context for a given thread is conceptually also a
fiber, it has no associated `detail::worker_fiber` instance. This is when
`active()` returns null. Higher-level __boost_fiber__ operations treat a
thread's initial context as equivalent to an explicitly-launched fiber, but
this method operates below that level of abstraction.]]
[[See also:] [[member_link algorithm..get_main_id]]]
]
[member_heading algorithm..run]
virtual bool run() = 0;
[variablelist
[[Effects:] [Selects one fiber in ready state and runs it until it suspends.
The choice of fiber is up to the subclass instance.]]
[[Returns:] [Returns `true` if one fiber was ready and successfully executed, `false`
otherwise.]]
]
[member_heading algorithm..wait]
virtual void wait( unique_lock< detail::spinlock > & lk) = 0;
[variablelist
[[Precondition:] [`lk` is locked by the current fiber. It locks the spinlock
protecting the internal state of a mutex or condition_variable.]]
[[Effects:] [Current fiber is set to waiting-state and gets suspended.]]
[[Postcondition:] [`lk` is unlocked.]]
]
[member_heading algorithm..wait_until]
virtual bool wait_until( clock_type::time_point const& timeout_time,
unique_lock< detail::spinlock > & lk) = 0;
[variablelist
[[Precondition:] [`lk` is locked by the current fiber. It locks the spinlock
protecting the internal state of a mutex or condition_variable.]]
[[Effects:] [Current fiber is set to waiting-state and gets suspended.]]
[[Returns:] [Returns `true` if fiber was resumed before time-point
`timeout_time` was reached, `false` otherwise.]]
[[Postcondition:] [`lk` is unlocked.]]
]
[member_heading algorithm..wait_for]
template< typename Rep, typename Period >
bool wait_for( chrono::duration< Rep, Period > const& timeout_duration,
unique_lock< detail::spinlock > & lk)
[variablelist
[[Precondition:] [`lk` is locked by the current fiber. It locks the spinlock
protecting the internal state of a mutex or condition_variable.]]
[[Effects:] [Current fiber is set to waiting-state and gets suspended.]]
[[Returns:] [Returns `true` if fiber was resumed before time-duration
`timeout_duration` has passed, `false` otherwise.]]
[[Postcondition:] [`lk` is unlocked.]]
]
[member_heading algorithm..yield]
virtual void yield() = 0;
[variablelist
[[Effects:] [Suspends active fiber without waiting; that is, the current fiber
is immediately set to ready-state.]]
]
[member_heading algorithm..get_main_id]
virtual detail::worker_fiber::id get_main_id() = 0;
[variablelist
[[Returns:] [A `worker_fiber::id` associated with the initial context of the
thread on which the scheduler is running.]]
[[Note:] [While the initial context for a given thread is conceptually also a
fiber, it has no associated `detail::worker_fiber` instance. Higher-level
__boost_fiber__ operations treat a thread's initial context as equivalent to
an explicitly-launched fiber, but this method operates below that level of
abstraction.]]
[[See also:] [[member_link algorithm..active]]]
]
[member_heading algorithm..get_main_fiber]
virtual detail::fiber_base::ptr_t get_main_fiber() = 0;
[variablelist
[[Returns:] [A `fiber_base::ptr_t` associated with the initial context of the
thread on which the scheduler is running.]]
[[Note:] [While the initial context for a given thread is conceptually also a
fiber, it has no associated `detail::worker_fiber` instance. Higher-level
__boost_fiber__ operations treat a thread's initial context as equivalent to
an explicitly-launched fiber, but this method operates below that level of
abstraction. The `fiber_base::ptr_t` is used in condition_variable and mutex
to signal threads initial context.]]
[[See also:] [[member_link algorithm..active]]]
[[Effects:] [Reschedule the fiber depending on the priority.]]
]
@@ -204,28 +77,8 @@ to signal threads initial context.]]
This class implements __algo__ and schedules fibers in round-robin fashion.
[class_heading round_robin_ws]
`round_robin_ws` is intended to be used for migrating fibers between threads (different
schedulers). For this purpose the class has two additional functions - `steal_from()` and
`migrate_to()`.
This functionality can be used to implement work-stealing/-sharing in a threadpool.
boost::fibers::round_robin_ws rr;
boost::fibers::set_scheduling_algorithm( & rr);
// steal a fiber from a scheduler `other_rr` running in another thread
boost::fibers::fiber f( other_rr->steal_from() );
// check if stealing was successful
if ( f)
{
// migrate stolen fiber to scheduler running in this thread
rr.migrate_to( f);
// detach fiber
f.detach();
}
[info The exsample section provides an scheduler used for migrating fibers
(work-stealing) between threads (different schedulers).]
[endsect]