chore: combine thread locals into struct

main
Sean McBride 4 years ago
parent b822f82584
commit 68e91a8853

@ -1,5 +1,5 @@
/* https://github.com/gwsystems/silverfish/blob/master/runtime/memory/64bit_nix.c */
#include <types.h>
#include "types.h"
#ifdef USE_MEM_VM
@ -7,7 +7,7 @@
INLINE float
get_f32(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
return *(float *)address;
@ -16,7 +16,7 @@ get_f32(i32 offset)
INLINE double
get_f64(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
return *(double *)address;
@ -25,7 +25,7 @@ get_f64(i32 offset)
INLINE i8
get_i8(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
return *(i8 *)address;
@ -34,7 +34,7 @@ get_i8(i32 offset)
INLINE i16
get_i16(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
return *(i16 *)address;
@ -43,7 +43,7 @@ get_i16(i32 offset)
INLINE i32
get_i32(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
return *(i32 *)address;
@ -52,7 +52,7 @@ get_i32(i32 offset)
INLINE i64
get_i64(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
return *(i64 *)address;
@ -61,7 +61,7 @@ get_i64(i32 offset)
INLINE i32
get_global_i32(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
return *(i32 *)address;
@ -70,7 +70,7 @@ get_global_i32(i32 offset)
INLINE i64
get_global_i64(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
return *(i64 *)address;
@ -80,7 +80,7 @@ get_global_i64(i32 offset)
INLINE void
set_f32(i32 offset, float v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
*(float *)address = v;
@ -89,7 +89,7 @@ set_f32(i32 offset, float v)
INLINE void
set_f64(i32 offset, double v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
*(double *)address = v;
@ -98,7 +98,7 @@ set_f64(i32 offset, double v)
INLINE void
set_i8(i32 offset, i8 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
*(i8 *)address = v;
@ -107,7 +107,7 @@ set_i8(i32 offset, i8 v)
INLINE void
set_i16(i32 offset, i16 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
*(i16 *)address = v;
@ -116,7 +116,7 @@ set_i16(i32 offset, i16 v)
INLINE void
set_i32(i32 offset, i32 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
*(i32 *)address = v;
@ -125,7 +125,7 @@ set_i32(i32 offset, i32 v)
INLINE void
set_i64(i32 offset, i64 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
*(i64 *)address = v;
@ -134,7 +134,7 @@ set_i64(i32 offset, i64 v)
INLINE void
set_global_i32(i32 offset, i32 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
*(i32 *)address = v;
@ -143,7 +143,7 @@ set_global_i32(i32 offset, i32 v)
INLINE void
set_global_i64(i32 offset, i64 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
void *address = &mem_as_chars[offset];
*(i64 *)address = v;
@ -155,7 +155,7 @@ get_function_from_table(u32 idx, u32 type_id)
{
assert(idx < INDIRECT_TABLE_SIZE);
struct indirect_table_entry f = module_indirect_table[idx];
struct indirect_table_entry f = local_sandbox_member_cache.module_indirect_table[idx];
// assert(f.type_id == type_id);
assert(f.func_pointer);

@ -73,11 +73,14 @@ struct indirect_table_entry {
void *func_pointer;
};
extern __thread struct indirect_table_entry *module_indirect_table;
/* Cache of Frequently Accessed Members used to avoid pointer chasing */
struct sandbox_member_cache {
struct indirect_table_entry *module_indirect_table;
void * linear_memory_start;
u32 linear_memory_size;
};
/* for sandbox linear memory isolation */
extern __thread void *sandbox_lmbase;
extern __thread u32 sandbox_lmbound;
extern __thread struct sandbox_member_cache local_sandbox_member_cache;
/* TODO: LOG_TO_FILE logic is untested */
extern i32 runtime_log_file_descriptor;

@ -1,8 +1,15 @@
#include "current_sandbox.h"
#include "types.h"
/* current sandbox that is active.. */
static __thread sandbox_t *worker_thread_current_sandbox = NULL;
__thread struct sandbox_member_cache local_sandbox_member_cache = {
.linear_memory_start = NULL,
.linear_memory_size = 0,
.module_indirect_table = NULL,
};
/**
* Getter for the current sandbox executing on this thread
* @returns the current sandbox executing on this thread
@ -22,15 +29,19 @@ current_sandbox_set(struct sandbox *sandbox)
{
/* Unpack hierarchy to avoid pointer chasing */
if (sandbox == NULL) {
local_sandbox_member_cache = (struct sandbox_member_cache){
.linear_memory_start = NULL,
.linear_memory_size = 0,
.module_indirect_table = NULL,
};
worker_thread_current_sandbox = NULL;
sandbox_lmbase = NULL;
sandbox_lmbound = 0;
module_indirect_table = NULL;
} else {
local_sandbox_member_cache = (struct sandbox_member_cache){
.linear_memory_start = sandbox->linear_memory_start,
.linear_memory_size = sandbox->linear_memory_size,
.module_indirect_table = sandbox->module->indirect_table,
};
worker_thread_current_sandbox = sandbox;
sandbox_lmbase = sandbox->linear_memory_start;
sandbox_lmbound = sandbox->linear_memory_size;
module_indirect_table = sandbox->module->indirect_table;
}
}

@ -1,9 +1,11 @@
#include <runtime.h>
#include <worker_thread.h>
#include <sandbox.h>
#include <uv.h>
#include <http_request.h>
#include <current_sandbox.h>
#include "current_sandbox.h"
#include "http_request.h"
#include "runtime.h"
#include "sandbox.h"
#include "types.h"
#include "worker_thread.h"
// What should we tell the child program its UID and GID are?
#define UID 0xFF
@ -462,7 +464,7 @@ wasm_mmap(i32 addr, i32 len, i32 prot, i32 flags, i32 file_descriptor, i32 offse
assert(len % WASM_PAGE_SIZE == 0);
i32 result = sandbox_lmbound;
i32 result = local_sandbox_member_cache.linear_memory_size;
for (int i = 0; i < len / WASM_PAGE_SIZE; i++) { expand_memory(); }
return result;

@ -1,7 +1,8 @@
/* Code from https://github.com/gwsystems/silverfish/blob/master/runtime/memory/64bit_nix.c */
#include <runtime.h>
#include <sandbox.h>
#include <current_sandbox.h>
#include "current_sandbox.h"
#include "runtime.h"
#include "sandbox.h"
#include "types.h"
#ifdef USE_MEM_VM
@ -27,10 +28,11 @@ expand_memory(void)
struct sandbox *sandbox = current_sandbox_get();
// max_pages = 0 => no limit: FIXME
assert((sandbox->sandbox_size + sandbox_lmbound) / WASM_PAGE_SIZE < WASM_MAX_PAGES);
assert((sandbox->sandbox_size + local_sandbox_member_cache.linear_memory_size) / WASM_PAGE_SIZE
< WASM_MAX_PAGES);
// Remap the relevant wasm page to readable
char *mem_as_chars = sandbox_lmbase;
char *page_address = &mem_as_chars[sandbox_lmbound];
char *mem_as_chars = local_sandbox_member_cache.linear_memory_start;
char *page_address = &mem_as_chars[local_sandbox_member_cache.linear_memory_size];
void *map_result = mmap(page_address, WASM_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
@ -40,12 +42,13 @@ expand_memory(void)
}
// TODO: check sandbox->linear_memory_max_size
if (sandbox_lmbound > sandbox->linear_memory_max_size) {
if (local_sandbox_member_cache.linear_memory_size > sandbox->linear_memory_max_size) {
printf("expand_memory - Out of Memory!\n");
exit(EXIT_FAILURE);
}
sandbox_lmbound += WASM_PAGE_SIZE;
sandbox->linear_memory_size = sandbox_lmbound;
local_sandbox_member_cache.linear_memory_size += WASM_PAGE_SIZE;
// local_sandbox_member_cache is "forked state", so update authoritative member
sandbox->linear_memory_size = local_sandbox_member_cache.linear_memory_size;
}
INLINE char *
@ -54,9 +57,10 @@ get_memory_ptr_for_runtime(u32 offset, u32 bounds_check)
// Due to how we setup memory for x86, the virtual memory mechanism will catch the error, if bounds <
// WASM_PAGE_SIZE
assert(bounds_check < WASM_PAGE_SIZE
|| (sandbox_lmbound > bounds_check && offset <= sandbox_lmbound - bounds_check));
|| (local_sandbox_member_cache.linear_memory_size > bounds_check
&& offset <= local_sandbox_member_cache.linear_memory_size - bounds_check));
char *mem_as_chars = (char *)sandbox_lmbase;
char *mem_as_chars = (char *)local_sandbox_member_cache.linear_memory_start;
char *address = &mem_as_chars[offset];
return address;

@ -1,15 +1,12 @@
#include <runtime.h>
__thread struct indirect_table_entry *module_indirect_table = NULL;
__thread void * sandbox_lmbase = NULL;
__thread u32 sandbox_lmbound = 0;
#include "runtime.h"
#include "types.h"
/* Region initialization helper function */
EXPORT void
initialize_region(u32 offset, u32 data_count, char *data)
{
assert(sandbox_lmbound >= data_count);
assert(offset < sandbox_lmbound - data_count);
assert(local_sandbox_member_cache.linear_memory_size >= data_count);
assert(offset < local_sandbox_member_cache.linear_memory_size - data_count);
/* FIXME: Hack around segmented and unsegmented access */
memcpy(get_memory_ptr_for_runtime(offset, data_count), data, data_count);
@ -19,11 +16,16 @@ void
add_function_to_table(u32 idx, u32 type_id, char *pointer)
{
assert(idx < INDIRECT_TABLE_SIZE);
assert(local_sandbox_member_cache.module_indirect_table != NULL);
/* TODO: atomic for multiple concurrent invocations? */
if (module_indirect_table[idx].type_id == type_id && module_indirect_table[idx].func_pointer == pointer) return;
if (local_sandbox_member_cache.module_indirect_table[idx].type_id == type_id
&& local_sandbox_member_cache.module_indirect_table[idx].func_pointer == pointer)
return;
module_indirect_table[idx] = (struct indirect_table_entry){ .type_id = type_id, .func_pointer = pointer };
local_sandbox_member_cache.module_indirect_table[idx] = (struct indirect_table_entry){
.type_id = type_id, .func_pointer = pointer
};
}
/* If we are using runtime globals, we need to populate them */

@ -4,9 +4,10 @@
#include <stdlib.h>
#include <uv.h>
#include <module.h>
#include <module_database.h>
#include <runtime.h>
#include "types.h"
#include "module.h"
#include "module_database.h"
#include "runtime.h"
/*************************
* Private Static Inline *
@ -148,20 +149,22 @@ module_new(char *name, char *path, i32 argument_count, u32 stack_size, u32 max_m
module->max_request_or_response_size = round_up_to_page(response_size);
}
/* module_indirect_table is a thread-local struct */
struct indirect_table_entry *cache_tbl = module_indirect_table;
/* assumption: All modules are created at program start before we enable preemption or enable the execution
of any worker threads We are checking that thread-local module_indirect_table is NULL to prove that we aren't
yet preempting If we want to be able to do this later, we can possibly defer module_initialize_table until
the first invocation */
assert(cache_tbl == NULL);
/* 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 module_indirect_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 local_sandbox_member_cache.module_indirect_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
*/
/* TODO: determine why we have to set the module_indirect_table state before calling table init and then
* restore the existing value. What is the relationship between these things? */
module_indirect_table = module->indirect_table;
assert(local_sandbox_member_cache.module_indirect_table == NULL);
local_sandbox_member_cache.module_indirect_table = module->indirect_table;
module_initialize_table(module);
module_indirect_table = cache_tbl;
local_sandbox_member_cache.module_indirect_table = NULL;
/* Add the module to the in-memory module DB */
module_database_add(module);

@ -1,14 +1,16 @@
#include <assert.h>
#include <runtime.h>
#include <worker_thread.h>
#include <sandbox.h>
#include <sys/mman.h>
#include <pthread.h>
#include <signal.h>
#include <uv.h>
#include <libuv_callbacks.h>
#include <current_sandbox.h>
#include <http_parser_settings.h>
#include "current_sandbox.h"
#include "http_parser_settings.h"
#include "libuv_callbacks.h"
#include "runtime.h"
#include "sandbox.h"
#include "types.h"
#include "worker_thread.h"
/**
* Takes the arguments from the sandbox struct and writes them into the WebAssembly linear memory
@ -21,8 +23,8 @@ sandbox_setup_arguments(struct sandbox *sandbox)
i32 argument_count = module_get_argument_count(sandbox->module);
/* whatever gregor has, to be able to pass arguments to a module! */
sandbox->arguments_offset = sandbox_lmbound;
assert(sandbox_lmbase == sandbox->linear_memory_start);
sandbox->arguments_offset = local_sandbox_member_cache.linear_memory_size;
assert(local_sandbox_member_cache.linear_memory_start == sandbox->linear_memory_start);
expand_memory();
i32 *array_ptr = worker_thread_get_memory_ptr_void(sandbox->arguments_offset, argument_count * sizeof(i32));

Loading…
Cancel
Save