Zth (libzth)
Loading...
Searching...
No Matches
sjlj.h
Go to the documentation of this file.
1#ifndef ZTH_CONTEXT_SJLJ_H
2#define ZTH_CONTEXT_SJLJ_H
3/*
4 * SPDX-FileCopyrightText: 2019-2026 Jochem Rutgers
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 */
8
9#ifndef ZTH_CONTEXT_CONTEXT_H
10# error This file must be included by libzth/context/context.h.
11#endif
12
13#ifdef __cplusplus
14
15# include <csetjmp>
16# include <csignal>
17
18namespace zth {
19
20class Context : public impl::ContextArch<Context> {
22public:
23 typedef ContextArch<Context> base;
24
25 constexpr explicit Context(ContextAttr const& attr) noexcept
26 : base(attr)
27 , m_env()
28 {}
29
30private:
31# ifdef ZTH_OS_BAREMETAL
32 // As bare metal does not have signals, sigsetjmp and siglongjmp is not necessary.
33 typedef jmp_buf jmp_buf_type;
34# define zth_sjlj_setjmp(env) ::setjmp(env)
35# define zth_sjlj_longjmp(env, val) ::longjmp(env, val)
36# else
37 typedef sigjmp_buf jmp_buf_type;
38# define zth_sjlj_setjmp(env) ::sigsetjmp(env, Config::ContextSignals)
39# define zth_sjlj_longjmp(env, val) ::siglongjmp(env, val)
40# endif
41
42public:
43 // cppcheck-suppress duplInheritedMember
44 int create() noexcept
45 {
46 int res = base::create();
47 if(res)
48 return res;
49
50 if(unlikely(!stack()))
51 // Stackless fiber only saves current context; nothing to do.
52 return 0;
53
55 void** sp_ = sp(stackUsable());
56 set_sp(m_env, sp_);
57 set_pc(m_env, reinterpret_cast<void*>(&context_trampoline_from_jmp_buf));
58 stack_push(sp_, this);
59 return 0;
60 }
61
62 // cppcheck-suppress duplInheritedMember
63 void context_switch(Context& to) noexcept
64 {
66
67 if(zth_sjlj_setjmp(m_env) == 0) {
68 context_prepare_jmp(to, to.m_env);
69 zth_sjlj_longjmp(to.m_env, 1);
70 }
71
73 }
74
75private:
76 jmp_buf_type m_env;
77};
78
79} // namespace zth
80#endif // __cplusplus
81#endif // ZTH_CONTEXT_SJLJ_H
int create() noexcept
Definition sjlj.h:44
ContextArch< Context > base
Definition sjlj.h:23
impl::ContextArch< Context > base
Definition sigaltstack.h:60
void context_switch(Context &to) noexcept
Definition sjlj.h:63
sigjmp_buf m_env
constexpr Context(ContextAttr const &attr) noexcept
Definition sjlj.h:25
static void * sp() noexcept
Definition arch_arm.h:116
static void stack_push(void **&sp, void *p) noexcept
Push data into the stack.
void context_pop_regs() noexcept
Post-sjlj context restoring.
Definition context.h:499
Stack const & stack() const noexcept
Return the stack address.
Definition context.h:249
static void set_sp(jmp_buf &env, void **sp) noexcept
Set the stack pointer in a jmp_buf.
void context_prepare_jmp(Impl &to, jmp_buf &env) noexcept
Pre-sjlj jump.
Definition context.h:505
static void set_pc(jmp_buf &env, void *sp) noexcept
Set the program counter in a jmp_buf.
int create() noexcept
Create context.
Definition context.h:159
ContextAttr & attr() noexcept
Return the context attributes, requested by the user.
Definition context.h:143
static void context_trampoline_from_jmp_buf() noexcept
Entry point to jump to from a (sig)jmp_buf.
Stack const & stackUsable() const noexcept
Return the start of the actual usable stack.
Definition context.h:257
void context_push_regs() noexcept
Pre-sjlj context saving.
Definition context.h:494
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
Definition allocator.h:143
#define zth_sjlj_setjmp(env)
Definition sjlj.h:38
#define zth_sjlj_longjmp(env, val)
Definition sjlj.h:39
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.
Definition util.h:55