You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.7 KiB

#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));
}