1#ifndef ZTH_CONTEXT_UCONTEXT_H
2#define ZTH_CONTEXT_UCONTEXT_H
9#ifndef ZTH_CONTEXT_CONTEXT_H
10# error This file must be included by libzth/context/context.h.
18# error Please define _XOPEN_SOURCE before including headers.
29# pragma GCC diagnostic push
30# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
31class Context :
public impl::ContextArch<Context> {
44 struct context_trampoline_args {
49 static void context_trampoline(uint32_t args_high, uint32_t args_low)
noexcept
51# ifdef ZTH_ENABLE_ASAN
52 void const* oldstack =
nullptr;
54 __sanitizer_finish_switch_fiber(
nullptr, &oldstack, &oldsize);
58 workerStack = Stack((
void*)oldstack, oldsize);
61 context_trampoline_args* args =
nullptr;
62 if(
sizeof(
void*) == 4) {
64 args =
reinterpret_cast<context_trampoline_args*
>(
65 (
static_cast<uintptr_t
>(args_low)));
68 args =
reinterpret_cast<context_trampoline_args*
>(
69 ((
static_cast<uintptr_t
>(args_high) << 32)
70 | (
static_cast<uintptr_t
>(args_low))));
74 Context* context = args->context;
78# ifdef ZTH_ENABLE_ASAN
80 void* fake_stack =
nullptr;
81 __sanitizer_start_switch_fiber(&fake_stack, oldstack, oldsize);
86 siglongjmp(args->origin, 1);
88# ifdef ZTH_ENABLE_ASAN
89 __sanitizer_finish_switch_fiber(fake_stack,
nullptr,
nullptr);
114 uc.uc_link =
nullptr;
116 uc.uc_stack.ss_sp = stack_.
p;
117 uc.uc_stack.ss_size = stack_.
size;
120 context_trampoline_args args = {};
124 &uc,
reinterpret_cast<void (*)(
void)
>(&context_trampoline), 2,
125 static_cast<uint32_t
>((
reinterpret_cast<uintptr_t
>(&args)) >> 32),
126 static_cast<uint32_t
>(
reinterpret_cast<uintptr_t
>(&args)));
128# ifdef ZTH_ENABLE_ASAN
129 void* fake_stack =
nullptr;
130 __sanitizer_start_switch_fiber(&fake_stack, stack_.
p, stack_.
size);
143# ifdef ZTH_ENABLE_ASAN
144 __sanitizer_finish_switch_fiber(fake_stack,
nullptr,
nullptr);
152# ifdef ZTH_ENABLE_ASAN
154 void* fake_stack =
nullptr;
160 __sanitizer_start_switch_fiber(
166 siglongjmp(to.m_env, 1);
168# ifdef ZTH_ENABLE_ASAN
169 __sanitizer_finish_switch_fiber(fake_stack,
nullptr,
nullptr);
176# pragma GCC diagnostic pop
impl::ContextArch< Context > base
void context_switch(Context &to) noexcept
constexpr Context(ContextAttr const &attr) noexcept
Stack & workerStack() noexcept
Stack const & stack() const noexcept
Return the stack address.
int create() noexcept
Create context.
ContextAttr & attr() noexcept
Return the context attributes, requested by the user.
Stack const & stackUsable() const noexcept
Return the start of the actual usable stack.
bool alive() const noexcept
Check if fiber is still running.
Worker & currentWorker() noexcept
Return the (thread-local) singleton Worker instance.
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
void context_entry(Context *context)
static bool const ContextSignals
Take POSIX signal into account when doing a context switch.
#define zth_assert(expr)
assert(), but better integrated in Zth.
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.