-
Notifications
You must be signed in to change notification settings - Fork 202
API Reference
Amanieu d'Antras edited this page Feb 7, 2015
·
16 revisions
class task<Result> {
// Result type of the task
typedef Result result_type;
// Create an empty task object (operator bool returns false)
task();
// Movable but not copyable
task(const task&) = delete;
task(task&&);
task& operator=(const task&) = delete;
task& operator=(task&&);
// Destroy the task object. This detaches the task and does not wait for
// it to finish.
~task();
// Returns true if this task object contains a reference to a valid
// task. If this is not the case then all other functions throw a
// std::invalid_argument exception.
explicit operator bool() const;
// Waits for the task to complete and then retrieves the result of the
// task. If the task contains an exception then that exception is
// rethrown. The result is moved out of the task, and then the task is
// cleared (operator bool returns false).
Result get();
// Waits for the task to have finished executing
void wait() const;
// Returns whether the task has finished executing
bool ready() const;
// Returns whether the task was canceled due to an exception
bool canceled() const;
// Returns the std::exception_ptr associated with this task if it
// was canceled by an exception. This calls wait() internally.
std::exception_ptr get_exception() const;
// Register a continuation function to be run after this task and
task<T> then(Func f); // T = result type of f
task<T> then(scheduler& sched, Func f); // T = result type of f
// Turn this task object into a shared_task<T>. This will
// invalidate the current task object.
shared_task<Result> share();
};
// shared_task<T> is almost identical to task<T>, except:
// - shared_task<T> is copyable, copies all refer to the same task
// - shared_task<T> doesn't get invalidated on get() and then()
// - get() returns a const reference to the result
class shared_task<Result> {
typedef Result result_type;
shared_task();
shared_task(const shared_task&);
shared_task(shared_task&&);
shared_task& operator=(const shared_task&);
shared_task& operator=(shared_task&&);
~shared_task();
explicit operator bool() const;
void get() const; // If Result is void
Result& get() const; // If Result is a reference type
const Result& get() const; // Otherwise
void wait() const;
bool ready() const;
bool canceled() const;
std::exception_ptr get_exception() const;
task<T> then(Func f) const; // T = result type of f
task<T> then(scheduler& sched, Func f) const; // T = result type of f
};
// Create a task already containing the given value
task<T> make_task(T value);
task<void> make_task();
// Spawn a task to run the given function, optionally using the given
// scheduler instead of the default. The default scheduler can be overriden
// by defining the LIBASYNC_CUSTOM_DEFAULT_SCHEDULER preprocessor macro.
task<T> spawn(Func f); // T = result type of f
task<T> spawn(scheduler& sched, Func f); // T = result type of f
class local_task<Func> {
// Local tasks can only be created using local_spawn()
local_task() = delete;
// Local tasks are non-movable and non-copyable
local_task(const local_task&) = delete;
local_task(local_task&&) = delete;
local_task& operator=(const local_task&) = delete;
local_task& operator=(local_task&&) = delete;
// The destructor implicitly waits for the task to finish
~local_task();
// Waits for the task to complete and then retrieves the result of the task.
// If the task contains an exception then that exception is rethrown. The
// result is moved out of the task.
void get(); // If Result == void
Result& get(); // If Result is a reference type
Result get(); // Otherwise
// Waits for the task to have finished executing
void wait() const;
// Returns whether the task has finished executing
bool ready() const;
};
// Spawn a local task to run the given function, optionally using the given
// scheduler instead of the default. The default scheduler can be overriden by
// defining the LIBASYNC_DEFAULT_SCHEDULER preprocessor macro.
local_task<Func> local_spawn(Func f);
local_task<Func> local_spawn(scheduler& sched, Func f);
class event_task<Result> {
event_task();
event_task(const event_task&) = delete;
event_task(event_task&&);
event_task& operator=(const event_task&) = delete;
event_task& operator=(event_task&&);
~event_task();
task<Result> get_task() const;
bool set() const; // If Result == void
bool set(Result& r) const; // If Result is a reference type
bool set(Result&& r) const; // Otherwise
bool set(const Result& r) const; // Otherwise
bool set_exception(std::exception_ptr except) const;
bool cancel() const;
};
// For T = void, return value is task<size_t>
task<std::pair<size_t, T>> when_any(task<T>/shared_task<T>... tasks); // All T must be the same
task<std::pair<size_t, T>> when_any(Iter begin, Iter end); // Range of task<T> or shared_task<T>
task<std::pair<size_t, T>> when_any(Range tasks); // Range of task<T> or shared_task<T>
struct void_ {};
task<std::tuple<T...>> when_all(task<T>/shared_task<T>... tasks); // Allows different T types, void becomes void_
// For T = void, return value is task<void>
task<std::vector<T>> when_all(Iter begin, Iter end); // Range of task<T> or shared_task<T>
task<std::vector<T>> when_all(Range tasks); // Range of task<T> or shared_task<T>
// Exception thrown by cancel_current_task
struct task_canceled {};
// A cancellation token is a boolean flag which indicates a cancellation request
class cancellation_token {
// A token is initialized to the 'not canceled' state
cancellation_token();
// Tokens are non-movable and non-copyable
cancellation_token(const cancellation_token&) = delete;
cancellation_token(cancellation_token&&) = delete;
cancellation_token& operator=(const cancellation_token&) = delete;
cancellation_token& operator=(cancellation_token&&) = delete;
// Returns whether the token has been canceled
bool is_canceled() const;
// Sets the token to the canceled state
void cancel();
};
// Throws a task_canceled exception
void cancel_current_task();
// Calls cancel_current_task() if the token is canceled
void interruption_point(const cancellation_token& token);
class task_run_handle {
// Task handles are movable but not copyable
task_run_handle(const task_run_handle&) = delete;
task_run_handle(task_run_handle&&);
task_run_handle& operator=(const task_run_handle&) = delete;
task_run_handle& operator=(task_run_handle&&);
// Executes the task and invalidates the handle
void run();
// Same as before, but uses the given wait handler
void run_with_wait_handler(wait_handler handler)
// Convert to and from void pointer
void* to_void_ptr();
static task_handle from_void_ptr(void*);
};
class task_wait_handle {
// Non-copyable and non-movable
task_wait_handle(const task_wait_handle&) = delete;
task_wait_handle(task_wait_handle&&) = delete;
task_wait_handle& operator=(const task_wait_handle&) = delete;
task_wait_handle& operator=(task_wait_handle&&) = delete;
// Check if the task has finished
bool ready() const;
// Queue a function to be executed when the task has finished executing.
template<typename Func> void on_finish(Func&& func)
};
// Set the wait handler for the current thread. This is used to allow a thread to do useful work while waiting for a task to complete.
typedef void (*wait_handler)(task_wait_handle t);
wait_handler set_thread_wait_handler(wait_handler w);
// Scheduler interface, all schedulers derive from this
class scheduler {
virtual void schedule(task_run_handle t) = 0;
};
// Built-in scheduler implementations
scheduler& threadpool_scheduler();
scheduler& inline_scheduler();
scheduler& thread_scheduler();
// Range object representing 2 iterators
class range<Iter> {
Iter begin() const;
Iter end() const;
};
// Create a range
range<Iter> make_range(Iter begin, Iter end);
// Integer range between 2 integers
class int_range<T> {
class iterator;
iterator begin() const;
iterator end() const;
};
// Create an integer range
int_range<T> irange(T begin, T end);
// Partitioners which wrap a range and split it between threads. A partitioner is just a range with an additional split() function.
<detail> static_partitioner(Range&& range);
<detail> static_partitioner(Range&& range, size_t grain);
<detail> auto_partitioner(Range&& range);
// Convert a range to a partitioner. This is a utility function for implementing new parallel algorithms. If the argument is already a partitioner then a copy of it is returned.
decltype(auto_partitioner(range)) to_partitioner(Range&& range);
Partitioner to_partitioner(Partitioner&& partitioner);
// Run a set of functions in parallel, optionally using a scheduler
void parallel_invoke(Func&&... funcs);
void parallel_invoke(scheduler& sched, Func&&... funcs);
// Run a function over a range in parallel. The range parameter can also be a partitioner to explicitly control how jobs are distributed to threads.
void parallel_for(Range&& range, const Func& func);
void parallel_for(scheduler& sched, Range&& range, const Func& func);
// Reduce a range in parallel. The range parameter can also be a partitioner to explicitly control how jobs are distributed to threads.
Result parallel_reduce(Range&& range, const Result& initial, const ReduceFunc& reduce);
Result parallel_reduce(scheduler& sched, Range&& range, const Result& initial, const ReduceFunc& reduce);
// Apply a function to a range and reduce it. The range parameter can also be a partitioner to explicitly control how jobs are distributed to threads.
Result parallel_map_reduce(Range&& range, const Result& initial, const MapFunc& map, const ReduceFunc& reduce);
Result parallel_map_reduce(scheduler& sched, Range&& range, const Result& initial, const MapFunc& map, const ReduceFunc& reduce);