37#if defined(__clang__) || defined(__GNUC__)
38#if defined(__arm__) || defined(__aarch64__)
39#define MKJMP_SET_SP(sp, size) \
40 __asm__("mov sp, %0" ::"r"((char *)(sp) + (size)))
41#elif defined(__i386__)
42#define MKJMP_SET_SP(sp, size) \
43 __asm__("movl %0, %%esp" ::"r"((char *)(sp) + (size)))
44#elif defined(__x86_64__)
45#define MKJMP_SET_SP(sp, size) \
46 __asm__("movq %0, %%rsp" ::"r"((char *)(sp) + (size)))
48#elif defined(_MSC_VER)
50#define MKJMP_SET_SP(sp, size) \
51 void *_sp = (char *)(sp) + (size); \
54#define MKJMP_SET_SP(sp, size) \
55 void *_sp = (char *)(sp) + (size); \
61#error Unsupported compiler or architecture for mkjmp()/sigmkjmp().
67static thread_local struct {
75static _Noreturn void ctx_init(
void *sp,
size_t size);
78#if _POSIX_C_SOURCE >= 200112L && (!defined(__NEWLIB__) || defined(__CYGWIN__))
83static thread_local struct {
92static _Noreturn void sigctx_init(
void *sp,
size_t size);
98mkjmp(jmp_buf env,
void (*func)(
void *),
void *arg,
void *sp,
size_t size)
104 if (!setjmp(ctx.env))
110#if _POSIX_C_SOURCE >= 200112L && (!defined(__NEWLIB__) || defined(__CYGWIN__))
113sigmkjmp(sigjmp_buf env,
int savemask,
void (*func)(
void *),
void *arg,
114 void *sp,
size_t size)
117 sigctx.savemask = savemask;
121 if (!sigsetjmp(sigctx.env, 0))
122 sigctx_init(sp, size);
130ctx_init(
void *sp,
size_t size)
135 MKJMP_SET_SP(sp, size);
146 void (*func)(
void *) = ctx.func;
150 if (!setjmp(ctx.penv))
168#if _POSIX_C_SOURCE >= 200112L && (!defined(__NEWLIB__) || defined(__CYGWIN__))
171sigctx_init(
void *sp,
size_t size)
176 MKJMP_SET_SP(sp, size);
187 void (*func)(
void *) = sigctx.func;
188 void *arg = sigctx.arg;
192 if (!sigsetjmp(sigctx.penv, sigctx.savemask))
193 siglongjmp(sigctx.env, 1);
#define _Noreturn
A function declared with a _Noreturn function specifier SHALL not return to its caller.
int mkjmp(jmp_buf env, void(*func)(void *), void *arg, void *sp, size_t size)
Creates and stores a calling environment with a user-provided stack suitable for use by longjmp().
int sigmkjmp(sigjmp_buf env, int savemask, void(*func)(void *), void *arg, void *sp, size_t size)
Creates and stores a calling environment with a user-provided stack suitable for use by siglongjmp().
This header file is part of the utilities library; it contains the mkjmp() and sigmkjmp() function de...
This is the internal header file of the utilities library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <threads....
_Noreturn void thrd_exit(int res)
Terminates execution of the calling thread and sets its result code to res.