refactor: Eliminate _new and _delete functions

master
Sean McBride 3 years ago
parent fdaff6c666
commit 35b83ba090

@ -8,12 +8,14 @@
#include "admissions_control.h"
#include "admissions_info.h"
#include "awsm_abi.h"
#include "current_wasm_module_instance.h"
#include "http.h"
#include "panic.h"
#include "pool.h"
#include "types.h"
#include "wasm_stack.h"
#include "wasm_memory.h"
#include "wasm_table.h"
#define MODULE_DEFAULT_REQUEST_RESPONSE_SIZE (PAGE_SIZE)
@ -22,8 +24,8 @@
extern thread_local int worker_thread_idx;
INIT_POOL(wasm_memory, wasm_memory_delete)
INIT_POOL(wasm_stack, wasm_stack_delete)
INIT_POOL(wasm_memory, wasm_memory_free)
INIT_POOL(wasm_stack, wasm_stack_free)
/*
* Defines the listen backlog, the queue length for completely established socketeds waiting to be accepted
@ -102,13 +104,50 @@ module_initialize_globals(struct module *module)
}
/**
* Invoke a module's initialize_tables
* @brief Invoke a module's initialize_tables
* @param module
*
* Table initialization calls a function that runs within the sandbox. Rather than setting the current sandbox,
* we partially fake this out by only setting the table and then clearing after table
* initialization is complete.
*
* assumption: This approach depends on module_alloc only being invoked at program start before preemption is
* enabled. We are check that current_wasm_module_instance.table is NULL to gain confidence that
* we are not invoking this in a way that clobbers a current module.
*
* If we want to be able to do this later, we can possibly defer module_initialize_table until the first
* invocation. Alternatively, we can maintain the table per sandbox and call initialize
* on each sandbox if this "assumption" is too restrictive and we're ready to pay a per-sandbox performance hit.
*/
static inline void
module_initialize_table(struct module *module)
{
assert(current_wasm_module_instance.table == NULL);
current_wasm_module_instance.table = module->indirect_table;
module->abi.initialize_tables();
current_wasm_module_instance.table = NULL;
}
static inline int
module_alloc_table(struct module *module)
{
/* WebAssembly Indirect Table */
/* TODO: Should this be part of the module or per-sandbox? */
/* TODO: How should this table be sized? */
module->indirect_table = wasm_table_alloc(INDIRECT_TABLE_SIZE);
if (module->indirect_table == NULL) return -1;
module_initialize_table(module);
return 0;
}
static inline void
module_initialize_pools(struct module *module)
{
for (int i = 0; i < MAX_WORKER_THREADS; i++) {
wasm_memory_pool_init(&module->pools[i].memory, false);
wasm_stack_pool_init(&module->pools[i].stack, false);
}
}
/**
@ -166,7 +205,7 @@ module_allocate_stack(struct module *module)
struct wasm_stack *stack = wasm_stack_pool_remove_nolock(&module->pools[worker_thread_idx].stack);
if (stack == NULL) {
stack = wasm_stack_new(module->stack_size);
stack = wasm_stack_alloc(module->stack_size);
if (unlikely(stack == NULL)) return NULL;
}
@ -193,7 +232,7 @@ module_allocate_linear_memory(struct module *module)
struct wasm_memory *linear_memory = wasm_memory_pool_remove_nolock(&module->pools[worker_thread_idx].memory);
if (linear_memory == NULL) {
linear_memory = wasm_memory_new(initial, max);
linear_memory = wasm_memory_alloc(initial, max);
if (unlikely(linear_memory == NULL)) return NULL;
}
@ -212,6 +251,6 @@ module_free_linear_memory(struct module *module, struct wasm_memory *memory)
*******************************/
void module_free(struct module *module);
struct module *module_new(char *mod_name, char *mod_path, uint32_t stack_sz, uint32_t relative_deadline_us, int port,
struct module *module_alloc(char *mod_name, char *mod_path, uint32_t stack_sz, uint32_t relative_deadline_us, int port,
int req_sz, int resp_sz, int admissions_percentile, uint32_t expected_execution_us);
int module_new_from_json(char *filename);
int module_alloc_from_json(char *filename);

@ -12,7 +12,7 @@
* Public API *
**************************/
struct sandbox *sandbox_new(struct module *module, int socket_descriptor, const struct sockaddr *socket_address,
struct sandbox *sandbox_alloc(struct module *module, int socket_descriptor, const struct sockaddr *socket_address,
uint64_t request_arrival_timestamp, uint64_t admissions_estimate);
int sandbox_prepare_execution_environment(struct sandbox *sandbox);
void sandbox_free(struct sandbox *sandbox);
@ -43,11 +43,11 @@ sandbox_free_linear_memory(struct sandbox *sandbox)
}
/**
* Free Linear Memory, leaving stack in place
* Deinitialize Linear Memory, cleaning up the backing buffer
* @param sandbox
*/
static inline void
sandbox_free_http_buffers(struct sandbox *sandbox)
sandbox_deinit_http_buffers(struct sandbox *sandbox)
{
assert(sandbox);
vec_u8_deinit(&sandbox->request);

@ -38,7 +38,7 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state)
case SANDBOX_RUNNING_SYS: {
local_runqueue_delete(sandbox);
sandbox_free_linear_memory(sandbox);
sandbox_free_http_buffers(sandbox);
sandbox_deinit_http_buffers(sandbox);
break;
}
default: {

@ -33,7 +33,7 @@ sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state)
sandbox->total_time = now - sandbox->timestamp_of.request_arrival;
local_runqueue_delete(sandbox);
sandbox_free_linear_memory(sandbox);
sandbox_free_http_buffers(sandbox);
sandbox_deinit_http_buffers(sandbox);
break;
}
default: {

@ -9,22 +9,10 @@ struct vec_u8 {
uint8_t *buffer; /* Backing heap allocation. Different lifetime because realloc might move this */
};
static inline struct vec_u8 *vec_u8_alloc(void);
static inline int vec_u8_init(struct vec_u8 *vec_u8, size_t capacity);
static inline struct vec_u8 *vec_u8_new(size_t capacity);
static inline struct vec_u8 *vec_u8_alloc(size_t capacity);
static inline void vec_u8_deinit(struct vec_u8 *vec_u8);
static inline void vec_u8_free(struct vec_u8 *vec_u8);
static inline void vec_u8_delete(struct vec_u8 *vec_u8);
/**
* Allocates an uninitialized vec on the heap'
* @returns a pointer to an uninitialized vec on the heap
*/
static inline struct vec_u8 *
vec_u8_alloc(void)
{
return (struct vec_u8 *)calloc(1, sizeof(struct vec_u8));
}
/**
* Initializes a vec, allocating a backing buffer for the provided capcity
@ -54,9 +42,9 @@ vec_u8_init(struct vec_u8 *vec_u8, size_t capacity)
* @returns a pointer to an initialized vec on the heap, ready for use
*/
static inline struct vec_u8 *
vec_u8_new(size_t capacity)
vec_u8_alloc(size_t capacity)
{
struct vec_u8 *vec_u8 = vec_u8_alloc();
struct vec_u8 *vec_u8 = (struct vec_u8 *)malloc(sizeof(struct vec_u8));
if (vec_u8 == NULL) return vec_u8;
int rc = vec_u8_init(vec_u8, capacity);
@ -88,26 +76,13 @@ vec_u8_deinit(struct vec_u8 *vec_u8)
vec_u8->capacity = 0;
}
/**
* Frees a vec struct allocated on the heap
* Assumes that the vec has already been deinitialized
*/
static inline void
vec_u8_free(struct vec_u8 *vec_u8)
{
assert(vec_u8->buffer == NULL);
assert(vec_u8->length == 0);
assert(vec_u8->capacity == 0);
free(vec_u8);
}
/**
* Deinitializes and frees a vec allocated to the heap
* @param vec_u8
*/
static inline void
vec_u8_delete(struct vec_u8 *vec_u8)
vec_u8_free(struct vec_u8 *vec_u8)
{
vec_u8_deinit(vec_u8);
vec_u8_free(vec_u8);
free(vec_u8);
}

@ -22,18 +22,51 @@ struct wasm_memory {
uint8_t * buffer; /* Backing heap allocation. Different lifetime because realloc might move this */
};
static INLINE struct wasm_memory *wasm_memory_alloc(void);
/* Object Lifecycle Functions */
static INLINE struct wasm_memory *wasm_memory_alloc(size_t initial, size_t max);
static INLINE int wasm_memory_init(struct wasm_memory *wasm_memory, size_t initial, size_t max);
static INLINE struct wasm_memory *wasm_memory_new(size_t initial, size_t max);
static INLINE void wasm_memory_deinit(struct wasm_memory *wasm_memory);
static INLINE void wasm_memory_free(struct wasm_memory *wasm_memory);
static INLINE void wasm_memory_delete(struct wasm_memory *wasm_memory);
static INLINE void wasm_memory_reinit(struct wasm_memory *wasm_memory, size_t initial);
/* Memory Size */
static INLINE int wasm_memory_expand(struct wasm_memory *wasm_memory, size_t size_to_expand);
static INLINE size_t wasm_memory_get_size(struct wasm_memory *wasm_memory);
static INLINE uint32_t wasm_memory_get_page_count(struct wasm_memory *wasm_memory);
/* Reading and writing to wasm_memory */
static INLINE void
wasm_memory_initialize_region(struct wasm_memory *wasm_memory, uint32_t offset, uint32_t region_size, uint8_t region[]);
static INLINE void * wasm_memory_get_ptr_void(struct wasm_memory *wasm_memory, uint32_t offset, uint32_t size);
static INLINE int8_t wasm_memory_get_i8(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE int16_t wasm_memory_get_i16(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE int32_t wasm_memory_get_i32(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE int64_t wasm_memory_get_i64(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE float wasm_memory_get_f32(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE double wasm_memory_get_f64(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE char wasm_memory_get_char(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE char * wasm_memory_get_string(struct wasm_memory *wasm_memory, uint32_t offset, uint32_t size);
static INLINE void wasm_memory_set_i8(struct wasm_memory *wasm_memory, uint32_t offset, int8_t value);
static INLINE void wasm_memory_set_i16(struct wasm_memory *wasm_memory, uint32_t offset, int16_t value);
static INLINE void wasm_memory_set_i32(struct wasm_memory *wasm_memory, uint32_t offset, int32_t value);
static INLINE void wasm_memory_set_i64(struct wasm_memory *wasm_memory, uint64_t offset, int64_t value);
static INLINE void wasm_memory_set_f32(struct wasm_memory *wasm_memory, uint32_t offset, float value);
static INLINE void wasm_memory_set_f64(struct wasm_memory *wasm_memory, uint32_t offset, double value);
static INLINE struct wasm_memory *
wasm_memory_alloc(void)
wasm_memory_alloc(size_t initial, size_t max)
{
return malloc(sizeof(struct wasm_memory));
struct wasm_memory *wasm_memory = malloc(sizeof(struct wasm_memory));
if (wasm_memory == NULL) return wasm_memory;
int rc = wasm_memory_init(wasm_memory, initial, max);
if (rc < 0) {
assert(0);
wasm_memory_free(wasm_memory);
return NULL;
}
return wasm_memory;
}
static INLINE int
@ -68,22 +101,6 @@ wasm_memory_init(struct wasm_memory *wasm_memory, size_t initial, size_t max)
return 0;
}
static INLINE struct wasm_memory *
wasm_memory_new(size_t initial, size_t max)
{
struct wasm_memory *wasm_memory = wasm_memory_alloc();
if (wasm_memory == NULL) return wasm_memory;
int rc = wasm_memory_init(wasm_memory, initial, max);
if (rc < 0) {
assert(0);
wasm_memory_free(wasm_memory);
return NULL;
}
return wasm_memory;
}
static INLINE void
wasm_memory_deinit(struct wasm_memory *wasm_memory)
{
@ -101,31 +118,14 @@ static INLINE void
wasm_memory_free(struct wasm_memory *wasm_memory)
{
assert(wasm_memory != NULL);
/* Assume prior deinitialization so we don't leak buffers */
assert(wasm_memory->buffer == NULL);
free(wasm_memory);
}
static INLINE void
wasm_memory_delete(struct wasm_memory *wasm_memory)
{
assert(wasm_memory != NULL);
wasm_memory_deinit(wasm_memory);
wasm_memory_free(wasm_memory);
}
static INLINE void
wasm_memory_wipe(struct wasm_memory *wasm_memory)
{
memset(wasm_memory->buffer, 0, wasm_memory->size);
free(wasm_memory);
}
static INLINE void
wasm_memory_reinit(struct wasm_memory *wasm_memory, size_t initial)
{
wasm_memory_wipe(wasm_memory);
memset(wasm_memory->buffer, 0, wasm_memory->size);
wasm_memory->size = initial;
}
@ -158,12 +158,6 @@ wasm_memory_expand(struct wasm_memory *wasm_memory, size_t size_to_expand)
return 0;
}
static INLINE void
wasm_memory_set_size(struct wasm_memory *wasm_memory, size_t size)
{
wasm_memory->size = size;
}
static INLINE size_t
wasm_memory_get_size(struct wasm_memory *wasm_memory)
{

@ -7,7 +7,6 @@
#include "sandbox_types.h"
#include "types.h"
/**
* @brief wasm_stack is a stack used to execute an AOT-compiled WebAssembly instance. It is allocated with a static size
* and a guard page beneath the lowest usuable address. Because the stack grows down, this protects against stack
@ -29,11 +28,11 @@ struct wasm_stack {
uint8_t * buffer; /* Points base address of backing heap allocation (Guard Page) */
};
static inline struct wasm_stack *
wasm_stack_allocate(void)
{
return calloc(1, sizeof(struct wasm_stack));
}
static struct wasm_stack *wasm_stack_alloc(size_t capacity);
static inline int wasm_stack_init(struct wasm_stack *wasm_stack, size_t capacity);
static inline void wasm_stack_reinit(struct wasm_stack *wasm_stack);
static inline void wasm_stack_deinit(struct wasm_stack *wasm_stack);
static inline void wasm_stack_free(struct wasm_stack *wasm_stack);
/**
* Allocates a static sized stack for a sandbox with a guard page underneath
@ -79,17 +78,10 @@ err_stack_allocation_failed:
goto done;
}
static INLINE void
wasm_stack_free(struct wasm_stack *wasm_stack)
{
free(wasm_stack);
}
static struct wasm_stack *
wasm_stack_new(size_t capacity)
wasm_stack_alloc(size_t capacity)
{
struct wasm_stack *wasm_stack = wasm_stack_allocate();
struct wasm_stack *wasm_stack = calloc(1, sizeof(struct wasm_stack));
int rc = wasm_stack_init(wasm_stack, capacity);
if (rc < 0) {
wasm_stack_free(wasm_stack);
@ -113,12 +105,12 @@ wasm_stack_deinit(struct wasm_stack *wasm_stack)
}
static inline void
wasm_stack_delete(struct wasm_stack *wasm_stack)
wasm_stack_free(struct wasm_stack *wasm_stack)
{
assert(wasm_stack != NULL);
assert(wasm_stack->buffer != NULL);
wasm_stack_deinit(wasm_stack);
wasm_stack_free(wasm_stack);
free(wasm_stack);
}
static inline void

@ -20,18 +20,10 @@ struct wasm_table {
struct wasm_table_entry *buffer; /* Backing heap allocation */
};
static INLINE struct wasm_table *wasm_table_alloc(void);
static INLINE int wasm_table_init(struct wasm_table *wasm_table, size_t capacity);
static INLINE struct wasm_table *wasm_table_new(size_t capacity);
static INLINE struct wasm_table *wasm_table_alloc(size_t capacity);
static INLINE void wasm_table_deinit(struct wasm_table *wasm_table);
static INLINE void wasm_table_free(struct wasm_table *wasm_table);
static INLINE void wasm_table_delete(struct wasm_table *wasm_table);
static INLINE struct wasm_table *
wasm_table_alloc(void)
{
return (struct wasm_table *)malloc(sizeof(struct wasm_table));
}
static INLINE int
wasm_table_init(struct wasm_table *wasm_table, size_t capacity)
@ -50,9 +42,9 @@ wasm_table_init(struct wasm_table *wasm_table, size_t capacity)
}
static INLINE struct wasm_table *
wasm_table_new(size_t capacity)
wasm_table_alloc(size_t capacity)
{
struct wasm_table *wasm_table = wasm_table_alloc();
struct wasm_table *wasm_table = (struct wasm_table *)malloc(sizeof(struct wasm_table));
if (wasm_table == NULL) return NULL;
int rc = wasm_table_init(wasm_table, capacity);

@ -179,7 +179,7 @@ listener_thread_main(void *dummy)
}
/* Allocate a Sandbox */
struct sandbox *sandbox = sandbox_new(module, client_socket,
struct sandbox *sandbox = sandbox_alloc(module, client_socket,
(const struct sockaddr *)&client_address,
request_arrival_timestamp, work_admitted);
if (unlikely(sandbox == NULL)) {

@ -369,7 +369,7 @@ main(int argc, char **argv)
#ifdef LOG_MODULE_LOADING
debuglog("Parsing modules file [%s]\n", argv[1]);
#endif
if (module_new_from_json(argv[1])) panic("failed to initialize module(s) defined in %s\n", argv[1]);
if (module_alloc_from_json(argv[1])) panic("failed to initialize module(s) defined in %s\n", argv[1]);
for (int i = 0; i < runtime_worker_threads_count; i++) {

@ -126,53 +126,42 @@ module_free(struct module *module)
free(module);
}
/**
* Module Contructor
* Creates a new module, invokes initialize_tables to initialize the indirect table, adds it to the module DB, and
*starts listening for HTTP Requests
*
* @param name
* @param path
* @param stack_size
* @param relative_deadline_us
* @param port
* @param request_size
* @returns A new module or NULL in case of failure
*/
struct module *
module_new(char *name, char *path, uint32_t stack_size, uint32_t relative_deadline_us, int port, int request_size,
int response_size, int admissions_percentile, uint32_t expected_execution_us)
static inline int
module_init(struct module *module, char *name, char *path, uint32_t stack_size, uint32_t relative_deadline_us, int port,
int request_size, int response_size, int admissions_percentile, uint32_t expected_execution_us)
{
int rc = 0;
assert(module != NULL);
assert(name != NULL);
assert(strlen(name) > 0);
assert(strlen(name) < MODULE_MAX_NAME_LENGTH);
assert(path != NULL);
assert(strlen(path) > 0);
assert(strlen(path) < MODULE_MAX_PATH_LENGTH);
assert(stack_size > 0);
assert(relative_deadline_us > 0);
assert(relative_deadline_us < RUNTIME_RELATIVE_DEADLINE_US_MAX);
assert(port > 0);
assert(admissions_percentile > 0);
assert(expected_execution_us > 0);
struct module *module = (struct module *)calloc(1, sizeof(struct module));
if (!module) {
fprintf(stderr, "Failed to allocate module: %s\n", strerror(errno));
goto err;
};
int rc = 0;
atomic_init(&module->reference_count, 0);
rc = awsm_abi_init(&module->abi, path);
if (rc != 0) goto awsm_abi_init_err;
if (rc != 0) goto err;
/* Set fields in the module struct */
strncpy(module->name, name, MODULE_MAX_NAME_LENGTH);
strncpy(module->path, path, MODULE_MAX_PATH_LENGTH);
module->stack_size = ((uint32_t)(round_up_to_page(stack_size == 0 ? WASM_STACK_SIZE : stack_size)));
debuglog("Stack Size: %u", module->stack_size);
module->socket_descriptor = -1;
module->port = port;
/* Deadlines */
module->relative_deadline_us = relative_deadline_us;
/* This should have been handled when a module was loaded */
assert(relative_deadline_us < RUNTIME_RELATIVE_DEADLINE_US_MAX);
/* This can overflow a uint32_t, so be sure to cast appropriately */
module->relative_deadline = (uint64_t)relative_deadline_us * runtime_processor_speed_MHz;
@ -181,49 +170,58 @@ module_new(char *name, char *path, uint32_t stack_size, uint32_t relative_deadli
admissions_info_initialize(&module->admissions_info, admissions_percentile, expected_execution,
module->relative_deadline);
/* WebAssembly Indirect Table */
/* TODO: Should this be part of the module or per-sandbox? */
/* TODO: How should this table be sized? */
module->indirect_table = wasm_table_new(INDIRECT_TABLE_SIZE);
/* Request Response Buffer */
if (request_size == 0) request_size = MODULE_DEFAULT_REQUEST_RESPONSE_SIZE;
if (response_size == 0) response_size = MODULE_DEFAULT_REQUEST_RESPONSE_SIZE;
module->max_request_size = round_up_to_page(request_size);
module->max_response_size = round_up_to_page(response_size);
/* Table initialization calls a function that runs within the sandbox. Rather than setting the current sandbox,
* we partially fake this out by only setting the table and then clearing after table
* initialization is complete.
*
* assumption: This approach depends on module_new only being invoked at program start before preemption is
* enabled. We are check that current_wasm_module_instance.table is NULL to gain confidence that
* we are not invoking this in a way that clobbers a current module.
*
* If we want to be able to do this later, we can possibly defer module_initialize_table until the first
* invocation. Alternatively, we can maintain the table per sandbox and call initialize
* on each sandbox if this "assumption" is too restrictive and we're ready to pay a per-sandbox performance hit.
*/
module_alloc_table(module);
module_initialize_pools(module);
assert(current_wasm_module_instance.table == NULL);
current_wasm_module_instance.table = module->indirect_table;
module_initialize_table(module);
current_wasm_module_instance.table = NULL;
/* Start listening for requests */
rc = module_listen(module);
if (rc < 0) goto err;
for (int i = 0; i < MAX_WORKER_THREADS; i++) {
wasm_memory_pool_init(&module->pools[i].memory, false);
wasm_stack_pool_init(&module->pools[i].stack, false);
done:
return rc;
err:
rc = -1;
goto done;
}
/* Start listening for requests */
rc = module_listen(module);
if (rc < 0) goto err_listen;
/**
* Module Contructor
* Creates a new module, invokes initialize_tables to initialize the indirect table, adds it to the module DB, and
*starts listening for HTTP Requests
*
* @param name
* @param path
* @param stack_size
* @param relative_deadline_us
* @param port
* @param request_size
* @returns A new module or NULL in case of failure
*/
struct module *
module_alloc(char *name, char *path, uint32_t stack_size, uint32_t relative_deadline_us, int port, int request_size,
int response_size, int admissions_percentile, uint32_t expected_execution_us)
{
struct module *module = (struct module *)calloc(1, sizeof(struct module));
if (!module) {
fprintf(stderr, "Failed to allocate module: %s\n", strerror(errno));
goto err;
};
int rc = module_init(module, name, path, stack_size, relative_deadline_us, port, request_size, response_size,
admissions_percentile, expected_execution_us);
if (rc < 0) goto init_err;
done:
return module;
err_listen:
awsm_abi_init_err:
init_err:
free(module);
err:
module = NULL;
@ -236,7 +234,7 @@ err:
* @return RC 0 on Success. -1 on Error
*/
int
module_new_from_json(char *file_name)
module_alloc_from_json(char *file_name)
{
assert(file_name != NULL);
int return_code = -1;
@ -424,10 +422,10 @@ module_new_from_json(char *file_name)
#endif
/* Allocate a module based on the values from the JSON */
struct module *module = module_new(module_name, module_path, 0, relative_deadline_us, port,
struct module *module = module_alloc(module_name, module_path, 0, relative_deadline_us, port,
request_size, response_size, admissions_percentile,
expected_execution_us);
if (module == NULL) goto module_new_err;
if (module == NULL) goto module_alloc_err;
assert(module);
module_set_http_info(module, response_content_type);
@ -444,7 +442,7 @@ module_new_from_json(char *file_name)
done:
return return_code;
module_new_err:
module_alloc_err:
json_parse_err:
fclose_err:
/* We will retry fclose when we fall through into stat_buffer_alloc_err */

@ -82,15 +82,6 @@ sandbox_allocate_http_buffers(struct sandbox *sandbox)
return 0;
}
static inline struct sandbox *
sandbox_allocate(void)
{
struct sandbox *sandbox = NULL;
size_t page_aligned_sandbox_size = round_up_to_page(sizeof(struct sandbox));
sandbox = calloc(1, page_aligned_sandbox_size);
sandbox_set_as_allocated(sandbox);
return sandbox;
}
/**
* Allocates HTTP buffers and performs our approximation of "WebAssembly instantiation"
@ -180,12 +171,15 @@ sandbox_init(struct sandbox *sandbox, struct module *module, int socket_descript
* @return the new sandbox request
*/
struct sandbox *
sandbox_new(struct module *module, int socket_descriptor, const struct sockaddr *socket_address,
sandbox_alloc(struct module *module, int socket_descriptor, const struct sockaddr *socket_address,
uint64_t request_arrival_timestamp, uint64_t admissions_estimate)
{
struct sandbox *sandbox = sandbox_allocate();
assert(sandbox);
struct sandbox *sandbox = NULL;
size_t page_aligned_sandbox_size = round_up_to_page(sizeof(struct sandbox));
sandbox = calloc(1, page_aligned_sandbox_size);
if (unlikely(sandbox == NULL)) return NULL;
sandbox_set_as_allocated(sandbox);
sandbox_init(sandbox, module, socket_descriptor, socket_address, request_arrival_timestamp,
admissions_estimate);
@ -193,39 +187,33 @@ sandbox_new(struct module *module, int socket_descriptor, const struct sockaddr
return sandbox;
}
/**
* Free stack and heap resources.. also any I/O handles.
* @param sandbox
*/
void
sandbox_free(struct sandbox *sandbox)
sandbox_deinit(struct sandbox *sandbox)
{
assert(sandbox != NULL);
assert(sandbox != current_sandbox_get());
assert(sandbox->state == SANDBOX_ERROR || sandbox->state == SANDBOX_COMPLETE);
int rc;
module_release(sandbox->module);
/* Linear Memory and Guard Page should already have been munmaped and set to NULL */
assert(sandbox->memory == NULL);
/* Free Sandbox Struct and HTTP Request and Response Buffers */
/* Free Sandbox Struct*/
if (likely(sandbox->stack != NULL)) sandbox_free_stack(sandbox);
free(sandbox);
}
if (rc == -1) {
debuglog("Failed to unmap Sandbox %lu\n", sandbox->id);
goto err_free_sandbox_failed;
};
/**
* Free stack and heap resources.. also any I/O handles.
* @param sandbox
*/
void
sandbox_free(struct sandbox *sandbox)
{
assert(sandbox != NULL);
assert(sandbox != current_sandbox_get());
assert(sandbox->state == SANDBOX_ERROR || sandbox->state == SANDBOX_COMPLETE);
done:
return;
err_free_sandbox_failed:
err_free_stack_failed:
/* Errors freeing memory is a fatal error */
panic("Failed to free Sandbox %lu\n", sandbox->id);
sandbox_deinit(sandbox);
free(sandbox);
}

Loading…
Cancel
Save