32 return Context::init();
59 }
catch(std::bad_alloc
const&) {
68 int res = context->create();
77 if(
likely(attr.stackSize > 0)) {
78#ifdef ZTH_CONTEXT_WINFIBER
83 context, stack.
p, stack.
p + stack.
size - 1U);
117#ifdef ZTH_ENABLE_ASAN
119 void* fake_stack =
nullptr;
120 __sanitizer_start_switch_fiber(
121 from->alive() ? &fake_stack :
nullptr, to->stackUsable().p, to->stackUsable().size);
125 from->context_switch(*to);
127#ifdef ZTH_ENABLE_ASAN
128 __sanitizer_finish_switch_fiber(fake_stack,
nullptr,
nullptr);
141 if(!Config::EnableStackWaterMark || !context)
145 void* guard =
nullptr;
147 if(f && f->
context() == context) {
150 guard = context->stackGuard(
nullptr);
157 context->stackGuard(guard);
177#ifdef ZTH_ENABLE_ASAN
178 __sanitizer_finish_switch_fiber(
nullptr,
nullptr,
nullptr);
185 context->stackGuard();
189 context->attr().entry(context->attr().arg);
199 zth_abort(
"Returned to finished context");
209#define ZTH_STACK_WATERMARKER ((uint64_t)0x5a7468574de2889eULL)
218static void stack_watermark_align(
void*& stack,
size_t*& sizeptr,
size_t* size =
nullptr) noexcept
223 uintptr_t stack_ =
reinterpret_cast<uintptr_t
>(stack);
226 stack_ = (stack_ +
sizeof(size_t) - 1U) & ~(uintptr_t)(
sizeof(
size_t) - 1U);
228 sizeptr =
reinterpret_cast<size_t*
>(stack_);
231 stack_ +=
sizeof(size_t);
234 *size -= stack_ - (uintptr_t)stack;
236 stack =
reinterpret_cast<void*
>(stack_);
245 if(!Config::EnableStackWaterMark || !stack || !size)
251 size_t* sizeptr =
nullptr;
252 stack_watermark_align(stack, sizeptr, &size);
255 for(
size_t i = 0; i *
sizeof(uint64_t) <= size -
sizeof(uint64_t); i++)
267 if(!Config::EnableStackWaterMark || !stack)
270 size_t* sizeptr =
nullptr;
271 stack_watermark_align(stack, sizeptr);
283 if(!Config::EnableStackWaterMark || !stack)
286 size_t* sizeptr =
nullptr;
287 stack_watermark_align(stack, sizeptr);
288 size_t size = *sizeptr;
292#ifdef ZTH_USE_VALGRIND
293 VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(stack, size);
296 for(uint64_t* s =
static_cast<uint64_t*
>(stack);
300#ifdef ZTH_USE_VALGRIND
301 VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(stack, size);
304 return size - unused *
sizeof(uint64_t);
320#ifdef ZTH_STACK_SWITCH
321void*
zth_stack_switch(
void* stack,
size_t size,
void* (*f)(
void*)
noexcept,
void* arg)
noexcept
Context * context() const noexcept
static safe_ptr< singleton_type >::type instance() noexcept
Return the only instance of T within this thread.
The class that manages the fibers within this thread.
Fiber * currentFiber() const noexcept
void * stack_switch(void *stack, size_t size, void *(*f)(void *) noexcept, void *arg) noexcept
Context switch mechanism implementation.
#define ZTH_STACK_WATERMARKER
void context_entry(zth::Context *context) noexcept
Entry point of the fiber.
#define zth_stack_switch(stack, size, f, arg)
Call the function f using the new stack pointer.
void zth_abort(char const *fmt,...)
Aborts the process after printing the given printf() formatted message.
Worker & currentWorker() noexcept
Return the (thread-local) singleton Worker instance.
void yield(Fiber *preferFiber=nullptr, bool alwaysYield=false, Timestamp const &now=Timestamp::now())
Allow a context switch.
fiber_type< F >::factory fiber(F f, char const *name=nullptr)
Create a new fiber.
size_t stack_watermark_remaining(void *stack) noexcept
Return the remaining stack size that was never touched.
void stack_watermark_init(void *stack, size_t size) noexcept
Initialize the memory region for stack high water marking.
size_t stack_watermark_maxused(void *stack) noexcept
Return the high water mark of the stack.
size_t stack_watermark_size(void *stack) noexcept
Return the size of the given stack region.
#define zth_dbg(group, fmt, a...)
Debug printf()-like function.
void context_switch(Context *from, Context *to) noexcept
Perform context switch.
void context_destroy(Context *context) noexcept
Destroy and cleanup a context.
int context_init() noexcept
One-time context mechanism initialization.
string err(int e)
Return a string like strerror() does, but as a zth::string.
void context_deinit() noexcept
Final cleanup.
int context_create(Context *&context, ContextAttr const &attr) noexcept
Create a context.
size_t context_stack_usage(Context *context) noexcept
Return the high water mark of the stack of the given context.
#define zth_assert(expr)
assert(), but better integrated in Zth.
#define likely(expr)
Marks the given expression to likely be evaluated to true.