35extern void __sanitizer_start_switch_fiber(
void **fake_save,
const void *bottom,
size_t size);
37__sanitizer_finish_switch_fiber(
void *fake_save,
const void **bottom_old,
size_t *size_old);
48extern void *__tsan_get_current_fiber(
void);
49extern void *__tsan_create_fiber(
unsigned flags);
50extern void __tsan_destroy_fiber(
void *fiber);
51extern void __tsan_switch_to_fiber(
void *fiber,
unsigned flags);
65[[gnu::no_sanitize_address]] [[gnu::no_sanitize_thread]]
70 __sanitizer_start_switch_fiber(&from->fake_stack, to->
stack.
limit, size);
77 if (to->tsan_fiber !=
nullptr) {
78 __tsan_switch_to_fiber(to->tsan_fiber, 0);
83 __sanitizer_finish_switch_fiber(from->fake_stack,
nullptr,
nullptr);
87[[gnu::no_sanitize_address]] [[gnu::no_sanitize_thread]]
93 __sanitizer_start_switch_fiber(
nullptr, to->
stack.
limit, size);
99 if (to->tsan_fiber !=
nullptr) {
100 __tsan_switch_to_fiber(to->tsan_fiber, 0);
110[[gnu::no_sanitize_address]]
118 const void *bottom =
nullptr;
120 __sanitizer_finish_switch_fiber(
nullptr, &bottom, &size);
122 if (from !=
nullptr) {
135 __tsan_destroy_fiber(fiber->tsan_fiber);
147static void stack_bounds_probe(
void *loop_ptr) {
158 memset(f, 0,
sizeof(*f));
160 (void)snprintf(f->
name,
sizeof(f->
name),
"thread");
169 memset(&probe, 0,
sizeof(probe));
171 (void)snprintf(probe.
name,
sizeof(probe.
name),
"stack-bounds-probe");
180 f->tsan_fiber = __tsan_get_current_fiber();
222 if (name !=
nullptr) {
223 (void)snprintf(f->
name,
sizeof(f->
name),
"%s", name);
232 f->tsan_fiber = __tsan_create_fiber(0);
259 void *copy =
srn_allocate(ctx, size,
alignof(max_align_t));
261 memcpy(copy, arg, size);
void * srn_allocate(const srn_context_t *ctx, size_t size, size_t alignment)
srn_object_id_t srn_allocate_object_id(srn_engine_t *engine)
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...
srn_fiber_t * srn_fiber_spawn_copy(srn_context_t *ctx, srn_fiber_entry_t entry, const void *arg, size_t size)
srn_fiber_spawn with size bytes of *arg copied into ctx first, so the fiber owns its argument and the...
srn_fiber_t * srn_fiber_spawn(srn_context_t *ctx, srn_fiber_entry_t entry, void *arg)
Make and schedule a fiber with every default, the engine's scheduler, the configured stack size,...
static void srn_fiber_launcher(void *fiber_ptr)
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_fiber_switch(srn_fiber_t *from, srn_fiber_t *to)
Compiled without AddressSanitizer instrumentation, in stack-use-after-return mode ASan would place fr...
srn_fiber_t * srn_fiber_make(srn_context_t *ctx, srn_scheduler_t *sched, const char *name, srn_fiber_entry_t entry, void *arg, size_t stack_size)
Create a fiber that will run entry(ctx, arg), registered with sched but NOT scheduled.
void srn_fiber_on_entry(srn_fiber_t *from)
Call as the first action inside a fresh fiber's entry.
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.
AI Generated (🤦) Fiber subsystem overview.
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_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_stack_free(srn_fiber_stack_t stack)
@ 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_result_t(* srn_fiber_entry_t)(srn_context_t *ctx, void *arg)
The function a fiber runs.
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_schedule(srn_fiber_t *fiber)
Schedule a NEW fiber, making it eligible to run.
srn_engine_t * engine
Long term state of the compiler.
srn_configuration_t config
The runtime's tunable knobs, the single source for every configurable value (see configuration....
srn_scheduler_t * scheduler
The fiber scheduler, that is the entry point of the fiber subsystem.
size_t stack_size
Size of every fiber stack, in bytes.
The saved context of a suspended fiber is a single word, its stack pointer at the moment it was switc...
void * limit
Low end of usable region.
void * start
High end, stack pointer initialises to this address.
char name[SRN_FIBER_NAME_MAX]
Debug name, the caller's choice copied at creation, or the autogenerated f#<id> from the engine wide ...
_Atomic srn_fiber_state_t state
The lifecycle state.
srn_fiber_result_t result
Set when state reaches SRN_FIBER_DONE.
srn_fiber_ctx_t fiber_ctx
Saved stack pointer (see srn_fiber_ctx_t).
#define PANIC_IF_NULL(ptr)
#define SHOULD_NOT_HAPPEN