86#if defined(__SANITIZE_ADDRESS__)
88#elif defined(__has_feature)
89# if __has_feature(address_sanitizer)
97#if defined(__SANITIZE_THREAD__)
99#elif defined(__has_feature)
100# if __has_feature(thread_sanitizer)
119#define srn_fiber_get_scheduler_m(fiber) fiber->ctx->engine->scheduler
138#define SRN_FIBER_DEFAULT_STACK_SIZE (128U * 1024U)
330[[nodiscard]] [[gnu::nonnull(1, 2, 3)]]
srn_fiber_t *
389 void (*fn)(
void *),
void *arg);
438 return (
size_t)((
char *)s.
start - (
char *)s.
limit);
void srn_sched_register(srn_scheduler_t *sched, srn_fiber_t *fiber)
Record a fiber in the scheduler's registry of live fibers, where it stays until it is reaped.
srn_fiber_t * srn_fiber_worker_loop(void)
The worker's loop of the worker running on the calling os thread.
void srn_fiber_switch_final(srn_fiber_t *to)
Like srn_fiber_switch, but for a fiber that has finished and must not be resumed: control transfers t...
void srn_fiber_swap(srn_fiber_ctx_t *from, srn_fiber_ctx_t *to)
Save the current execution context into from, restore to, and resume on to's stack.
srn_fiber_t * srn_fiber_make(srn_context_t *ctx, srn_scheduler_t *sched, srn_fiber_entry_t entry, void *arg, size_t stack_size)
Create a fiber that will run entry(ctx, arg).
void srn_fiber_ready(srn_fiber_t *fiber)
Mark a suspended fiber runnable again.
srn_fiber_result_t srn_fiber_wait_for(srn_fiber_t *target)
Block the calling fiber until target finishes, then return its result.
srn_fiber_stack_t srn_fiber_stack_alloc(size_t size)
Allocate a stack of at least size usable bytes plus a guard page, or SRN_FIBER_DEFAULT_STACK_SIZE whe...
static size_t srn_fiber_stack_size(srn_fiber_stack_t s)
void srn_fiber_ctx_make(srn_fiber_ctx_t *fiber_ctx, srn_fiber_stack_t stack, void(*fn)(void *), void *arg)
Initialise a fresh fiber context so the first srn_fiber_swap into it begins executing fn(arg) on stac...
void srn_fiber_init_thread(srn_fiber_t *f)
Represent the calling OS thread as the running fiber ("#0"), so the scheduler or a test can switch aw...
void srn_sched_shutdown(srn_scheduler_t *sched)
The one stop tear down of the fiber subsystem, should be called once srn_sched_run has returned.
void srn_fiber_stack_free(srn_fiber_stack_t stack)
void srn_sched_stop(srn_scheduler_t *sched)
Ask a running scheduler to stop.
void srn_sched_enqueue(srn_scheduler_t *sched, srn_fiber_t *fiber)
Place a fiber on a scheduler's ready queue, making it eligible to run.
@ SRN_FIBER_NEW
Created, stack mapped, never resumed.
@ SRN_FIBER_RUNNING
Currently executing.
@ SRN_FIBER_READY
On the run queue, eligible to run.
@ SRN_FIBER_DONE
Entry returned. The result is final.
@ SRN_FIBER_SUSPENDED
Parked off the run queue, awaits srn_fiber_ready.
srn_fiber_result_t(* srn_fiber_entry_t)(srn_context_t *ctx, void *arg)
The function a fiber runs.
srn_scheduler_t * srn_sched_init(srn_engine_t *engine)
srn_fiber_t * srn_fiber_current(void)
The fiber currently running on this os thread (the bootstrap fiber if none).
void srn_sched_run(srn_scheduler_t *sched, int nworkers)
Run the scheduler with nworkers os threads draining it, returning once the pool goes quiescent (every...
void srn_fiber_switch(srn_fiber_t *from, srn_fiber_t *to)
Switch from from to to, both live fibers, telling AddressSanitizer about the stack change.
void srn_fiber_on_entry(srn_fiber_t *from)
Call as the first action inside a fresh fiber's entry.
bool(* srn_fiber_park_fn)(srn_fiber_t *self, void *arg)
Suspend commit callback.
void * srn_fiber_result_t
enum srn_fiber_state_e srn_fiber_state_t
void srn_fiber_on_reap(srn_fiber_t *fiber)
Call when a finished fiber is reaped, after it has switched away for the last time.
void srn_fiber_suspend(srn_fiber_park_fn commit, void *arg)
Park the running fiber until a party calls srn_fiber_ready.
void srn_fiber_yield(void)
Yield cooperatively: re-enqueue the running fiber and run the next ready one.
Engine is a structure to own the long living and main pieces of the compiler.
The saved context of a suspended fiber is a single word: its stack pointer at the moment it was switc...
One stack per fiber, mapped with a guard page at the low end so an overflow faults deterministically ...
void * guard
The protected page to detect stack overflows.
void * limit
Low end of usable region.
void * start
High end, stack pointer initialises to this address.
_Atomic srn_fiber_state_t state
The lifecycle state.
srn_fiber_t * link
Intrusive link threading this fiber onto one of the scheduler's singly-linked lists (the ready run qu...
srn_fiber_t * waiters
Head of the list of fibers blocked in srn_fiber_wait_for on this fiber.
srn_fiber_result_t result
Set when state reaches SRN_FIBER_DONE.
srn_fiber_park_fn park_commit
While this fiber is suspending, the commit the worker routine runs once the fiber is off the stack,...
srn_fiber_t * reg_prev
Registry links.
const char * name
For debugging purposes.
srn_fiber_ctx_t fiber_ctx
Saved stack pointer (see srn_fiber_ctx_t)