#pragma once /* * This header is the single entry point into the arch_context code. * It includes processor independent code and conditionally includes architecture * dependent code. */ /* * These preprocessor conditionals load architecture-dependent code. * * Each of these headers include common.h, a sibling header that contains common * structures, enums, and externs used by the processor independent code. Those * definitions are thus transitively loaded here with the appropriate architecture * specific code. * * While the code in common.h could be located in this file above the conditionals, * structuring the code as such prevents IDEs from knowing how to resolve the * symbols when aarch64/context.h or x86_64/context is the active file. */ #if defined(AARCH64) || defined(aarch64) #include "aarch64/context.h" #elif defined(X86_64) || defined(x86_64) #include "x86_64/context.h" #else #warning "Architecture not set. Using x86_64" #define X86_64 #include "x86_64/context.h" #endif /** * Restore a full mcontext * Writes sandbox_context to active_context * active_context was saved to the stack by a signal handler * @param active_context - the context of the current worker thread * @param sandbox_context - the context that we want to restore */ static inline void arch_mcontext_restore(mcontext_t *active_context, struct arch_context *sandbox_context) { assert(!software_interrupt_is_enabled()); assert(active_context != NULL); assert(sandbox_context != NULL); /* Assumption: Base Context is only ever used by arch_context_switch */ assert(sandbox_context != &worker_thread_base_context); /* Transitioning from Slow -> Running */ assert(sandbox_context->variant == ARCH_CONTEXT_VARIANT_SLOW); sandbox_context->variant = ARCH_CONTEXT_VARIANT_RUNNING; /* Restore mcontext */ memcpy(active_context, &sandbox_context->mctx, sizeof(mcontext_t)); } /** * Save the full mcontext of the currently executing process * @param sandbox_context - destination * @param active_context - source */ static inline void arch_mcontext_save(struct arch_context *sandbox_context, const mcontext_t *active_context) { /* Assumption: Only called indirectly via signal handler, so interrupts should be disabled */ assert(!software_interrupt_is_enabled()); assert(sandbox_context != NULL); assert(active_context != NULL); /* Assumption: The base context should never be modified */ assert(sandbox_context != &worker_thread_base_context); /* Transitioning from {Unused, Running} -> Slow */ assert(sandbox_context->variant == ARCH_CONTEXT_VARIANT_UNUSED || sandbox_context->variant == ARCH_CONTEXT_VARIANT_RUNNING); sandbox_context->variant = ARCH_CONTEXT_VARIANT_SLOW; /* Copy mcontext */ memcpy(&sandbox_context->mctx, active_context, sizeof(mcontext_t)); }