2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-20 14:42:21 +00:00
Files
fiber/libs/tasklet/doc/tasklet_ref.qbk
Oliver Kowalke 39ec793737 initial checkin
2011-02-09 18:41:35 +01:00

1265 lines
36 KiB
Plaintext

[/
(C) Copyright 2007-8 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).
]
[section:tasklet_management Tasklet Management]
[heading Synopsis]
Each __tasklet__ class represents a micro-task which will be launched and
managed by the __scheduler__ class. Objects of type __tasklet__ are copy- and
moveable.
boost::tasklet f; // not-a-tasklet
void f()
{
boost::tasklet f1( boost::tasklets::make_tasklet( some_fn, boost::tasklet::default_stacksize) );
boost::tasklet f2( boost::tasklets::make_tasklet( another_fn, boost::tasklet::default_stacksize) );
boost::tasklets::scheduler<> s;
s.submit( f1); // f1 gets copied
s.submit( boost::move( f2) ); // f2 gets moved
std::cout << f1.get_id() << std::endl;
std::cout << f2.get_id() << std::endl;
}
[note If tasklets are migrated between threads the code called by a tasklet must
not use thread-local-storage.]
[heading Launching]
A new tasklet is launched by passing an object of a callable type that can be
invoked with no parameters to the constructor and submiting the tasklet (copy-
or move-op.) to an instance of __scheduler__. The object is then copied into
internal storage, and invoked on the newly-created tasklet. 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_tasklet__ must ensure
that the referred-to object outlives the newly-created tasklet.
struct callable
{ void operator()(); };
boost::tasklet copies_are_safe()
{
callable x;
return boost::tasklet( x);
} // x is destroyed, but the newly-created tasklet has a copy, so this is OK
boost::tasklet oops()
{
callable x;
return boost::tasklet( boost::ref( x), boost::tasklet::default_stacksize);
} // x is destroyed, but the newly-created tasklet still has a reference
// this leads to undefined behaviour
If you wish to construct an instance of __tasklet__ with a function or callable
object that requires arguments to be supplied, this can be done by passing
additional arguments to the __tasklet__ constructor:
void find_the_question( int the_answer);
boost::tasklet deep_thought_2( find_the_question, 42, boost::tasklet::default_stacksize);
The arguments are ['copied] into the internal tasklet structure: if a reference
is required, use `boost::ref`, just as for references to callable functions.
For convinience `boost::tasklets::make_tasklet()` is provided:
boost::tasklet f( boost::tasklets::make_tasklet( new_fn, arg1, arg2, arg3, boost::tasklet::default_stacksize) );
Another alternative is to use `scheduler<>::make_tasklet()` which creates and
stores the new tasklet inside the scheduler.
boost::tasklets::scheduler<> sched;
sched.make_tasklet( new_fn, arg1, arg2, arg3, boost::tasklet_default_stacksize);
[heading Exceptions]
Exceptions thrown by the function or callable object passed to the __tasklet__
constructor are consumed by the framework (if it required to know which
exceptions was thrown use __future__ and __packaged_task__).
[warning Don't use the sjlj exception model. Frame-unwind-tables instead of
setjmp/longjmp based exception handling should be used.]
[heading Joining]
In order to wait for a tasklet to finish, the __join__ member functions of the
__tasklet__ object can be used. __join__ will block the calling tasklet until
the tasklet represented by the __tasklet__ object has completed.
If the tasklet has already completed, or the __tasklet__ object represents
__not_a_tasklet__, then __join__ returns immediately.
void some_fn()
{}
void joining_tasklet_fn( boost::tasklet f)
{ f.join(); }
boost:.tasklets::scheduler<> sched;
boost::tasklet f( some_fn, boost::tasklet_default_stacksize);
sched.submit_tasklet( f);
sched.make_tasklet( joining_tasklet, f, boost::tasklet_default_stacksize);
for (;;)
{
while ( sched.run() );
if ( sched.empty() ) break;
}
[heading Interruption]
A running tasklet can be ['interrupted] by invoking the __interrupt__ member
function. When the interrupted tasklet next executes one of the specified
__interruption_points__ (or if it is currently __blocked__ whilst executing one)
with interruption enabled, then a __tasklet_interrupted__ exception will be
thrown in the interrupted tasklet. If not caught, this will cause the execution
of the interrupted tasklet to terminate.
If a tasklet wishes to avoid being interrupted, it can create an instance of
__disable_interruption__. Objects of this class disable interruption for the
tasklet that created them on construction, and restore the interruption state to
whatever it was before on destruction:
void f()
{
// interruption enabled here
{
boost::this_tasklet::disable_interruption disabler1;
// interruption disabled
{
boost::this_tasklet::disable_interruption disabler2;
// interruption still disabled
} // disabler2 destroyed, interruption state restored
// interruption still disabled
} // disabler1 destroyed, interruption state restored
// interruption now enabled
}
The effects of an instance of __disable_interruption__ can be temporarily
reversed by constructing an instance of __restore_interruption__, passing in the
__disable_interruption__ object in question. This will restore the interruption
state to what it was when the __disable_interruption__ object was constructed,
and then disable interruption again when the __restore_interruption__ object is
destroyed.
void g()
{
// interruption enabled here
{
boost::this_tasklet::disable_interruption disabler;
// interruption disabled
{
boost::this_tasklet::restore_interruption restorer( disabler);
// interruption now enabled
} // restorer destroyed, interruption disable again
} // disabler destroyed, interruption state restored
// interruption now enabled
}
At any point, the interruption state for the current tasklet can be queried by
calling __interruption_enabled__.
[heading Predefined Interruption Points]
The following functions are ['interruption points], which will throw
__tasklet_interrupted__ if interruption is enabled for the current tasklet, and
interruption is requested for the current tasklet:
* [join_link `boost::tasklet::join()`]
* [cond_wait_link `boost::tasklets::condition::wait()`]
* [auto_reset_wait_link `boost::tasklets::auto_reset_event::wait()`]
* [manual_reset_wait_link `boost::tasklets::manual_reset_event::wait()`]
* [count_down_wait_link `boost::tasklets::count_down_event::wait()`]
* __interruption_point__
[heading Tasklet IDs]
Objects of class __tasklet_id__ can be used to identify tasklets. Each running
tasklet has a unique ID obtainable from the corresponding __tasklet__ by calling
the `get_id()` member function, or by calling `boost::this_tasklet::get_id()`
from within the tasklet. Objects of class __tasklet_id__ can be copied, and used
as keys in associative containers: the full range of comparison operators is
provided. Tasklet IDs can also be written to an output stream using the stream
insertion operator, though the output format is unspecified.
Each instance of __tasklet_id__ either refers to some tasklet, or
__not_a_tasklet__. Instances that refer to __not_a_tasklet__ compare equal to
each other, but not equal to any instances that refer to an actual tasklet. The
comparison operators on __tasklet_id__ yield a total order for every non-equal
tasklet ID.
[section:tasklet Class `tasklet`]
#include <boost/tasklet/tasklet.hpp>
class tasklet
{
public:
tasklet();
~tasklet();
template< typename Fn >
explicit tasklet( Fn fn, std::size_t stack_size);
template< typename Fn, typename A1, typename A2,... >
tasklet( Fn fn, A1 a1, A2 a2,..., std::size_t stack_size);
template< typename Fn >
explicit tasklet( Fn && fn, std::size_t stack_size);
// move support
tasklet( tasklet && x);
tasklet & operator=( tasklet && x);
operator unspecified-bool-type() const;
bool operator!() const;
void swap( tasklet & other);
id get_id() const;
bool operator==( tasklet const&) const;
bool operator!=( tasklet const&) const;
bool is_alive() const;
int priority() const;
void priority( int);
void interrupt();
bool interruption_requested() const;
void cancel();
void join();
};
void swap( tasklet & lhs, tasklet & rhs);
template< typename Fn >
tasklet make_tasklet( Fn fn, std::size_t stack_size);
template< typename Fn, typename A1, typename A2,..., typename A10 >
tasklet make_tasklet( Fn fn, A1 a1, A2 a2,..., A10 a10, std::size_t stack_size);
[section:default_constructor `tasklet()`]
[variablelist
[[Effects:] [Constructs a __tasklet__ instance that refers to
__not_a_tasklet__.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:callable_constructor_stack `template< typename Fn > tasklet( Fn fn, std::size_t stack_size)`]
[variablelist
[[Preconditions:] [`Callable` must by copyable.]]
[[Effects:] [`fn` is copied into storage managed internally by the tasklet
library, and that copy is invoked on a newly-created tasklet. Second version
sets the stack-size of the tasklet.]]
[[Postconditions:] [`*this` refers to the newly created tasklet.]]
[[Throws:] [__bad_alloc__]]
]
[endsect]
[section:multiple_argument_constructor `template< typename Fn, typename A1, typename A2,... > tasklet( Fn fn, A1 a1, A2 a2,..., std::size_t stack_size)`]
[variablelist
[[Preconditions:] [`Fn` and each `A`n must by copyable or movable.]]
[[Effects:] [As if `tasklet( boost::bind( fn, a1, a2,...) )`. Consequently,
`fn` and each `a`n are copied into internal storage for access by the new
tasklet. Second version additionaly sets the stack-size used by the tasklet.]]
[[Postconditions:] [`*this` refers to the newly created tasklet.]]
[[Throws:] [__bad_alloc__]]
[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be
specified in addition to the function `fn`.]]
]
[endsect]
[section:destructor `~tasklet()`]
[variablelist
[[Effects:] [Destroys `*this`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:get_id `tasklet::id get_id() const`]
[variablelist
[[Returns:] [If `*this` refers to a tasklet, an instance of __tasklet_id__ that
represents that tasklet. Otherwise returns a default-constructed
__tasklet_id__.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:join `void join()`]
[variablelist
[[Effects:] [Waits for `*this` to complete.]]
[[Throws:] [__tasklet_interrupted__ if the current tasklet is interrupted.]]
[[Notes:] [`join()` is one of the predefined __interruption_points__.]]
]
[endsect]
[section:interrupt `void interrupt()`]
[variablelist
[[Effects:] [If `*this` refers to a tasklet, request that the tasklet will be
interrupted the next time it enters one of the predefined
__interruption_points__ with interruption enabled, or if it is currently
__blocked__ in a call to one of the predefined __interruption_points__ with
interruption enabled .]]
[[Throws:] [__tasklet_moved__ if not a tasklet of execution.]]
]
[endsect]
[section:interruption_requested `bool interruption_requested()`]
[variablelist
[[Effects:] [If `*this` refers to a tasklet, the function returns if the
interruption of the tasklet was already requested.]]
[[Throws:] [__tasklet_moved__ if `*this` is not a tasklet of execution.]]
]
[endsect]
[section:cancel `void cancel()`]
[variablelist
[[Effects:] [If `*this` refers to a tasklet, request that the tasklet will be
canceled the next time it yields its execution.]]
[[Throws:] [__tasklet_moved__ if `*this` is not a tasklet of execution.]]
]
[endsect]
[section:is_alive `bool is_alive()`]
[variablelist
[[Effects:] [If `*this` refers to a tasklet, the function returns false if the
tasklet is terminated or not started Otherwise it returns true.]]
[[Throws:] [__tasklet_moved__ if `*this` is not a tasklet of execution.]]
]
[endsect]
[section:unspec_operator `operator unspecified-bool-type() const`]
[variablelist
[[Returns:] [If `*this` refers to a tasklet, the function returns true.
Otherwise false.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:not_operator `bool operator!() const`]
[variablelist
[[Returns:] [If `*this` refers not to a tasklet, the function returns true.
Otherwise false.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:equals `bool operator==( tasklet const& other) const`]
[variablelist
[[Returns:] [`get_id()==other.get_id()`]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:not_equals `bool operator!=( tasklet const& other) const`]
[variablelist
[[Returns:] [`get_id()!=other.get_id()`]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:swap `void swap( tasklet & other)`]
[variablelist
[[Effects:] [Exchanges the tasklets associated with `*this` and `other`, so
`*this` is associated with the tasklet 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/tasklet/tasklet.hpp>
void swap( tasklet & lhs, tasklet & rhs);
[variablelist
[[Effects:] [[link tasklet.tasklet_management.tasklet.swap `lhs.swap( rhs)`].]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:non_member_make_tasklet Non-member template function `make_tasklet()`]
#include <boost/tasklet/tasklet.hpp>
template< typename Fn >
tasklet make_tasklet( Fn fn, std::size_t stack_size);
template< typename Fn, typename A1, typename A2,... >
tasklet make_tasklet( Fn fn, A1 a1, A2 a2,..., std::size_t stack_size);
[variablelist
[[Effects:] [Creates a tasklet.]]
]
[endsect]
[section:id Class `boost::tasklet::id`]
#include <boost/tasklet/tasklet.hpp>
class tasklet::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 __tasklet_id__ instance that represents
__not_a_tasklet__.]]
[[Throws:] [Nothing]]
]
[endsect]
[section:is_equal `bool operator==( id const& y) const`]
[variablelist
[[Returns:] [`true` if `*this` and `y` both represent the same tasklet of
execution, or both represent __not_a_tasklet__, `false` otherwise.]]
[[Throws:] [Nothing]]
]
[endsect]
[section:not_equal `bool operator!=( id const& y) const`]
[variablelist
[[Returns:] [`true` if `*this` and `y` represent different tasklets of
execution, or one represents a tasklet of execution, and the other represent
__not_a_tasklet__, `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 __tasklet_id__ values places `*this` before `y`, `false` otherwise.]]
[[Throws:] [Nothing]]
[[Note:] [A __tasklet_id__ instance representing __not_a_tasklet__ will always
compare less than an instance representing a tasklet 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 __tasklet_id__ instance `x` to the
stream `os`, such that the representation of two instances of __tasklet_id__ `a`
and `b` is the same if `a==b`, and different if `a!=b`.]]
[[Returns:] [`os`]]
]
[endsect]
[endsect]
[endsect]
[section:this_tasklet Namespace `this_tasklet`]
[section:get_id Non-member function `get_id()`]
#include <boost/tasklet/utility.hpp>
namespace this_tasklet
{
tasklet::id get_id();
}
[variablelist
[[Returns:] [An instance of __tasklet_id__ that represents that currently
executing tasklet.]]
[[Throws:] [__tasklet_error__ if an error occurs.]]
]
[endsect]
[section:interruption_point Non-member function `interruption_point()`]
#include <boost/tasklet/utility.hpp>
namespace this_tasklet
{
void interruption_point();
}
[variablelist
[[Effects:] [Check to see if the current tasklet has been interrupted.]]
[[Throws:] [__tasklet_interrupted__ if __interruption_enabled__ and
__interruption_requested__ both return `true`.]]
]
[endsect]
[section:interruption_requested Non-member function `interruption_requested()`]
#include <boost/tasklet/utility.hpp>
namespace this_tasklet
{
bool interruption_requested();
}
[variablelist
[[Returns:] [`true` if interruption has been requested for the current tasklet,
`false` otherwise.]]
[[Throws:] [__tasklet_error__ if an error occurs.]]
]
[endsect]
[section:interruption_enabled Non-member function `interruption_enabled()`]
#include <boost/tasklet/utility.hpp>
namespace this_tasklet
{
bool interruption_enabled();
}
[variablelist
[[Returns:] [`true` if interruption has been enabled for the current tasklet,
`false` otherwise.]]
[[Throws:] [__tasklet_error__ if an error occurs.]]
]
[endsect]
[section:cancel Non-member function `cancel()`]
#include <boost/tasklet/utility.hpp>
namespace this_tasklet
{
void cancel();
}
[variablelist
[[Effects:] [Cancels the current tasklet.]]
[[Throws:] [__tasklet_error__ if an error occurs.]]
]
[endsect]
[section:non_member_yield Non-member function `yield()`]
#include <boost/tasklet/utility.hpp>
namespace this_tasklet
{
void yield();
}
[variablelist
[[Effects:] [Gives up the remainder of the current tasklet's time slice, to
allow other tasklets to run.]]
[[Throws:] [__tasklet_error__ if an error occurs.]]
]
[endsect]
[section:attaskletexit Non-member template function `at_tasklet_exit()`]
#include <boost/tasklet/utility.hpp>
template<typename Callable>
void at_tasklet_exit(Callable func);
[variablelist
[[Effects:] [A copy of `func` is placed in
tasklet-specific storage. This copy is invoked when the current tasklet
exits (even if the tasklet has been interrupted).]]
[[Postconditions:] [A copy of `func` has been saved for invocation on tasklet
exit.]]
[[Throws:] [`std::bad_alloc` if memory cannot be allocated for the copy of the
function, __tasklet_error__ if any other error occurs within the tasklet
library. Any exception thrown whilst copying `func` into internal storage.]]
[[Note:] [This function is *not* called if the tasklet was terminated
forcefully using platform-specific APIs, or if the tasklet is
terminated due to a call to `exit()`, `abort()` or
`std::terminate()`. In particular, returning from `main()` is
equivalent to call to `exit()`, so will not call any functions
registered with `at_tasklet_exit()`]]
]
[endsect]
[section:submit Non-member function `submit_tasklet( tasklet)`]
#include <boost/tasklet/utility.hpp>
namespace this_tasklet
{
void submit_tasklet( tasklet);
}
[variablelist
[[Effects:] [Submits the passed tasklet to the scheduler running the active
tasklet.]]
[[Throws:] [__tasklet_error__ if an error occurs.]]
]
[endsect]
[section:disable_interruption Class `disable_interruption`]
#include <boost/tasklet/interruption.hpp>
namespace this_tasklet
{
class disable_interruption
{
public:
disable_interruption();
~disable_interruption();
};
}
`boost::this_tasklet::disable_interruption` disables interruption for the
current tasklet on construction, and restores the prior interruption state on
destruction. Instances of `disable_interruption` cannot be copied or moved.
[section:constructor `disable_interruption()`]
[variablelist
[[Effects:] [Stores the current state of __interruption_enabled__ and disables
interruption for the current tasklet.]]
[[Postconditions:] [__interruption_enabled__ returns `false` for the current
tasklet.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:destructor `~disable_interruption()`]
[variablelist
[[Preconditions:] [Must be called from the same tasklet from which `*this` was
constructed.]]
[[Effects:] [Restores the current state of __interruption_enabled__ for the
current tasklet to that prior to the construction of `*this`.]]
[[Postconditions:] [__interruption_enabled__ for the current tasklet returns the
value stored in the constructor of `*this`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[endsect]
[section:restore_interruption Class `restore_interruption`]
#include <boost/tasklet/interruption.hpp>
namespace this_tasklet
{
class restore_interruption
{
public:
explicit restore_interruption(disable_interruption& disabler);
~restore_interruption();
};
}
On construction of an instance of `boost::this_tasklet::restore_interruption`,
the interruption state for the current tasklet is restored to the interruption
state stored by the constructor of the supplied instance of
__disable_interruption__. When the instance is destroyed, interruption is again
disabled. Instances of `restore_interruption` cannot be copied or moved.
[section:constructor `explicit restore_interruption(disable_interruption& disabler)`]
[variablelist
[[Preconditions:] [Must be called from the same tasklet from which `disabler`
was constructed.]]
[[Effects:] [Restores the current state of __interruption_enabled__ for the
current tasklet to that prior to the construction of `disabler`.]]
[[Postconditions:] [__interruption_enabled__ for the current tasklet returns the
value stored in the constructor of `disabler`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:destructor `~restore_interruption()`]
[variablelist
[[Preconditions:] [Must be called from the same tasklet from which `*this` was
constructed.]]
[[Effects:] [Disables interruption for the current tasklet.]]
[[Postconditions:] [__interruption_enabled__ for the current tasklet returns
`false`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[endsect]
[endsect]
[section:scheduler Scheduler]
[heading Synopsis]
The template __scheduler__ is responsible for managing and scheduling of
tasklets passed to it. The scheduling algorithm is provided as an template
argument to __scheduler__ (default is __round_robin__). The class implementing
the scheduling algorithm must derive from class __strategy__. It is possible to
migrate tasklets between schedulers.
[note If the tasklet is not thread-affine (using thread-local-storage) it can be
migrated to a scheduler running in another thread.]
Usally __scheduler__ will be invoked until all tasklets are scheduled and
finished.
boost::tasklets::scheduler<> sched;
sched.make_tasklet( some_fn);
for (;;)
{
while ( sched.run() );
if ( sched.empty() ) break;
}
[section:scheduler Template `template< typename Strategy > scheduler`]
#include <boost/tasklet/scheduler.hpp>
template< typename Strategy >
class scheduler
{
public:
scheduler();
~scheduler();
bool run();
bool empty();
std::size_t size();
std::size_t ready();
void submit_tasklet( tasklet);
template< typename Fn >
void make_tasklet( Fn fn, std::size_t stack_size);
template< typename Fn >
void make_tasklet( Fn && fn, std::size_t stack_size);
template< typename Fn, typename A1, typename A2,..., typename A10 >
void make_tasklet( Fn fn, A0 a0, A1 a1,..., A10 a10, std:size_t stack_size);
void migrate_tasklet( tasklet f);
template< typename OtherStrategy >
void migrate_tasklet( tasklet::id const& id, scheduler< OtherStrategy & sched);
};
[section:ctor `scheduler()`]
[variablelist
[[Effects:] [Creates an object of type scheduler< Strategy >.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:dtor `~scheduler()`]
[variablelist
[[Effects:] [Detaches all managed tasklets and destroys the scheduler.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:run `bool run()`]
[variablelist
[[Effects:] [Executes a tasklet from the internal storage and removes terminated
tasklets. The function returns `true` if a tasklet could be executed or a
terminated tasklet could be removed - otherwise `false`.]]
[[Throws:] [__system_error__ if a system call failed.]]
]
[endsect]
[section:empty `bool empty()`]
[variablelist
[[Effects:] [Returns `true` if the scheduler contains tasklets (maybe runnable
or waiting).]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:size `std::size_t size()`]
[variablelist
[[Effects:] [Returns how many tasklets the scheduler contains (maybe runnable or
waiting).]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:ready `std::size_t ready()`]
[variablelist
[[Effects:] [Returns how many tasklets are ready to run in the scheduler.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:submit_tasklet `void submit_tasklet( tasklet f)`]
[variablelist
[[Effects:] [This function stores the passed tasklet in the scheduler.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:make_tasklet2 `template< typename Fn > void make_tasklet( Fn fn, std::size_t stack_size)`]
[variablelist
[[Effects:] [The functions create a tasklet which gets stored in the internal
structures from scheduler.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:make_tasklet3 `template< typename Fn, typename A1, typename A2,..., typename A10 > void make_tasklet( Fn fn, A0 a0, A1 a1,..., A10 a10, std::size_t stack_size)`]
[variablelist
[[Effects:] [The functions create a tasklet which gets stored in the internal
structures from scheduler.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:migrate_tasklet `void migrate_tasklet( tasklet f)`]
[variablelist
[[Effects:] [The tasklet will be migrated to the scheduler.]]
[[Throws:] [Throws __tasklet_moved__, tasklet_error, scheduler_error.]]
]
[endsect]
[section:migrate_tasklet_t `template< typename OtherStrategy > void migrate_tasklet( tasklet::id const& id, scheduler< OtherStrategy > & sched)`]
[variablelist
[[Effects:] [The tasklet will be migrated to the scheduler.]]
[[Throws:] [Throws __tasklet_moved__, tasklet_error, scheduler_error.]]
]
[endsect]
[endsect]
[endsect]
[section:strategy Strategy]
[heading Synopsis]
The template __scheduler__ accepts the implementation of the scheduling
algorithm as a template argument (currently __round_robin__ is the choosen as
the default). Each class destined to implement a scheduling algorithm must
derive from __strategy__. The member `active_tasklet` holds the current
(running) tasklet and `master_tasklet` executes the scheduling logic.
[section:strategy Class `strategy`]
#include <boost/tasklet/strategy.hpp>
class strategy
{
protected:
static __thread tasklet * active_tasklet;
void attach( tasklet &);
void detach( tasklet &);
void call( tasklet &);
void yield( tasklet &);
void enable_interruption( tasklet &);
bool interruption_enabled( tasklet const&);
bool in_state_not_started( tasklet const&);
bool in_state_ready( tasklet const&);
bool in_state_running( tasklet const&);
bool in_state_wait_for_tasklet( tasklet const&);
bool in_state_wait_for_object( tasklet const&);
bool in_state_terminated( tasklet const&);
void set_state_ready( tasklet &);
void set_state_running( tasklet &);
void set_state_wait_for_tasklet( tasklet &);
void set_state_wait_for_object( tasklet &);
void set_state_terminated( tasklet &);
public:
strategy();
virtual ~strategy();
virtual void add( tasklet) = 0;
virtual void join( tasklet::id const&) = 0;
virtual void interrupt( tasklet::id const&) = 0;
virtual void reschedule( tasklet::id const&) = 0;
virtual void cancel( tasklet::id const&) = 0;
virtual void yield( tasklet::id const&) = 0;
virtual void wait_for_object( object::id const&, spin_mutex::scoped_lock &) = 0;
virtual void object_notify_one( object::id const&) = 0;
virtual void object_notify_all( object::id const&) = 0;
virtual tasklet release( tasklet::id const&) = 0;
virtual void migrate( tasklet) = 0;
virtual void detach_all() = 0;
virtual bool run() = 0;
virtual bool empty() = 0;
virtual std::size_t size() = 0;
virtual std::size_t ready() = 0;
};
[section:attach `void attach( tasklet &)`]
[variablelist
[[Effects:] [Protected member function in order to register the scheduler in
internal storage from the tasklet.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:detach `void detach( tasklet &)`]
[variablelist
[[Effects:] [Protected member function in order to unregister the scheduler in
internal storage from the tasklet.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:call `void call( tasklet & f)`]
[variablelist
[[Effects:] [Protected member function calls tasklet `f`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:yield2 `void yield( tasklet & f)`]
[variablelist
[[Effects:] [Protected member function yield tasklet `f`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:enable_interruption `void enable_interruption( tasklet &)`]
[variablelist
[[Effects:] [Protected member function enables interruption on the tasklet.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:interruption_enabled `bool interruption_enabled( tasklet const&)`]
[variablelist
[[Effects:] [Protected member function tests if interruption is enabled on the
tasklet.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:in_state_not_started `bool in_state_not_started( tasklet const&)`]
[variablelist
[[Effects:] [Protected member function tests if the tasklet is in the state
`started`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:in_state_ready `bool in_state_ready( tasklet const&)`]
[variablelist
[[Effects:] [Protected member function tests if the tasklet is in the state
`ready`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:in_state_running `bool in_state_running( tasklet const&)`]
[variablelist
[[Effects:] [Protected member function tests if the tasklet is in the state
`running`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:in_state_wait_for_tasklet `bool in_state_wait_for_tasklet( tasklet const&)`]
[variablelist
[[Effects:] [Protected member function tests if the tasklet is in the state
`wait for tasklet`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:in_state_wait_for_object `bool in_state_wait_for_object( tasklet const&)`]
[variablelist
[[Effects:] [Protected member function tests if the tasklet is in the state
`wait for object`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:in_state_terminated `bool in_state_terminated( tasklet const&)`]
[variablelist
[[Effects:] [Protected member function tests if the tasklet is in the state
`terminated`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:set_state_ready `void set_state_ready( tasklet &)`]
[variablelist
[[Effects:] [Protected member function sets the state of the tasklet to
`ready`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:set_state_running `void set_state_running( tasklet &)`]
[variablelist
[[Effects:] [Protected member function sets the state of the tasklet to
`running`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:set_state_wait_for_tasklet `void set_state_wait_for_tasklet( tasklet &)`]
[variablelist
[[Effects:] [Protected member function sets the state of the tasklet to
`wait for tasklet`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:set_state_wait_for_object `void set_state_wait_for_object( tasklet &)`]
[variablelist
[[Effects:] [Protected member function sets the state of the tasklet to
`wait for object`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:set_state_terminated `void set_state_terminated( tasklet &)`]
[variablelist
[[Effects:] [Protected member function sets the state of the tasklet to
`terminated`.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:ctor `strategy()`]
[variablelist
[[Effects:] [Creates an object of type strategy and initializes the
master_tasklet member.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:add `virtual void add( tasklet) = 0`]
[variablelist
[[Precondition:] [Tasklet was not assigned to another scheduler.]]
[[Effects:] [Add a tasklet to the scheduler.]]
]
[endsect]
[section:join `virtual void join( tasklet::id const&) = 0`]
[variablelist
[[Precondition:] [Tasklet belongs to this scheduler.]]
[[Effects:] [The active tasklet will yield until the tasklet identified by the
id has finished its
execution or was interrupted.]]
]
[endsect]
[section:interrupt `virtual void interrupt( tasklet::id const&) = 0`]
[variablelist
[[Precondition:] [Tasklet belongs to this scheduler.]]
[[Effects:] [The tasklet identified by the id will be interrupted by its next
execution.]]
]
[endsect]
[section:reschedule `virtual void reschedule( tasklet::id const&) = 0`]
[variablelist
[[Precondition:] [Tasklet belongs to this scheduler.]]
[[Effects:] [The scheduling-algorithm will be applied uppon the tasklet
identified by the id again.]]
]
[endsect]
[section:cancel `virtual void cancel( tasklet::id const&) = 0`]
[variablelist
[[Precondition:] [Tasklet belongs to this scheduler.]]
[[Effects:] [The tasklet with passed identifier will be stopped, e.g. removed
from the run-queue.]]
]
[endsect]
[section:yield1 `virtual void yield( tasklet::id const&) = 0`]
[variablelist
[[Precondition:] [Tasklet is the active tasklet.]]
[[Effects:] [Yield active tasklet and switch back to `master_tasklet` in order
to schedule another tasklet from the internal storage.]]
]
[endsect]
[section:wait_for_object `virtual void wait_for_object( object::id const&, spin_mutex::scoped_lock &) = 0`]
[variablelist
[[Effects:] [The active tasklet waits on object until notified.]]
]
[endsect]
[section:object_notify_one `virtual void object_notify_one( object::id const&) = 0`]
[variablelist
[[Effects:] [Notify one tasklet waiting on the object. The tasklet gets ready
for scheduling.]]
]
[endsect]
[section:object_notify_all `virtual void object_notify_all( object::id const&) = 0`]
[variablelist
[[Effects:] [Notify all tasklets waiting on the object. The tasklets get ready
for scheduling.]]
]
[endsect]
[section:release `virtual void release( tasklet::id const&) = 0`]
[variablelist
[[Postcondition:] [The tasklet is not terminated or waits on tasklet or
object.]]
[[Effects:] [Release tasklet from scheduler.]]
]
[endsect]
[section:migrate `virtual void migrate( tasklet) = 0`]
[variablelist
[[Postcondition:] [The tasklet is not already managed by scheduler.]]
[[Effects:] [Adds tasklet to scheduler.]]
]
[endsect]
[section:detach_all `virtual void detach_all() = 0`]
[variablelist
[[Effects:] [Detaches all managed tasklets from this.]]
]
[endsect]
[section:run `virtual bool run() = 0`]
[variablelist
[[Effects:] [Executes a tasklet from the internal storage and removes terminated
tasklets. The function returns `true` if a tasklet could be executed or a
terminated tasklet could be removed - otherwise `false`.]]
[[Throws:] [__system_error__ if a system call failed.]]
]
[endsect]
[section:empty `virtual bool empty() = 0`]
[variablelist
[[Effects:] [Returns `true` if the scheduler contains tasklets (maybe runnable
or waiting).]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:size `virtual std::size_t size() = 0`]
[variablelist
[[Effects:] [Returns how many tasklets the scheduler contains (maybe runnable or
waiting).]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:ready `virtual std::size_t ready() = 0`]
[variablelist
[[Effects:] [Returns how many tasklets are ready to run in the scheduler.]]
[[Throws:] [Nothing.]]
]
[endsect]
[endsect]
[section:round_robin Class `round_robin`]
The class `round_robin` derives from __strategy__ and implements a simple
round-robin scheduling-algorithm. It does not make use of tasklet-priorities.
[endsect]
[endsect]
[endsect]