diff --git a/runtime/include/arch/aarch64/context.h b/runtime/include/arch/aarch64/context.h index 8e482f1..4abb962 100644 --- a/runtime/include/arch/aarch64/context.h +++ b/runtime/include/arch/aarch64/context.h @@ -4,6 +4,8 @@ #include #include +#include "arch_context.h" + #define ARCH_NREGS (2) /* SP + PC only */ #define ARCH_SIG_JMP_OFF 0x100 /* Based on code generated! */ @@ -18,7 +20,6 @@ struct arch_context { mcontext_t mctx; }; -extern void __attribute__((noreturn)) worker_thread_mcontext_restore(void); extern __thread struct arch_context worker_thread_base_context; /* Initialized a context, zeroing out registers and setting the Instruction and Stack pointers */ @@ -104,7 +105,7 @@ arch_context_switch(struct arch_context *ca, struct arch_context *na) ".align 8\n\t" "exit%=:\n\t" : - : [ curr ] "r"(cr), [ next ] "r"(nr), [ slowpath ] "r"(&worker_thread_mcontext_restore) + : [ curr ] "r"(cr), [ next ] "r"(nr), [ slowpath ] "r"(&arch_context_mcontext_restore) : "memory", "cc", "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15"); diff --git a/runtime/include/arch/x86_64/context.h b/runtime/include/arch/x86_64/context.h index a68affd..9cd7a04 100644 --- a/runtime/include/arch/x86_64/context.h +++ b/runtime/include/arch/x86_64/context.h @@ -7,6 +7,7 @@ #include #include +#include "arch_context.h" #include "software_interrupt.h" #define ARCH_SIG_JMP_OFF 8 @@ -31,7 +32,6 @@ struct arch_context { mcontext_t mctx; }; -extern void __attribute__((noreturn)) worker_thread_mcontext_restore(void); extern __thread struct arch_context worker_thread_base_context; static void __attribute__((noinline)) arch_context_init(struct arch_context *actx, reg_t ip, reg_t sp) @@ -162,11 +162,11 @@ arch_context_switch(struct arch_context *current, struct arch_context *next) * Slow Path * If the stack pointer equaled 0, that means the sandbox was preempted and we need to * fallback to a full mcontext-based context switch. We do this by invoking - * worker_thread_mcontext_restore, which fires a SIGUSR1 signal. The SIGUSR1 signal handler + * arch_context_mcontext_restore, which fires a SIGUSR1 signal. The SIGUSR1 signal handler * executes the mcontext-based context switch. */ "1:\n\t" - "call worker_thread_mcontext_restore\n\t" + "call arch_context_mcontext_restore\n\t" ".align 8\n\t" /* diff --git a/runtime/include/arch_context.h b/runtime/include/arch_context.h new file mode 100644 index 0000000..a52d77f --- /dev/null +++ b/runtime/include/arch_context.h @@ -0,0 +1 @@ +void __attribute__((noinline)) __attribute__((noreturn)) arch_context_mcontext_restore(void); diff --git a/runtime/include/sandbox.h b/runtime/include/sandbox.h index a596ee2..7f66d84 100644 --- a/runtime/include/sandbox.h +++ b/runtime/include/sandbox.h @@ -86,7 +86,6 @@ extern __thread struct arch_context *worker_thread_next_context; extern void worker_thread_block_current_sandbox(void); extern void worker_thread_on_sandbox_exit(struct sandbox *sandbox); extern void worker_thread_process_io(void); -extern void __attribute__((noreturn)) worker_thread_mcontext_restore(void); extern void worker_thread_wakeup_sandbox(struct sandbox *sandbox); /*************************** diff --git a/runtime/src/arch_context.c b/runtime/src/arch_context.c new file mode 100644 index 0000000..c6776e9 --- /dev/null +++ b/runtime/src/arch_context.c @@ -0,0 +1,18 @@ +#include +#include + +#include "types.h" + +/** + * Called by the inline assembly in arch_context_switch to send a SIGUSR1 in order to restore a previously preempted + * thread. The only way to restore all of the mcontext registers of a preempted sandbox is to send ourselves a signal, + * then update the registers we should return to, then sigreturn (by returning from the handler). This returns to the + * control flow restored from the mcontext + */ +void __attribute__((noinline)) __attribute__((noreturn)) arch_context_mcontext_restore(void) +{ + debuglog("Thread %lu | Signaling SIGUSR1 on self to initiate mcontext restore...\n", pthread_self()); + pthread_kill(pthread_self(), SIGUSR1); + + assert(false); /* should not get here.. */ +} diff --git a/runtime/src/worker_thread.c b/runtime/src/worker_thread.c index c36fe33..066028b 100644 --- a/runtime/src/worker_thread.c +++ b/runtime/src/worker_thread.c @@ -142,19 +142,6 @@ worker_thread_process_io(void) #endif } -/** - * We need to switch back to a previously preempted thread. The only way to restore all of its registers is to use - * sigreturn. To get to sigreturn, we need to send ourselves a signal, then update the registers we should return to, - * then sigreturn (by returning from the handler). - */ -void __attribute__((noinline)) __attribute__((noreturn)) worker_thread_mcontext_restore(void) -{ - debuglog("Thread %lu | Signaling SIGUSR1 on self to initiate mcontext restore...\n", pthread_self()); - pthread_kill(pthread_self(), SIGUSR1); - - assert(false); /* should not get here.. */ -} - /** * Run all outstanding events in the local thread's libuv event loop */