refactor: move mcontext_restore to arch_context

main
Sean McBride 4 years ago
parent d1f80d8b1e
commit 2b161f2f86

@ -4,6 +4,8 @@
#include <unistd.h> #include <unistd.h>
#include <ucontext.h> #include <ucontext.h>
#include "arch_context.h"
#define ARCH_NREGS (2) /* SP + PC only */ #define ARCH_NREGS (2) /* SP + PC only */
#define ARCH_SIG_JMP_OFF 0x100 /* Based on code generated! */ #define ARCH_SIG_JMP_OFF 0x100 /* Based on code generated! */
@ -18,7 +20,6 @@ struct arch_context {
mcontext_t mctx; mcontext_t mctx;
}; };
extern void __attribute__((noreturn)) worker_thread_mcontext_restore(void);
extern __thread struct arch_context worker_thread_base_context; extern __thread struct arch_context worker_thread_base_context;
/* Initialized a context, zeroing out registers and setting the Instruction and Stack pointers */ /* 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" ".align 8\n\t"
"exit%=:\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", : "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", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26",
"d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15"); "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15");

@ -7,6 +7,7 @@
#include <ucontext.h> #include <ucontext.h>
#include <unistd.h> #include <unistd.h>
#include "arch_context.h"
#include "software_interrupt.h" #include "software_interrupt.h"
#define ARCH_SIG_JMP_OFF 8 #define ARCH_SIG_JMP_OFF 8
@ -31,7 +32,6 @@ struct arch_context {
mcontext_t mctx; mcontext_t mctx;
}; };
extern void __attribute__((noreturn)) worker_thread_mcontext_restore(void);
extern __thread struct arch_context worker_thread_base_context; 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) 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 * Slow Path
* If the stack pointer equaled 0, that means the sandbox was preempted and we need to * 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 * 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. * executes the mcontext-based context switch.
*/ */
"1:\n\t" "1:\n\t"
"call worker_thread_mcontext_restore\n\t" "call arch_context_mcontext_restore\n\t"
".align 8\n\t" ".align 8\n\t"
/* /*

@ -0,0 +1 @@
void __attribute__((noinline)) __attribute__((noreturn)) arch_context_mcontext_restore(void);

@ -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_block_current_sandbox(void);
extern void worker_thread_on_sandbox_exit(struct sandbox *sandbox); extern void worker_thread_on_sandbox_exit(struct sandbox *sandbox);
extern void worker_thread_process_io(void); 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); extern void worker_thread_wakeup_sandbox(struct sandbox *sandbox);
/*************************** /***************************

@ -0,0 +1,18 @@
#include <signal.h>
#include <pthread.h>
#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.. */
}

@ -142,19 +142,6 @@ worker_thread_process_io(void)
#endif #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 * Run all outstanding events in the local thread's libuv event loop
*/ */

Loading…
Cancel
Save