Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Static Protected Member Functions | Friends | List of all members
uni20::async::TaskPromiseBase Class Reference

Shared non-polymorphic implementation for Uni20 task promises. More...

#include <async_task_promise.hpp>

Inheritance diagram for uni20::async::TaskPromiseBase:
[legend]
Collaboration diagram for uni20::async::TaskPromiseBase:
[legend]

Classes

struct  ExceptionSinkNode
 Intrusive node describing one exception propagation sink. More...
 

Public Member Functions

int add_awaiter () noexcept
 Increase the number of active awaiters by one.
 
int add_awaiter (int count) noexcept
 Increase the number of active awaiters by a specified count.
 
template<TaskAwaitable A>
auto await_transform (A &&a)
 Transforms rvalue awaitables into task-aware awaiters.
 
template<TaskFactoryAwaitable A>
auto await_transform (A &&a)
 
template<TaskAwaitable A>
auto await_transform (A &a)
 Transform an awaiter to transfer one task ownership claim.
 
template<TaskFactoryAwaitable A>
auto await_transform (A &a)
 Transform the awaiter to provide transfer of shared ownership of the TaskFactory.
 
template<typename T >
auto await_transform (T &&)
 Fallback await_transform overload that rejects unsupported awaitables.
 
template<typename Task >
requires std::derived_from<std::remove_cvref_t<Task>, BasicTask>
Task && await_transform (Task &&task) noexcept
 Pass through a concrete task that uses the shared basic task representation.
 
TaskHandle destroy_with_continuation () noexcept
 safely destroy this coroutine, returning the continuation_ (which also must now be destroyed)
 
auto final_suspend () noexcept
 
std::exception_ptr get_exception () noexcept
 Get the current exception pointer, or nullptr if there is no current exception.
 
bool has_started () const noexcept
 Query whether the coroutine has begun executing.
 
auto initial_suspend () noexcept
 Suspend immediately on coroutine entry.
 
template<TaskPromise Promise>
TaskHandle initialize_task (std::coroutine_handle< Promise > handle) noexcept
 Cache erased self-identity and register the initial ownership claim.
 
bool is_cancel_on_resume () const noexcept
 Reports whether cancellation-on-resume is currently set.
 
void mark_started () noexcept
 Mark the coroutine as having been scheduled to start executing.
 
std::optional< int > preferred_numa_node () const noexcept
 Retrieve the preferred NUMA node for this coroutine.
 
void register_exception_sink (ExceptionSinkNode &node, std::shared_ptr< EpochContext > epoch, bool explicit_sink)
 Register one exception propagation sink with this promise.
 
bool release_awaiter () noexcept
 Decrease the number of active awaiters by one.
 
bool release_awaiter (int count) noexcept
 Decrease the number of active awaiters by a specified count.
 
TaskHandle release_ownership ()
 Release ownership of the coroutine and return it, if it was exclusively owned.
 
void rethrow_exception ()
 Throw the current exception, if there is one.
 
constexpr void return_void () noexcept
 Called when the coroutine returns normally.
 
IScheduler * scheduler () const noexcept
 Return the scheduler currently recorded for this task.
 
TaskHandle self () noexcept
 Return this promise's erased coroutine identity.
 
void set_cancel_on_resume () noexcept
 Mark the coroutine for cancellation at next resume.
 
void set_exception (std::exception_ptr e) noexcept
 Record an exception for deferred rethrow on resume.
 
void set_preferred_numa_node (std::optional< int > node) noexcept
 Set the preferred NUMA node recorded for this coroutine.
 
BasicTask take_ownership () noexcept
 Acquire exclusive ownership of the coroutine.
 
TaskFactory take_shared_ownership (int count)
 Acquire shared ownership of the coroutine for use with multi-await constructs.
 
constexpr TaskPromiseBase () noexcept=default
 Default-construct the promise.
 
template<typename... Args>
 TaskPromiseBase (Args &&... args)
 Construct the promise and process coroutine arguments for debug metadata.
 
void unhandled_exception ()
 Called on unhandled exception escaping the coroutine.
 
void unregister_exception_sink (ExceptionSinkNode &node, bool from_destructor) noexcept
 Unregister one exception propagation sink from this promise.
 
 ~TaskPromiseBase () noexcept
 

Static Public Member Functions

static bool can_transfer_directly (TaskHandle from, TaskHandle to) noexcept
 Report whether symmetric transfer is valid for two prepared task routes.
 
static void destroy_and_track (TaskHandle handle) noexcept
 Destroy a coroutine handle while recording destruction in the registry.
 
static void note_leaked (TaskHandle handle) noexcept
 Record that a coroutine has been intentionally leaked.
 
static void note_running (TaskHandle handle) noexcept
 Record that a coroutine has transitioned into a runnable/running state.
 
static void note_suspended (TaskHandle handle) noexcept
 Record that a coroutine has suspended and is waiting for resumption.
 
static void prepare_nested_route (TaskHandle parent, TaskHandle child)
 Complete an unbound child's route before nested execution.
 
static std::coroutine_handle resolve_await_suspend_result (TaskHandle current, BasicTask &&task)
 Resolve an await_suspend task return value into a coroutine transfer handle.
 
static void resume_and_track (TaskHandle handle)
 Resume a coroutine handle while recording the running transition.
 
template<TaskFactoryAwaitable A>
static void suspend_factory_awaitable (TaskHandle current, A &awaitable)
 Execute await_suspend for TaskFactoryAwaitable and apply TaskRegistry tracking.
 
template<TaskAwaitable A>
static auto suspend_task_awaitable (TaskHandle current, A &awaitable)
 Execute await_suspend for TaskAwaitable and apply TaskRegistry tracking.
 

Public Attributes

std::atomic< int > awaiter_count_ = 0
 Number of active ownership claims on this coroutine.
 
std::atomic< bool > cancel_on_resume_ {false}
 If true, then when the coroutine is next resumed (i.e.
 
TaskHandle continuation_ {}
 Uni20 task coroutines are nestable.
 
std::exception_ptr * continuation_exception_ = nullptr
 Destination for an exception returned by a directly awaited task.
 
std::exception_ptr eptr_ = nullptr
 
std::atomic< bool > exception_ {false}
 EpochContext can inject an exception into a coroutine, which will be thrown when resuming from an awaiter.
 
ExceptionSinkNode * exception_sinks_head_ {nullptr}
 
uint64_t Instance
 
std::string Name
 
std::atomic< int > preferred_numa_node_ {kNoPreferredNumaNode}
 Preferred NUMA node recorded for the coroutine.
 
std::atomic< bool > started_ {false}
 Tracks whether the coroutine has been scheduled or otherwise started.
 

Static Public Attributes

static constexpr int kNoPreferredNumaNode = std::numeric_limits<int>::min()
 

Static Protected Member Functions

static void validate_scheduler_route (IScheduler *scheduler, TaskRoute route)
 Validate a prospective task route without changing promise state.
 

Friends

class BasicTask
 

Detailed Description

Shared non-polymorphic implementation for Uni20 task promises.

Constructor & Destructor Documentation

◆ TaskPromiseBase() [1/2]

template<typename... Args>
uni20::async::TaskPromiseBase::TaskPromiseBase ( Args &&...  args)
inline

Construct the promise and process coroutine arguments for debug metadata.

Template Parameters
ArgsCoroutine argument types.
Parameters
argsCoroutine arguments forwarded for ProcessCoroutineArgument.

◆ ~TaskPromiseBase()

uni20::async::TaskPromiseBase::~TaskPromiseBase ( )
inlinenoexcept

◆ TaskPromiseBase() [2/2]

constexpr uni20::async::TaskPromiseBase::TaskPromiseBase ( )
constexprdefaultnoexcept

Default-construct the promise.

Member Function Documentation

◆ add_awaiter() [1/2]

int uni20::async::TaskPromiseBase::add_awaiter ( )
inlinenoexcept

Increase the number of active awaiters by one.

Returns
The value of the counter prior to the increment.

◆ add_awaiter() [2/2]

int uni20::async::TaskPromiseBase::add_awaiter ( int  count)
inlinenoexcept

Increase the number of active awaiters by a specified count.

Parameters
countThe number of awaiters to add.
Returns
The value of the counter prior to the increment.

◆ await_transform() [1/6]

template<TaskFactoryAwaitable A>
auto uni20::async::TaskPromiseBase::await_transform ( A &&  a)
inline

Transforms rvalue awaitables into task-aware awaiters.

Transforms rvalue awaitable factories into task-aware awaiters.

Template Parameters
AAwaitable type.
Parameters
aAwaitable object.
Returns
Task-aware awaiter bound to this promise.
Template Parameters
AAwaitable-factory type.
Parameters
aAwaitable factory object.
Returns
Task-aware awaiter bound to this promise.

◆ await_transform() [2/6]

template<TaskFactoryAwaitable A>
auto uni20::async::TaskPromiseBase::await_transform ( A &&  a)

◆ await_transform() [3/6]

template<TaskFactoryAwaitable A>
auto uni20::async::TaskPromiseBase::await_transform ( A &  a)
inline

Transform an awaiter to transfer one task ownership claim.

Transforms lvalue awaitable factories into task-aware awaiters.

Transforms lvalue awaitables into task-aware awaiters.

Template Parameters
AAwaitable type.
Parameters
aAwaitable object.
Returns
Task-aware awaiter bound to this promise.
Template Parameters
AAwaitable-factory type.
Parameters
aAwaitable factory object.
Returns
Task-aware awaiter bound to this promise.

◆ await_transform() [4/6]

template<TaskFactoryAwaitable A>
auto uni20::async::TaskPromiseBase::await_transform ( A &  a)

Transform the awaiter to provide transfer of shared ownership of the TaskFactory.

◆ await_transform() [5/6]

template<typename T >
auto uni20::async::TaskPromiseBase::await_transform ( T &&  )
inline

Fallback await_transform overload that rejects unsupported awaitables.

Template Parameters
TUnsupported awaitable type.

◆ await_transform() [6/6]

template<typename Task >
requires std::derived_from<std::remove_cvref_t<Task>, BasicTask>
Task && uni20::async::TaskPromiseBase::await_transform ( Task &&  task)
inlinenoexcept

Pass through a concrete task that uses the shared basic task representation.

Template Parameters
TaskConcrete task or basic task reference type.
Parameters
taskTask being awaited.
Returns
Forwarded task reference.

◆ can_transfer_directly()

bool uni20::async::TaskPromiseBase::can_transfer_directly ( TaskHandle  from,
TaskHandle  to 
)
inlinestaticnoexcept

Report whether symmetric transfer is valid for two prepared task routes.

Parameters
fromCurrently executing task.
toTask that would execute next on the current thread.

◆ destroy_and_track()

static void uni20::async::TaskPromiseBase::destroy_and_track ( TaskHandle  handle)
inlinestaticnoexcept

Destroy a coroutine handle while recording destruction in the registry.

◆ destroy_with_continuation()

TaskHandle uni20::async::TaskPromiseBase::destroy_with_continuation ( )
inlinenoexcept

safely destroy this coroutine, returning the continuation_ (which also must now be destroyed)

◆ final_suspend()

auto uni20::async::TaskPromiseBase::final_suspend ( )
inlinenoexcept
Note
At final_suspend the coroutine frame is owned exclusively by the coroutine. The scheduler must not retain or access the coroutine_handle after resume(). This function eagerly destroys the coroutine and resumes its continuation.

◆ get_exception()

std::exception_ptr uni20::async::TaskPromiseBase::get_exception ( )
inlinenoexcept

Get the current exception pointer, or nullptr if there is no current exception.

Precondition
caller must be the sole owner of the coroutine, in order to avoid race conditions with set_exception()

◆ has_started()

bool uni20::async::TaskPromiseBase::has_started ( ) const
inlinenoexcept

Query whether the coroutine has begun executing.

◆ initial_suspend()

auto uni20::async::TaskPromiseBase::initial_suspend ( )
inlinenoexcept

Suspend immediately on coroutine entry.

◆ initialize_task()

template<TaskPromise Promise>
TaskHandle uni20::async::TaskPromiseBase::initialize_task ( std::coroutine_handle< Promise >  handle)
inlinenoexcept

Cache erased self-identity and register the initial ownership claim.

◆ is_cancel_on_resume()

bool uni20::async::TaskPromiseBase::is_cancel_on_resume ( ) const
inlinenoexcept

Reports whether cancellation-on-resume is currently set.

Returns
true when cancellation is requested.

◆ mark_started()

void uni20::async::TaskPromiseBase::mark_started ( )
inlinenoexcept

Mark the coroutine as having been scheduled to start executing.

◆ note_leaked()

static void uni20::async::TaskPromiseBase::note_leaked ( TaskHandle  handle)
inlinestaticnoexcept

Record that a coroutine has been intentionally leaked.

◆ note_running()

static void uni20::async::TaskPromiseBase::note_running ( TaskHandle  handle)
inlinestaticnoexcept

Record that a coroutine has transitioned into a runnable/running state.

◆ note_suspended()

static void uni20::async::TaskPromiseBase::note_suspended ( TaskHandle  handle)
inlinestaticnoexcept

Record that a coroutine has suspended and is waiting for resumption.

◆ preferred_numa_node()

std::optional< int > uni20::async::TaskPromiseBase::preferred_numa_node ( ) const
inlinenoexcept

Retrieve the preferred NUMA node for this coroutine.

Returns
Optional containing the preferred node, if one was recorded.

◆ prepare_nested_route()

void uni20::async::TaskPromiseBase::prepare_nested_route ( TaskHandle  parent,
TaskHandle  child 
)
inlinestatic

Complete an unbound child's route before nested execution.

Scheduler inheritance is allowed across task domains only when the parent scheduler accepts the child's complete route.

Parameters
parentCurrently executing parent task.
childChild selected for execution.

◆ register_exception_sink()

void uni20::async::TaskPromiseBase::register_exception_sink ( ExceptionSinkNode &  node,
std::shared_ptr< EpochContext >  epoch,
bool  explicit_sink 
)
inline

Register one exception propagation sink with this promise.

Parameters
nodeIntrusive node owned by a buffer object.
epochEpoch that should receive unhandled coroutine exceptions.
explicit_sinktrue when registered via propagate_exceptions_to(...).

◆ release_awaiter() [1/2]

bool uni20::async::TaskPromiseBase::release_awaiter ( )
inlinenoexcept

Decrease the number of active awaiters by one.

Returns
true if this was the last awaiter and the coroutine is now unowned.

◆ release_awaiter() [2/2]

bool uni20::async::TaskPromiseBase::release_awaiter ( int  count)
inlinenoexcept

Decrease the number of active awaiters by a specified count.

Parameters
countThe number of awaiters to release.
Returns
true if the count reached zero exactly as a result of this call.

◆ release_ownership()

TaskHandle uni20::async::TaskPromiseBase::release_ownership ( )
inline

Release ownership of the coroutine and return it, if it was exclusively owned.

Returns
the coroutine handle, if we had exclusive ownership; otherwise returns null
Postcondition
The promise no longer owns the released claim.

◆ resolve_await_suspend_result()

static std::coroutine_handle uni20::async::TaskPromiseBase::resolve_await_suspend_result ( TaskHandle  current,
BasicTask &&  task 
)
inlinestatic

Resolve an await_suspend task return value into a coroutine transfer handle.

Parameters
currentCurrent coroutine identity.
taskReturned ownership token from awaitable.await_suspend(...).
Returns
Handle selected for immediate transfer by coroutine semantics.

◆ resume_and_track()

static void uni20::async::TaskPromiseBase::resume_and_track ( TaskHandle  handle)
inlinestatic

Resume a coroutine handle while recording the running transition.

◆ rethrow_exception()

void uni20::async::TaskPromiseBase::rethrow_exception ( )
inline

Throw the current exception, if there is one.

Precondition
caller must be the sole owner of the coroutine, in order to avoid race conditions with set_exception()

◆ return_void()

constexpr void uni20::async::TaskPromiseBase::return_void ( )
inlineconstexprnoexcept

Called when the coroutine returns normally.

◆ scheduler()

IScheduler * uni20::async::TaskPromiseBase::scheduler ( ) const
inlinenoexcept

Return the scheduler currently recorded for this task.

◆ self()

TaskHandle uni20::async::TaskPromiseBase::self ( )
inlinenoexcept

Return this promise's erased coroutine identity.

◆ set_cancel_on_resume()

void uni20::async::TaskPromiseBase::set_cancel_on_resume ( )
inlinenoexcept

Mark the coroutine for cancellation at next resume.

◆ set_exception()

void uni20::async::TaskPromiseBase::set_exception ( std::exception_ptr  e)
inlinenoexcept

Record an exception for deferred rethrow on resume.

Parameters
eException pointer to record.

◆ set_preferred_numa_node()

void uni20::async::TaskPromiseBase::set_preferred_numa_node ( std::optional< int >  node)
inlinenoexcept

Set the preferred NUMA node recorded for this coroutine.

Parameters
nodePreferred node value, or empty to clear the preference.

◆ suspend_factory_awaitable()

template<TaskFactoryAwaitable A>
void uni20::async::TaskPromiseBase::suspend_factory_awaitable ( TaskHandle  current,
A &  awaitable 
)
static

Execute await_suspend for TaskFactoryAwaitable and apply TaskRegistry tracking.

◆ suspend_task_awaitable()

template<TaskAwaitable A>
auto uni20::async::TaskPromiseBase::suspend_task_awaitable ( TaskHandle  current,
A &  awaitable 
)
static

Execute await_suspend for TaskAwaitable and apply TaskRegistry tracking.

◆ take_ownership()

BasicTask uni20::async::TaskPromiseBase::take_ownership ( )
inlinenoexcept

Acquire exclusive ownership of the coroutine.

This increments the awaiter count and asserts that the coroutine was previously unowned.

Precondition
The coroutine must be unowned (awaiter_count_ == 0).
Returns
A newly constructed BasicTask that takes ownership of the coroutine.

◆ take_shared_ownership()

TaskFactory uni20::async::TaskPromiseBase::take_shared_ownership ( int  count)
inline

Acquire shared ownership of the coroutine for use with multi-await constructs.

Parameters
countThe number of distinct BasicTask ownership claims to create.
Precondition
The coroutine must be unowned (awaiter_count_ == 0).
Returns
A factory that will dispense up to count owning BasicTask values.

◆ unhandled_exception()

void uni20::async::TaskPromiseBase::unhandled_exception ( )
inline

Called on unhandled exception escaping the coroutine.

◆ unregister_exception_sink()

void uni20::async::TaskPromiseBase::unregister_exception_sink ( ExceptionSinkNode &  node,
bool  from_destructor 
)
inlinenoexcept

Unregister one exception propagation sink from this promise.

Parameters
nodeIntrusive node currently linked into this promise.
from_destructortrue when called from buffer destruction.

◆ validate_scheduler_route()

static void uni20::async::TaskPromiseBase::validate_scheduler_route ( IScheduler *  scheduler,
TaskRoute  route 
)
inlinestaticprotected

Validate a prospective task route without changing promise state.

Friends And Related Symbol Documentation

◆ BasicTask

friend class BasicTask
friend

Member Data Documentation

◆ awaiter_count_

std::atomic<int> uni20::async::TaskPromiseBase::awaiter_count_ = 0

Number of active ownership claims on this coroutine.

Note
When the count reaches zero, the coroutine is considered unowned. Ownership must be transferred explicitly using take_ownership().

◆ cancel_on_resume_

std::atomic<bool> uni20::async::TaskPromiseBase::cancel_on_resume_ {false}

If true, then when the coroutine is next resumed (i.e.

transferred to the scheduler) it is destroyed (stack unwound and coroutine frame freed).

◆ continuation_

TaskHandle uni20::async::TaskPromiseBase::continuation_ {}

Uni20 task coroutines are nestable.

continuation_ tracks the parent coroutine so final suspension can return through the parent's scheduler route.

◆ continuation_exception_

std::exception_ptr* uni20::async::TaskPromiseBase::continuation_exception_ = nullptr

Destination for an exception returned by a directly awaited task.

This points into the awaiting BasicTask stored in the suspended parent frame and is cleared before the child frame is destroyed.

◆ eptr_

std::exception_ptr uni20::async::TaskPromiseBase::eptr_ = nullptr

◆ exception_

std::atomic<bool> uni20::async::TaskPromiseBase::exception_ {false}

EpochContext can inject an exception into a coroutine, which will be thrown when resuming from an awaiter.

This could, in principle, happen from multiple threads if we are awaiting multiple buffers so we protect access by the exception_ flag. Only the first attempt to set exception_ to true is permitted to set eptr_; subsequent exceptions are simply dropped.

◆ exception_sinks_head_

ExceptionSinkNode* uni20::async::TaskPromiseBase::exception_sinks_head_ {nullptr}

◆ Instance

uint64_t uni20::async::TaskPromiseBase::Instance

◆ kNoPreferredNumaNode

constexpr int uni20::async::TaskPromiseBase::kNoPreferredNumaNode = std::numeric_limits<int>::min()
staticconstexpr

◆ Name

std::string uni20::async::TaskPromiseBase::Name

◆ preferred_numa_node_

std::atomic<int> uni20::async::TaskPromiseBase::preferred_numa_node_ {kNoPreferredNumaNode}

Preferred NUMA node recorded for the coroutine.

◆ started_

std::atomic<bool> uni20::async::TaskPromiseBase::started_ {false}

Tracks whether the coroutine has been scheduled or otherwise started.


The documentation for this class was generated from the following files: