tmc::ex_braid#
ex_braid
is a serializing executor. Only one thread can run tasks on the ex_braid
at a time.
An instance of ex_braid
must be created as a child of another executor; threads from the parent executor will participate in executing tasks on the ex_braid
.
You can submit work items to a braid like any other executor using tmc::post()
/ tmc::post_bulk()
.
If a task is already running on a braid, co_await
ing or spawn()
ing tasks will also execute those tasks in the braid.
Usage Example#
You can enter a braid in the middle of a coroutine using tmc::enter()
/ tmc::exit()
.
In this way, a braid can be used as a fine-grained lock or async mutex.
Entering and exiting a braid has acquire/release semantics.
int non_atomic_counter;
tmc::task<void> braid_lock_middle(tmc::ex_braid& braid) {
// assume we start on the cpu executor here
int my_count;
auto lock = co_await tmc::enter(braid);
// we are on the braid now;
// accessing non_atomic_counter inside this block is thread-safe
my_count = non_atomic_counter;
non_atomic_counter++;
co_await lock.exit();
// we are back on the cpu executor now, with our original priority
}
You can run a child task on the braid using run_on()
, after which the parent task will resume back on the original executor.
int non_atomic_counter;
tmc::task<int> next_count() {
return non_atomic_counter++;
}
tmc::task<void> braid_lock_child(tmc::ex_braid& braid) {
// assume we start on the cpu executor here
// only the child task will run on the braid, where it can safely access non_atomic_counter
int my_count = co_await tmc::spawn(next_count()).run_on(braid);
// we are still on the cpu executor afterward
}
API Reference#
-
class ex_braid#
Public Functions
-
void post(work_item &&Item, size_t Priority = 0, size_t ThreadHint = NO_HINT)#
Submits a single work_item to the braid, and attempts to take the lock and start executing tasks on the braid.
Rather than calling this directly, it is recommended to use the
tmc::post()
free function template.
-
template<typename It>
inline void post_bulk(It &&Items, size_t Count, size_t Priority = 0, size_t ThreadHint = NO_HINT)# Submits
count
items to the braid, and attempts to take the lock and start executing tasks on the braid.It
must be an iterator type that implementsoperator*()
andIt& operator++()
.Rather than calling this directly, it is recommended to use the
tmc::post_bulk()
free function template.
-
inline tmc::ex_any *type_erased()#
Returns a pointer to the type erased
ex_any
version of this executor. This object shares a lifetime with this executor, and can be used for pointer-based equality comparison against the thread-localtmc::current_executor()
.
-
ex_braid()#
Construct a braid with the current executor as its parent. It is an error to call this from a thread that is not running on an executor.
-
void post(work_item &&Item, size_t Priority = 0, size_t ThreadHint = NO_HINT)#