chore: run clang-format

sledge_graph
Sean McBride 5 years ago
parent 2805934d49
commit c9b9a6553e

@ -6,7 +6,6 @@ Language: Cpp
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true AlignConsecutiveDeclarations: true
AlignConsecutiveMacros: true
AlignEscapedNewlines: Left AlignEscapedNewlines: Left
AlignTrailingComments: true AlignTrailingComments: true

@ -17,7 +17,7 @@ struct arch_context {
mcontext_t mctx; mcontext_t mctx;
}; };
typedef struct arch_context arch_context_t; typedef struct arch_context arch_context_t;
extern void __attribute__((noreturn)) worker_thread__sandbox_switch_preempt(void); extern void __attribute__((noreturn)) worker_thread__sandbox_switch_preempt(void);
extern __thread arch_context_t worker_thread__base_context; extern __thread arch_context_t worker_thread__base_context;

@ -28,8 +28,8 @@ current_sandbox__set(struct sandbox *sandbox)
if (sandbox == NULL) return; if (sandbox == NULL) return;
// Thread Local State about the Current Sandbox // Thread Local State about the Current Sandbox
sandbox_lmbase = sandbox->linear_memory_start; sandbox_lmbase = sandbox->linear_memory_start;
sandbox_lmbound = sandbox->linear_memory_size; sandbox_lmbound = sandbox->linear_memory_size;
module_indirect_table = sandbox->module->indirect_table; module_indirect_table = sandbox->module->indirect_table;
} }

@ -13,7 +13,8 @@
/** /**
* http-parser data callback called when a URL is called * http-parser data callback called when a URL is called
* Sanity check to make sure that the path matches the name of the module * Sanity check to make sure that the path matches the name of the module
* TODO: Why does this not fail this assertion? To execute fibonacci, I just request localhost:10000, not localhost:10000/fibonacci * TODO: Why does this not fail this assertion? To execute fibonacci, I just request localhost:10000, not
*localhost:10000/fibonacci
* @param parser * @param parser
* @param at the start of the URL * @param at the start of the URL
* @param length the length of the URL * @param length the length of the URL
@ -22,7 +23,7 @@
static inline int static inline int
http_parser_settings__on_url(http_parser *parser, const char *at, size_t length) http_parser_settings__on_url(http_parser *parser, const char *at, size_t length)
{ {
struct sandbox *sandbox = (struct sandbox *) parser->data; struct sandbox *sandbox = (struct sandbox *)parser->data;
assert(strncmp(sandbox->module->name, (at + 1), length - 1) == 0); assert(strncmp(sandbox->module->name, (at + 1), length - 1) == 0);
return 0; return 0;
@ -36,7 +37,7 @@ http_parser_settings__on_url(http_parser *parser, const char *at, size_t length)
static inline int static inline int
http_parser_settings__on_message_begin(http_parser *parser) http_parser_settings__on_message_begin(http_parser *parser)
{ {
struct sandbox * sandbox = (struct sandbox *) parser->data; struct sandbox * sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request; struct http_request *http_request = &sandbox->http_request;
http_request->message_begin = 1; http_request->message_begin = 1;
@ -49,7 +50,8 @@ http_parser_settings__on_message_begin(http_parser *parser)
* Sets the key value of the latest header * Sets the key value of the latest header
* on a new header if last_was_value is true * on a new header if last_was_value is true
* updating an existing header if last_was_value is false * updating an existing header if last_was_value is false
* TODO: Is this logic correct? What is the relationship between fields and values? Is overwrite the correct logic if on_header executes twice in a row? * TODO: Is this logic correct? What is the relationship between fields and values? Is overwrite the correct logic if
*on_header executes twice in a row?
* @param parser * @param parser
* @param at start address of the header field * @param at start address of the header field
* @param length length of the header field * @param length length of the header field
@ -58,15 +60,16 @@ http_parser_settings__on_message_begin(http_parser *parser)
static inline int static inline int
http_parser_settings__on_header_field(http_parser *parser, const char *at, size_t length) http_parser_settings__on_header_field(http_parser *parser, const char *at, size_t length)
{ {
struct sandbox * sandbox = (struct sandbox *) parser->data; struct sandbox * sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request; struct http_request *http_request = &sandbox->http_request;
if (http_request->last_was_value) http_request->header_count++; if (http_request->last_was_value) http_request->header_count++;
assert(http_request->header_count <= HTTP_HEADERS_MAX); assert(http_request->header_count <= HTTP_HEADERS_MAX);
assert(length < HTTP_HEADER_MAXSZ); assert(length < HTTP_HEADER_MAXSZ);
http_request->last_was_value = 0; http_request->last_was_value = 0;
http_request->headers[http_request->header_count - 1].key = (char *)at; // it is from the sandbox's request_response_data, should persist. http_request->headers[http_request->header_count - 1].key = (char *)
at; // it is from the sandbox's request_response_data, should persist.
return 0; return 0;
} }
@ -82,14 +85,15 @@ http_parser_settings__on_header_field(http_parser *parser, const char *at, size_
static inline int static inline int
http_parser_settings__on_header_value(http_parser *parser, const char *at, size_t length) http_parser_settings__on_header_value(http_parser *parser, const char *at, size_t length)
{ {
struct sandbox * sandbox = (struct sandbox *) parser->data; struct sandbox * sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request; struct http_request *http_request = &sandbox->http_request;
http_request->last_was_value = 1; http_request->last_was_value = 1;
assert(http_request->header_count <= HTTP_HEADERS_MAX); assert(http_request->header_count <= HTTP_HEADERS_MAX);
assert(length < HTTP_HEADERVAL_MAXSZ); assert(length < HTTP_HEADERVAL_MAXSZ);
http_request->headers[http_request->header_count - 1].value = (char *)at; // it is from the sandbox's request_response_data, should persist. http_request->headers[http_request->header_count - 1].value = (char *)
at; // it is from the sandbox's request_response_data, should persist.
return 0; return 0;
} }
@ -102,7 +106,7 @@ http_parser_settings__on_header_value(http_parser *parser, const char *at, size_
static inline int static inline int
http_parser_settings__on_header_end(http_parser *parser) http_parser_settings__on_header_end(http_parser *parser)
{ {
struct sandbox * sandbox = (struct sandbox *) parser->data; struct sandbox * sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request; struct http_request *http_request = &sandbox->http_request;
http_request->header_end = 1; http_request->header_end = 1;
@ -120,7 +124,7 @@ http_parser_settings__on_header_end(http_parser *parser)
static inline int static inline int
http_parser_settings__on_body(http_parser *parser, const char *at, size_t length) http_parser_settings__on_body(http_parser *parser, const char *at, size_t length)
{ {
struct sandbox * sandbox = (struct sandbox *) parser->data; struct sandbox * sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request; struct http_request *http_request = &sandbox->http_request;
assert(http_request->body_length + length <= sandbox->module->max_request_size); assert(http_request->body_length + length <= sandbox->module->max_request_size);
@ -141,7 +145,7 @@ http_parser_settings__on_body(http_parser *parser, const char *at, size_t length
static inline int static inline int
http_parser_settings__on_msg_end(http_parser *parser) http_parser_settings__on_msg_end(http_parser *parser)
{ {
struct sandbox * sandbox = (struct sandbox *) parser->data; struct sandbox * sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request; struct http_request *http_request = &sandbox->http_request;
http_request->message_end = 1; http_request->message_end = 1;
@ -173,8 +177,8 @@ http_parser_settings__register_callbacks(http_parser_settings *settings)
void void
http_parser_settings__initialize(http_parser_settings *settings) http_parser_settings__initialize(http_parser_settings *settings)
{ {
http_parser_settings_init(settings); http_parser_settings_init(settings);
http_parser_settings__register_callbacks(settings); http_parser_settings__register_callbacks(settings);
} }
#endif /* SRFT_HTTP_PARSER_SETTINGS_H */ #endif /* SRFT_HTTP_PARSER_SETTINGS_H */

@ -14,9 +14,10 @@ struct http_request {
int header_count; int header_count;
char * body; char * body;
int body_length; int body_length;
int body_read_length; // How far we've read int body_read_length; // How far we've read
// additional for http-parser // additional for http-parser
int last_was_value; // http-parser flag used to help the http-parser callbacks differentiate between header fields and values to know when to allocate a new header int last_was_value; // http-parser flag used to help the http-parser callbacks differentiate between header
// fields and values to know when to allocate a new header
int header_end; // boolean flag set when header processing is complete int header_end; // boolean flag set when header processing is complete
int message_begin; // boolean flag set when body processing begins int message_begin; // boolean flag set when body processing begins
int message_end; // boolean flag set when body processing is complete int message_end; // boolean flag set when body processing is complete

@ -32,14 +32,14 @@ libuv_callbacks__on_read_parse_http_request(uv_stream_t *stream, ssize_t number_
struct http_request *rh = &sandbox->http_request; struct http_request *rh = &sandbox->http_request;
if (!rh->message_end) return; if (!rh->message_end) return;
} }
// When the entire message has been read, stop the stream and wakeup the sandbox // When the entire message has been read, stop the stream and wakeup the sandbox
uv_read_stop(stream); uv_read_stop(stream);
worker_thread__wakeup_sandbox(sandbox); worker_thread__wakeup_sandbox(sandbox);
} }
/** /**
* On libuv close, executes this callback to wake the blocked sandbox back up * On libuv close, executes this callback to wake the blocked sandbox back up
* @param stream * @param stream
**/ **/
static inline void static inline void
@ -73,7 +73,8 @@ libuv_callbacks__on_write_wakeup_sandbox(uv_write_t *write, int status)
struct sandbox *sandbox = write->data; struct sandbox *sandbox = write->data;
if (status < 0) { if (status < 0) {
sandbox->client_libuv_shutdown_request.data = sandbox; sandbox->client_libuv_shutdown_request.data = sandbox;
uv_shutdown(&sandbox->client_libuv_shutdown_request, (uv_stream_t *)&sandbox->client_libuv_stream, libuv_callbacks__on_shutdown_wakeup_sakebox); uv_shutdown(&sandbox->client_libuv_shutdown_request, (uv_stream_t *)&sandbox->client_libuv_stream,
libuv_callbacks__on_shutdown_wakeup_sakebox);
return; return;
} }
worker_thread__wakeup_sandbox(sandbox); worker_thread__wakeup_sandbox(sandbox);
@ -83,9 +84,9 @@ static inline void
libuv_callbacks__on_allocate_setup_request_response_data(uv_handle_t *h, size_t suggested, uv_buf_t *buf) libuv_callbacks__on_allocate_setup_request_response_data(uv_handle_t *h, size_t suggested, uv_buf_t *buf)
{ {
struct sandbox *sandbox = h->data; struct sandbox *sandbox = h->data;
size_t l = (sandbox->module->max_request_or_response_size - sandbox->request_response_data_length); size_t l = (sandbox->module->max_request_or_response_size - sandbox->request_response_data_length);
buf->base = (sandbox->request_response_data + sandbox->request_response_data_length); buf->base = (sandbox->request_response_data + sandbox->request_response_data_length);
buf->len = l > suggested ? suggested : l; buf->len = l > suggested ? suggested : l;
} }
#endif /* SFRT_SANDBOX_H */ #endif /* SFRT_SANDBOX_H */

@ -6,18 +6,18 @@
#include <types.h> #include <types.h>
struct module { struct module {
char name[MOD_NAME_MAX]; char name[MOD_NAME_MAX];
char path[MOD_PATH_MAX]; char path[MOD_PATH_MAX];
void *dynamic_library_handle; // Handle to the *.so of the serverless function void * dynamic_library_handle; // Handle to the *.so of the serverless function
i32 argument_count; i32 argument_count;
u32 stack_size; // a specification? u32 stack_size; // a specification?
u64 max_memory; // perhaps a specification of the module. (max 4GB) u64 max_memory; // perhaps a specification of the module. (max 4GB)
u32 timeout; // again part of the module specification. u32 timeout; // again part of the module specification.
u32 reference_count; // ref count how many instances exist here. u32 reference_count; // ref count how many instances exist here.
struct indirect_table_entry indirect_table[INDIRECT_TABLE_SIZE]; struct indirect_table_entry indirect_table[INDIRECT_TABLE_SIZE];
struct sockaddr_in socket_address; struct sockaddr_in socket_address;
int socket_descriptor; int socket_descriptor;
int port; int port;
// unfortunately, using UV for accepting connections is not great! // unfortunately, using UV for accepting connections is not great!
// on_connection, to create a new accepted connection, will have to // on_connection, to create a new accepted connection, will have to
@ -36,7 +36,7 @@ struct module {
int response_header_count; int response_header_count;
char response_content_type[HTTP_HEADERVAL_MAXSZ]; char response_content_type[HTTP_HEADERVAL_MAXSZ];
char response_headers[HTTP_HEADERS_MAX][HTTP_HEADER_MAXSZ]; char response_headers[HTTP_HEADERS_MAX][HTTP_HEADER_MAXSZ];
// Equals the largest of either max_request_size or max_response_size // Equals the largest of either max_request_size or max_response_size
unsigned long max_request_or_response_size; unsigned long max_request_or_response_size;
@ -165,7 +165,7 @@ module__release(struct module *module)
**/ **/
static inline void static inline void
module__set_http_info(struct module *module, int request_count, char *request_headers, char request_content_type[], module__set_http_info(struct module *module, int request_count, char *request_headers, char request_content_type[],
int response_count, char *response_headers, char response_content_type[]) int response_count, char *response_headers, char response_content_type[])
{ {
assert(module); assert(module);
module->request_header_count = request_count; module->request_header_count = request_count;
@ -181,7 +181,8 @@ module__set_http_info(struct module *module, int request_count, char *request_he
***************************************/ ***************************************/
void module__free(struct module *module); void module__free(struct module *module);
struct module *module__new(char *mod_name, char *mod_path, i32 argument_count, u32 stack_sz, u32 max_heap, u32 timeout, int port, int req_sz, int resp_sz); struct module *module__new(char *mod_name, char *mod_path, i32 argument_count, u32 stack_sz, u32 max_heap, u32 timeout,
int module__new_from_json(char *filename); int port, int req_sz, int resp_sz);
int module__new_from_json(char *filename);
#endif /* SFRT_MODULE_H */ #endif /* SFRT_MODULE_H */

@ -6,7 +6,7 @@
struct module *module_database__find_by_name(char *name); struct module *module_database__find_by_name(char *name);
struct module *module_database__find_by_socket_descriptor(int socket_descriptor); struct module *module_database__find_by_socket_descriptor(int socket_descriptor);
extern struct module *module_database[]; extern struct module *module_database[];
extern int module_database_free_offset; extern int module_database_free_offset;
/** /**

@ -21,7 +21,7 @@ INLINE char *get_memory_ptr_for_runtime(u32 offset, u32 bounds_check);
void runtime__initialize(void); void runtime__initialize(void);
void listener_thread__initialize(void); void listener_thread__initialize(void);
void stub_init(i32 offset); void stub_init(i32 offset);
void *worker_thread__main(void *return_code); void * worker_thread__main(void *return_code);
/** /**
* TODO: ??? * TODO: ???

@ -33,8 +33,8 @@ typedef enum
struct sandbox { struct sandbox {
sandbox__state_t state; sandbox__state_t state;
u32 sandbox_size; // The struct plus enough buffer to hold the request or response (sized off largest) u32 sandbox_size; // The struct plus enough buffer to hold the request or response (sized off largest)
void *linear_memory_start; // after sandbox struct void *linear_memory_start; // after sandbox struct
u32 linear_memory_size; // from after sandbox struct u32 linear_memory_size; // from after sandbox struct
u32 linear_memory_max_size; u32 linear_memory_max_size;
@ -57,11 +57,11 @@ struct sandbox {
void *arguments; // arguments from request, must be of module->argument_count size. void *arguments; // arguments from request, must be of module->argument_count size.
i32 return_value; i32 return_value;
struct sandbox__io_handle handles[SBOX_MAX_OPEN]; struct sandbox__io_handle handles[SBOX_MAX_OPEN];
struct sockaddr client_address; // client requesting connection! struct sockaddr client_address; // client requesting connection!
int client_socket_descriptor; int client_socket_descriptor;
uv_tcp_t client_libuv_stream; uv_tcp_t client_libuv_stream;
uv_shutdown_t client_libuv_shutdown_request; uv_shutdown_t client_libuv_shutdown_request;
http_parser http_parser; http_parser http_parser;
struct http_request http_request; struct http_request http_request;
@ -73,8 +73,8 @@ struct sandbox {
// Used by the ps_list macro // Used by the ps_list macro
struct ps_list list; struct ps_list list;
ssize_t request_response_data_length; // <= max(module->max_request_or_response_size) ssize_t request_response_data_length; // <= max(module->max_request_or_response_size)
char request_response_data[1]; // of rr_data_sz, following sandbox mem.. char request_response_data[1]; // of rr_data_sz, following sandbox mem..
} PAGE_ALIGNED; } PAGE_ALIGNED;
typedef struct sandbox sandbox_t; typedef struct sandbox sandbox_t;
@ -87,21 +87,22 @@ typedef struct sandbox sandbox_t;
extern __thread struct sandbox *worker_thread__current_sandbox; extern __thread struct sandbox *worker_thread__current_sandbox;
extern __thread arch_context_t *worker_thread__next_context; extern __thread arch_context_t *worker_thread__next_context;
extern void worker_thread__block_current_sandbox(void); extern void worker_thread__block_current_sandbox(void);
extern void worker_thread__completion_queue__add_sandbox(struct sandbox *sandbox); extern void worker_thread__completion_queue__add_sandbox(struct sandbox *sandbox);
extern void worker_thread__current_sandbox__exit(void); extern void worker_thread__current_sandbox__exit(void);
extern struct sandbox * worker_thread__get_next_sandbox(int interrupt); extern struct sandbox *worker_thread__get_next_sandbox(int interrupt);
extern void worker_thread__process_io(void); extern void worker_thread__process_io(void);
extern void __attribute__((noreturn)) worker_thread__sandbox_switch_preempt(void); extern void __attribute__((noreturn)) worker_thread__sandbox_switch_preempt(void);
extern void worker_thread__wakeup_sandbox(sandbox_t *sb); extern void worker_thread__wakeup_sandbox(sandbox_t *sb);
/*************************** /***************************
* Public API * * Public API *
**************************/ **************************/
struct sandbox *sandbox__allocate(struct module *module, char *arguments, int socket_descriptor, const struct sockaddr *socket_address, u64 start_time); struct sandbox *sandbox__allocate(struct module *module, char *arguments, int socket_descriptor,
const struct sockaddr *socket_address, u64 start_time);
void sandbox__free(struct sandbox *sandbox); void sandbox__free(struct sandbox *sandbox);
int sandbox__parse_http_request(struct sandbox *sandbox, size_t length); int sandbox__parse_http_request(struct sandbox *sandbox, size_t length);
/** /**
@ -137,7 +138,7 @@ static inline int
sandbox__initialize_io_handle(struct sandbox *sandbox) sandbox__initialize_io_handle(struct sandbox *sandbox)
{ {
if (!sandbox) return -1; if (!sandbox) return -1;
int handle_index; int handle_index;
for (handle_index = 0; handle_index < SBOX_MAX_OPEN; handle_index++) { for (handle_index = 0; handle_index < SBOX_MAX_OPEN; handle_index++) {
if (sandbox->handles[handle_index].file_descriptor < 0) break; if (sandbox->handles[handle_index].file_descriptor < 0) break;
} }
@ -159,8 +160,10 @@ sandbox__initialize_io_handle_and_set_file_descriptor(struct sandbox *sandbox, i
{ {
if (!sandbox) return -1; if (!sandbox) return -1;
if (file_descriptor < 0) return file_descriptor; if (file_descriptor < 0) return file_descriptor;
int handle_index = sandbox__initialize_io_handle(sandbox); int handle_index = sandbox__initialize_io_handle(sandbox);
if (handle_index != -1) sandbox->handles[handle_index].file_descriptor = file_descriptor; // well, per sandbox.. so synchronization necessary! if (handle_index != -1)
sandbox->handles[handle_index].file_descriptor =
file_descriptor; // well, per sandbox.. so synchronization necessary!
return handle_index; return handle_index;
} }

@ -20,7 +20,7 @@ DEQUE_PROTOTYPE(sandbox, sandbox_request_t *);
/** /**
* Pushes a sandbox request to the global deque * Pushes a sandbox request to the global deque
* @param sandbox_request * @param sandbox_request
**/ **/
static inline int static inline int
sandbox_request__add_to_global_dequeue(sandbox_request_t *sandbox_request) sandbox_request__add_to_global_dequeue(sandbox_request_t *sandbox_request)
@ -48,15 +48,16 @@ sandbox_request__add_to_global_dequeue(sandbox_request_t *sandbox_request)
* @return the new sandbox request * @return the new sandbox request
**/ **/
static inline sandbox_request_t * static inline sandbox_request_t *
sandbox_request__allocate(struct module *module, char *arguments, int socket_descriptor, const struct sockaddr *socket_address, u64 start_time) sandbox_request__allocate(struct module *module, char *arguments, int socket_descriptor,
const struct sockaddr *socket_address, u64 start_time)
{ {
sandbox_request_t *sandbox_request = (sandbox_request_t *)malloc(sizeof(sandbox_request_t)); sandbox_request_t *sandbox_request = (sandbox_request_t *)malloc(sizeof(sandbox_request_t));
assert(sandbox_request); assert(sandbox_request);
sandbox_request->module = module; sandbox_request->module = module;
sandbox_request->arguments = arguments; sandbox_request->arguments = arguments;
sandbox_request->socket_descriptor = socket_descriptor; sandbox_request->socket_descriptor = socket_descriptor;
sandbox_request->socket_address = (struct sockaddr *)socket_address; sandbox_request->socket_address = (struct sockaddr *)socket_address;
sandbox_request->start_time = start_time; sandbox_request->start_time = start_time;
debuglog("[%p: %s]\n", sandbox_request, sandbox_request->module->name); debuglog("[%p: %s]\n", sandbox_request, sandbox_request->module->name);
sandbox_request__add_to_global_dequeue(sandbox_request); sandbox_request__add_to_global_dequeue(sandbox_request);

@ -21,7 +21,7 @@
#define IMPORT __attribute__((visibility("default"))) #define IMPORT __attribute__((visibility("default")))
#define INLINE __attribute__((always_inline)) #define INLINE __attribute__((always_inline))
#define WEAK __attribute__((weak)) #define WEAK __attribute__((weak))
#ifndef CACHELINE_SIZE #ifndef CACHELINE_SIZE
#define CACHELINE_SIZE 32 #define CACHELINE_SIZE 32
@ -32,13 +32,13 @@
#endif #endif
#define CACHE_ALIGNED __attribute__((aligned(CACHELINE_SIZE))) #define CACHE_ALIGNED __attribute__((aligned(CACHELINE_SIZE)))
#define PAGE_ALIGNED __attribute__((aligned(PAGE_SIZE))) #define PAGE_ALIGNED __attribute__((aligned(PAGE_SIZE)))
/* For this family of macros, do NOT pass zero as the pow2 */ /* For this family of macros, do NOT pass zero as the pow2 */
#define round_to_pow2(x, pow2) (((unsigned long)(x)) & (~((pow2)-1))) #define round_to_pow2(x, pow2) (((unsigned long)(x)) & (~((pow2)-1)))
#define round_up_to_pow2(x, pow2) (round_to_pow2(((unsigned long)x) + (pow2)-1, (pow2))) #define round_up_to_pow2(x, pow2) (round_to_pow2(((unsigned long)x) + (pow2)-1, (pow2)))
#define round_to_page(x) round_to_pow2(x, PAGE_SIZE) #define round_to_page(x) round_to_pow2(x, PAGE_SIZE)
#define round_up_to_page(x) round_up_to_pow2(x, PAGE_SIZE) #define round_up_to_page(x) round_up_to_pow2(x, PAGE_SIZE)
// Type alias's so I don't have to write uint32_t a million times // Type alias's so I don't have to write uint32_t a million times
@ -52,11 +52,11 @@ typedef int64_t i64;
typedef uint64_t u64; typedef uint64_t u64;
// FIXME: per-module configuration? // FIXME: per-module configuration?
#define WASM_PAGE_SIZE (1024 * 64) // 64KB #define WASM_PAGE_SIZE (1024 * 64) // 64KB
#define WASM_START_PAGES (1 << 8) // 16MB #define WASM_START_PAGES (1 << 8) // 16MB
#define WASM_MAX_PAGES (1 << 15) // 4GB #define WASM_MAX_PAGES (1 << 15) // 4GB
#define WASM_STACK_SIZE (1 << 19) // 512KB. #define WASM_STACK_SIZE (1 << 19) // 512KB.
#define SBOX_MAX_MEM (1L << 32) // 4GB #define SBOX_MAX_MEM (1L << 32) // 4GB
// These are per module symbols and I'd need to dlsym for each module. instead just use global constants, see above // These are per module symbols and I'd need to dlsym for each module. instead just use global constants, see above
// macros. The code generator compiles in the starting number of wasm pages, and the maximum number of pages If we try // macros. The code generator compiles in the starting number of wasm pages, and the maximum number of pages If we try
@ -100,30 +100,31 @@ typedef enum
} mod_argindex_t; } mod_argindex_t;
#define MOD_MAIN_FN "wasmf_main" #define MOD_MAIN_FN "wasmf_main"
#define MOD_GLB_FN "populate_globals" #define MOD_GLB_FN "populate_globals"
#define MOD_MEM_FN "populate_memory" #define MOD_MEM_FN "populate_memory"
#define MOD_TBL_FN "populate_table" #define MOD_TBL_FN "populate_table"
#define MOD_LIBC_FN "wasmf___init_libc" #define MOD_LIBC_FN "wasmf___init_libc"
#define MOD_MAX_ARGS 16 // Max number of arguments #define MOD_MAX_ARGS 16 // Max number of arguments
#define MOD_ARG_MAX_SZ 64 // Max size of a single argument #define MOD_ARG_MAX_SZ 64 // Max size of a single argument
#define MOD_MAX 1024 // Max size of a single module in JSON #define MOD_MAX 1024 // Max size of a single module in JSON
#define MOD_NAME_MAX 32 // Max module name length #define MOD_NAME_MAX 32 // Max module name length
#define MOD_PATH_MAX 256 // Max module path length #define MOD_PATH_MAX 256 // Max module path length
#define JSON_ELE_MAX 16 // Max number of elements defined in JSON #define JSON_ELE_MAX 16 // Max number of elements defined in JSON
// This is the max number of standboxes that get pulled onto the local runqueue in a single batch // This is the max number of standboxes that get pulled onto the local runqueue in a single batch
#define SBOX_PULL_MAX 1 #define SBOX_PULL_MAX 1
#define SBOX_MAX_OPEN 32 #define SBOX_MAX_OPEN 32
#define SBOX_PREOPEN_MAGIC (707707707) // reads lol lol lol upside down #define SBOX_PREOPEN_MAGIC (707707707) // reads lol lol lol upside down
#define SOFTINT_TIMER_START_USEC (10 * 1000) // start timers 10 ms from now. #define SOFTINT_TIMER_START_USEC (10 * 1000) // start timers 10 ms from now.
#define SOFTINT_TIMER_PERIOD_USEC (1000 * 5) // 5ms timer.. #define SOFTINT_TIMER_PERIOD_USEC (1000 * 5) // 5ms timer..
#ifdef DEBUG #ifdef DEBUG
#ifdef NOSTDIO #ifdef NOSTDIO
#define debuglog(fmt, ...) dprintf(log_file_descriptor, "(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ##__VA_ARGS__) #define debuglog(fmt, ...) \
dprintf(log_file_descriptor, "(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ##__VA_ARGS__)
#else #else
#define debuglog(fmt, ...) printf("(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ##__VA_ARGS__) #define debuglog(fmt, ...) printf("(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ##__VA_ARGS__)
#endif #endif
@ -133,33 +134,33 @@ typedef enum
#define GLB_STDOUT "/dev/null" #define GLB_STDOUT "/dev/null"
#define GLB_STDERR "/dev/null" #define GLB_STDERR "/dev/null"
#define GLB_STDIN "/dev/zero" #define GLB_STDIN "/dev/zero"
#define LOGFILE "awesome.log" #define LOGFILE "awesome.log"
#define RDWR_VEC_MAX 16 #define RDWR_VEC_MAX 16
#define MOD_REQ_CORE 0 // Dedicated Listener Core #define MOD_REQ_CORE 0 // Dedicated Listener Core
// If multicore, use all but the dedicated listener core // If multicore, use all but the dedicated listener core
// If there are fewer cores than this, main dynamically overrides this and uses all available // If there are fewer cores than this, main dynamically overrides this and uses all available
#define SBOX_NCORES (NCORES > 1 ? NCORES - 1 : NCORES) #define SBOX_NCORES (NCORES > 1 ? NCORES - 1 : NCORES)
#define SBOX_MAX_REQS (1 << 19) // random! #define SBOX_MAX_REQS (1 << 19) // random!
#define SBOX_RESP_STRSZ 32 #define SBOX_RESP_STRSZ 32
#define MOD_BACKLOG 1000 #define MOD_BACKLOG 1000
#define EPOLL_MAX 1024 #define EPOLL_MAX 1024
#define MOD_REQ_RESP_DEFAULT (PAGE_SIZE) #define MOD_REQ_RESP_DEFAULT (PAGE_SIZE)
#define QUIESCENSE_TIME (1 << 20) // cycles! #define QUIESCENSE_TIME (1 << 20) // cycles!
#define HTTP_HEADERS_MAX 16 #define HTTP_HEADERS_MAX 16
#define HTTP_HEADER_MAXSZ 32 #define HTTP_HEADER_MAXSZ 32
#define HTTP_HEADERVAL_MAXSZ 64 #define HTTP_HEADERVAL_MAXSZ 64
#define HTTP_RESP_200OK "HTTP/1.1 200 OK\r\n" #define HTTP_RESP_200OK "HTTP/1.1 200 OK\r\n"
#define HTTP_RESP_CONTTYPE "Content-type: \r\n" #define HTTP_RESP_CONTTYPE "Content-type: \r\n"
#define HTTP_RESP_CONTLEN "Content-length: \r\n\r\n" // content body follows this #define HTTP_RESP_CONTLEN "Content-length: \r\n\r\n" // content body follows this
#define HTTP_RESP_CONTTYPE_PLAIN "text/plain" #define HTTP_RESP_CONTTYPE_PLAIN "text/plain"
#endif /* SFRT_TYPES_H */ #endif /* SFRT_TYPES_H */

@ -16,4 +16,3 @@ http_request__get_body(struct http_request *http_request, char **body)
*body = http_request->body; *body = http_request->body;
return http_request->body_length; return http_request->body_length;
} }

@ -23,14 +23,17 @@ http_response__encode_as_vector(struct http_response *http_response)
http_response->bufs[buffer_count] = uv_buf_init(http_response->status, http_response->status_length); http_response->bufs[buffer_count] = uv_buf_init(http_response->status, http_response->status_length);
buffer_count++; buffer_count++;
for (int i = 0; i < http_response->header_count; i++) { for (int i = 0; i < http_response->header_count; i++) {
http_response->bufs[buffer_count] = uv_buf_init(http_response->headers[i].header, http_response->headers[i].length); http_response->bufs[buffer_count] = uv_buf_init(http_response->headers[i].header,
http_response->headers[i].length);
buffer_count++; buffer_count++;
} }
if (http_response->body) { if (http_response->body) {
http_response->bufs[buffer_count] = uv_buf_init(http_response->body, http_response->body_length); http_response->bufs[buffer_count] = uv_buf_init(http_response->body, http_response->body_length);
buffer_count++; buffer_count++;
http_response->bufs[buffer_count] = uv_buf_init(http_response->status + http_response->status_length - 2, 2); // for crlf http_response->bufs[buffer_count] = uv_buf_init(http_response->status + http_response->status_length
- 2,
2); // for crlf
buffer_count++; buffer_count++;
} }
#else #else

@ -9,25 +9,25 @@
#define GID 0xFE #define GID 0xFE
// Elf auxilary vector values (see google for what those are) // Elf auxilary vector values (see google for what those are)
#define AT_NULL 0 #define AT_NULL 0
#define AT_IGNORE 1 #define AT_IGNORE 1
#define AT_EXECFD 2 #define AT_EXECFD 2
#define AT_PHDR 3 #define AT_PHDR 3
#define AT_PHENT 4 #define AT_PHENT 4
#define AT_PHNUM 5 #define AT_PHNUM 5
#define AT_PAGESZ 6 #define AT_PAGESZ 6
#define AT_BASE 7 #define AT_BASE 7
#define AT_FLAGS 8 #define AT_FLAGS 8
#define AT_ENTRY 9 #define AT_ENTRY 9
#define AT_NOTELF 10 #define AT_NOTELF 10
#define AT_UID 11 #define AT_UID 11
#define AT_EUID 12 #define AT_EUID 12
#define AT_GID 13 #define AT_GID 13
#define AT_EGID 14 #define AT_EGID 14
#define AT_CLKTCK 17 #define AT_CLKTCK 17
#define AT_SECURE 23 #define AT_SECURE 23
#define AT_BASE_PLATFORM 24 #define AT_BASE_PLATFORM 24
#define AT_RANDOM 25 #define AT_RANDOM 25
// offset = a WASM ptr to memory the runtime can use // offset = a WASM ptr to memory the runtime can use
void void
@ -87,8 +87,8 @@ uv_fs_get_type(uv_fs_t *req)
return req->fs_type; return req->fs_type;
} }
#define UV_FS_REQ_INIT() \ #define UV_FS_REQ_INIT() \
{ \ { \
.data = current_sandbox__get(), .result = 0 \ .data = current_sandbox__get(), .result = 0 \
} }
@ -162,21 +162,21 @@ wasm_write(i32 file_descriptor, i32 buf_offset, i32 buf_size)
return ret; return ret;
} }
#define WO_RDONLY 00 #define WO_RDONLY 00
#define WO_WRONLY 01 #define WO_WRONLY 01
#define WO_RDWR 02 #define WO_RDWR 02
#define WO_CREAT 0100 #define WO_CREAT 0100
#define WO_EXCL 0200 #define WO_EXCL 0200
#define WO_NOCTTY 0400 #define WO_NOCTTY 0400
#define WO_TRUNC 01000 #define WO_TRUNC 01000
#define WO_APPEND 02000 #define WO_APPEND 02000
#define WO_NONBLOCK 04000 #define WO_NONBLOCK 04000
#define WO_DSYNC 010000 #define WO_DSYNC 010000
#define WO_SYNC 04010000 #define WO_SYNC 04010000
#define WO_RSYNC 04010000 #define WO_RSYNC 04010000
#define WO_DIRECTORY 0200000 #define WO_DIRECTORY 0200000
#define WO_NOFOLLOW 0400000 #define WO_NOFOLLOW 0400000
#define WO_CLOEXEC 02000000 #define WO_CLOEXEC 02000000
#define SYS_OPEN 2 #define SYS_OPEN 2
i32 i32
@ -612,8 +612,8 @@ wasm_getpid()
#define WF_SETSIG 10 #define WF_SETSIG 10
#define WF_GETSIG 11 #define WF_GETSIG 11
#define WF_GETLK 5 #define WF_GETLK 5
#define WF_SETLK 6 #define WF_SETLK 6
#define WF_SETLKW 7 #define WF_SETLKW 7
#define SYS_FCNTL 72 #define SYS_FCNTL 72
@ -750,11 +750,11 @@ wasm_fchown(i32 file_descriptor, u32 owner, u32 group)
} }
// networking syscalls // networking syscalls
#define SYS_SOCKET 41 #define SYS_SOCKET 41
#define SYS_CONNECT 42 #define SYS_CONNECT 42
#define SYS_ACCEPT 43 #define SYS_ACCEPT 43
#define SYS_BIND 49 #define SYS_BIND 49
#define SYS_LISTEN 50 #define SYS_LISTEN 50
static void static void
wasm_connection_callback(uv_stream_t *srv, int status) wasm_connection_callback(uv_stream_t *srv, int status)
@ -805,7 +805,7 @@ wasm_socket(i32 domain, i32 type, i32 protocol)
i32 i32
wasm_connect(i32 sockfd, i32 sockaddr_offset, i32 addrlen) wasm_connect(i32 sockfd, i32 sockaddr_offset, i32 addrlen)
{ {
struct sandbox *c = current_sandbox__get(); struct sandbox *c = current_sandbox__get();
int file_descriptor = current_sandbox__get_file_descriptor(sockfd); int file_descriptor = current_sandbox__get_file_descriptor(sockfd);
debuglog("[%p] [%d, %d]\n", c, sockfd, file_descriptor); debuglog("[%p] [%d, %d]\n", c, sockfd, file_descriptor);
union uv_any_handle *h = current_sandbox__get_libuv_handle(sockfd); union uv_any_handle *h = current_sandbox__get_libuv_handle(sockfd);
@ -834,10 +834,10 @@ i32
wasm_accept(i32 sockfd, i32 sockaddr_offset, i32 addrlen_offset) wasm_accept(i32 sockfd, i32 sockaddr_offset, i32 addrlen_offset)
{ {
// what do we do with the sockaddr TODO: ???? // what do we do with the sockaddr TODO: ????
socklen_t * addrlen = get_memory_ptr_void(addrlen_offset, sizeof(socklen_t)); socklen_t * addrlen = get_memory_ptr_void(addrlen_offset, sizeof(socklen_t));
struct sockaddr * socket_address = get_memory_ptr_void(sockaddr_offset, *addrlen); struct sockaddr * socket_address = get_memory_ptr_void(sockaddr_offset, *addrlen);
union uv_any_handle *s = current_sandbox__get_libuv_handle(sockfd); union uv_any_handle *s = current_sandbox__get_libuv_handle(sockfd);
int cfd = current_sandbox__initialize_io_handle(); int cfd = current_sandbox__initialize_io_handle();
if (cfd < 0) return -1; if (cfd < 0) return -1;
struct sandbox *c = current_sandbox__get(); struct sandbox *c = current_sandbox__get();
debuglog("[%p] [%d, %d]\n", c, sockfd, current_sandbox__get_file_descriptor(sockfd)); debuglog("[%p] [%d, %d]\n", c, sockfd, current_sandbox__get_file_descriptor(sockfd));
@ -865,7 +865,7 @@ wasm_accept(i32 sockfd, i32 sockaddr_offset, i32 addrlen_offset)
i32 i32
wasm_bind(i32 sockfd, i32 sockaddr_offset, i32 addrlen) wasm_bind(i32 sockfd, i32 sockaddr_offset, i32 addrlen)
{ {
struct sandbox *c = current_sandbox__get(); struct sandbox *c = current_sandbox__get();
int file_descriptor = current_sandbox__get_file_descriptor(sockfd); int file_descriptor = current_sandbox__get_file_descriptor(sockfd);
debuglog("[%p] [%d,%d]\n", c, sockfd, file_descriptor); debuglog("[%p] [%d,%d]\n", c, sockfd, file_descriptor);
union uv_any_handle *h = current_sandbox__get_libuv_handle(sockfd); union uv_any_handle *h = current_sandbox__get_libuv_handle(sockfd);
@ -916,7 +916,7 @@ wasm_listen(i32 sockfd, i32 backlog)
return c->return_value; return c->return_value;
} }
#define SYS_SENDTO 44 #define SYS_SENDTO 44
#define SYS_RECVFROM 45 #define SYS_RECVFROM 45
void void
@ -936,14 +936,15 @@ void
wasm_write_callback(uv_write_t *req, int status) wasm_write_callback(uv_write_t *req, int status)
{ {
struct sandbox *c = req->data; struct sandbox *c = req->data;
c->return_value = status; c->return_value = status;
debuglog("[%p] %d\n", c, status); debuglog("[%p] %d\n", c, status);
worker_thread__wakeup_sandbox(c); worker_thread__wakeup_sandbox(c);
} }
void void
wasm_udp_recv_callback(uv_udp_t *h, ssize_t nread, const uv_buf_t *buffer, const struct sockaddr *socket_address, unsigned flags) wasm_udp_recv_callback(uv_udp_t *h, ssize_t nread, const uv_buf_t *buffer, const struct sockaddr *socket_address,
unsigned flags)
{ {
struct sandbox *c = h->data; struct sandbox *c = h->data;
@ -959,7 +960,7 @@ void
wasm_udp_send_callback(uv_udp_send_t *req, int status) wasm_udp_send_callback(uv_udp_send_t *req, int status)
{ {
struct sandbox *c = req->data; struct sandbox *c = req->data;
c->return_value = status; c->return_value = status;
debuglog("[%p] %d\n", c, status); debuglog("[%p] %d\n", c, status);
worker_thread__wakeup_sandbox(c); worker_thread__wakeup_sandbox(c);
@ -1032,9 +1033,9 @@ wasm_recvfrom(i32 file_descriptor, i32 buff_offset, i32 size, i32 flags, i32 soc
// so we keep the read buffer pointers in sandbox structure.. // so we keep the read buffer pointers in sandbox structure..
// for use in the callbacks.. // for use in the callbacks..
c->read_buffer = buffer; c->read_buffer = buffer;
c->read_size = size; c->read_size = size;
c->read_length = 0; c->read_length = 0;
c->return_value = 0; c->return_value = 0;
// TODO: what if stream read more than what "size" is here?? // TODO: what if stream read more than what "size" is here??
if (t == UV_TCP) { if (t == UV_TCP) {

@ -50,7 +50,8 @@ module__initialize_as_server(struct module *module)
struct epoll_event accept_evt; struct epoll_event accept_evt;
accept_evt.data.ptr = (void *)module; accept_evt.data.ptr = (void *)module;
accept_evt.events = EPOLLIN; accept_evt.events = EPOLLIN;
if (epoll_ctl(runtime__epoll_file_descriptor, EPOLL_CTL_ADD, module->socket_descriptor, &accept_evt) < 0) assert(0); if (epoll_ctl(runtime__epoll_file_descriptor, EPOLL_CTL_ADD, module->socket_descriptor, &accept_evt) < 0)
assert(0);
} }
/*************************************** /***************************************
@ -82,8 +83,8 @@ module__free(struct module *module)
/** /**
* Module Contructor * Module Contructor
* Creates a new module, invokes initialize_tables to initialize the indirect table, adds it to the module DB, and starts * Creates a new module, invokes initialize_tables to initialize the indirect table, adds it to the module DB, and
*listening for HTTP Requests *starts listening for HTTP Requests
* *
* @param name * @param name
* @param path * @param path
@ -97,7 +98,7 @@ module__free(struct module *module)
**/ **/
struct module * struct module *
module__new(char *name, char *path, i32 argument_count, u32 stack_size, u32 max_memory, u32 timeout, int port, module__new(char *name, char *path, i32 argument_count, u32 stack_size, u32 max_memory, u32 timeout, int port,
int request_size, int response_size) int request_size, int response_size)
{ {
struct module *module = (struct module *)malloc(sizeof(struct module)); struct module *module = (struct module *)malloc(sizeof(struct module));
if (!module) return NULL; if (!module) return NULL;
@ -146,8 +147,8 @@ module__new(char *name, char *path, i32 argument_count, u32 stack_size, u32 max_
// assumption: All modules are created at program start before we enable preemption or enable the execution of // 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 // 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 // yet preempting If we want to be able to do this later, we can possibly defer module__initialize_table until
// first invocation // the first invocation
assert(cache_tbl == NULL); assert(cache_tbl == NULL);
// TODO: determine why we have to set the module_indirect_table state before calling table init and then restore // TODO: determine why we have to set the module_indirect_table state before calling table init and then restore
@ -308,10 +309,10 @@ module__new_from_json(char *file_name)
// Allocate a module based on the values from the JSON // Allocate a module based on the values from the JSON
struct module *module = module__new(module_name, module_path, argument_count, 0, 0, 0, port, struct module *module = module__new(module_name, module_path, argument_count, 0, 0, 0, port,
request_size, response_size); request_size, response_size);
assert(module); assert(module);
module__set_http_info(module, request_count, request_headers, request_content_type, response_count, module__set_http_info(module, request_count, request_headers, request_content_type, response_count,
reponse_headers, response_content_type); reponse_headers, response_content_type);
module_count++; module_count++;
free(request_headers); free(request_headers);
free(reponse_headers); free(reponse_headers);

@ -8,7 +8,7 @@
// In-memory representation of all active modules // In-memory representation of all active modules
struct module *module_database[MOD_MAX] = { NULL }; struct module *module_database[MOD_MAX] = { NULL };
// First free in module // First free in module
int module_database_free_offset = 0; int module_database_free_offset = 0;
/** /**
* Given a name, find the associated module * Given a name, find the associated module

@ -72,8 +72,8 @@ listener_thread__main(void *dummy)
int total_requests = 0; int total_requests = 0;
while (true) { while (true) {
int request_count = epoll_wait(runtime__epoll_file_descriptor, epoll_events, EPOLL_MAX, -1); int request_count = epoll_wait(runtime__epoll_file_descriptor, epoll_events, EPOLL_MAX, -1);
u64 start_time = util__rdtsc(); u64 start_time = util__rdtsc();
for (int i = 0; i < request_count; i++) { for (int i = 0; i < request_count; i++) {
if (epoll_events[i].events & EPOLLERR) { if (epoll_events[i].events & EPOLLERR) {
perror("epoll_wait"); perror("epoll_wait");
@ -82,10 +82,10 @@ listener_thread__main(void *dummy)
struct sockaddr_in client_address; struct sockaddr_in client_address;
socklen_t client_length = sizeof(client_address); socklen_t client_length = sizeof(client_address);
struct module * module = (struct module *)epoll_events[i].data.ptr; struct module * module = (struct module *)epoll_events[i].data.ptr;
assert(module); assert(module);
int es = module->socket_descriptor; int es = module->socket_descriptor;
int socket_descriptor = accept(es, (struct sockaddr *)&client_address, &client_length); int socket_descriptor = accept(es, (struct sockaddr *)&client_address, &client_length);
if (socket_descriptor < 0) { if (socket_descriptor < 0) {
perror("accept"); perror("accept");
assert(0); assert(0);
@ -93,12 +93,9 @@ listener_thread__main(void *dummy)
total_requests++; total_requests++;
printf("Received Request %d at %lu\n", total_requests, start_time); printf("Received Request %d at %lu\n", total_requests, start_time);
sandbox_request_t *sandbox_request = sandbox_request__allocate( sandbox_request_t *sandbox_request =
module, sandbox_request__allocate(module, module->name, socket_descriptor,
module->name, (const struct sockaddr *)&client_address, start_time);
socket_descriptor,
(const struct sockaddr *)&client_address,
start_time);
assert(sandbox_request); assert(sandbox_request);
// TODO: Refactor sandbox_request__allocate to not add to global request queue and do this here // TODO: Refactor sandbox_request__allocate to not add to global request queue and do this here
@ -176,7 +173,8 @@ worker_thread__switch_to_sandbox(struct sandbox *next_sandbox)
arch_context_t *current_register_context = current_sandbox == NULL ? NULL : &current_sandbox->ctxt; arch_context_t *current_register_context = current_sandbox == NULL ? NULL : &current_sandbox->ctxt;
current_sandbox__set(next_sandbox); current_sandbox__set(next_sandbox);
// If the current sandbox we're switching from is in a RETURNED state, add to completion queue // If the current sandbox we're switching from is in a RETURNED state, add to completion queue
if (current_sandbox && current_sandbox->state == RETURNED) worker_thread__completion_queue__add_sandbox(current_sandbox); if (current_sandbox && current_sandbox->state == RETURNED)
worker_thread__completion_queue__add_sandbox(current_sandbox);
worker_thread__next_context = next_register_context; worker_thread__next_context = next_register_context;
arch_context_switch(current_register_context, next_register_context); arch_context_switch(current_register_context, next_register_context);
softint__enable(); softint__enable();
@ -202,7 +200,8 @@ done:
/** /**
* Mark the currently executing sandbox as blocked, remove it from the local runqueue, and pull the sandbox at the head of the runqueue * Mark the currently executing sandbox as blocked, remove it from the local runqueue, and pull the sandbox at the head
*of the runqueue
**/ **/
void void
worker_thread__block_current_sandbox(void) worker_thread__block_current_sandbox(void)
@ -211,9 +210,10 @@ worker_thread__block_current_sandbox(void)
softint__disable(); softint__disable();
struct sandbox *current_sandbox = current_sandbox__get(); struct sandbox *current_sandbox = current_sandbox__get();
ps_list_rem_d(current_sandbox); ps_list_rem_d(current_sandbox);
current_sandbox->state = BLOCKED; current_sandbox->state = BLOCKED;
struct sandbox *next_sandbox = worker_thread__get_next_sandbox(0); struct sandbox *next_sandbox = worker_thread__get_next_sandbox(0);
debuglog("[%p: %next_sandbox, %p: %next_sandbox]\n", current_sandbox, current_sandbox->module->name, next_sandbox, next_sandbox ? next_sandbox->module->name : ""); debuglog("[%p: %next_sandbox, %p: %next_sandbox]\n", current_sandbox, current_sandbox->module->name,
next_sandbox, next_sandbox ? next_sandbox->module->name : "");
softint__enable(); softint__enable();
worker_thread__switch_to_sandbox(next_sandbox); worker_thread__switch_to_sandbox(next_sandbox);
} }
@ -231,7 +231,7 @@ worker_thread__process_io(void)
// great! if there is a way (TODO), perhaps RUN_ONCE and check if your I/O is processed, if yes, return else do // great! if there is a way (TODO), perhaps RUN_ONCE and check if your I/O is processed, if yes, return else do
// async block! // async block!
uv_run(get_thread_libuv_handle(), UV_RUN_DEFAULT); uv_run(get_thread_libuv_handle(), UV_RUN_DEFAULT);
#else /* USE_HTTP_SYNC */ #else /* USE_HTTP_SYNC */
worker_thread__block_current_sandbox(); worker_thread__block_current_sandbox();
#endif /* USE_HTTP_UVIO */ #endif /* USE_HTTP_UVIO */
#else #else
@ -267,8 +267,9 @@ worker_thread__pull_and_process_sandbox_requests(void)
if ((sandbox_request = sandbox_request__steal_from_global_dequeue()) == NULL) break; if ((sandbox_request = sandbox_request__steal_from_global_dequeue()) == NULL) break;
// Actually allocate the sandbox for the requests that we've pulled // Actually allocate the sandbox for the requests that we've pulled
struct sandbox *sandbox = sandbox__allocate(sandbox_request->module, sandbox_request->arguments, struct sandbox *sandbox = sandbox__allocate(sandbox_request->module, sandbox_request->arguments,
sandbox_request->socket_descriptor, sandbox_request->socket_address, sandbox_request->socket_descriptor,
sandbox_request->start_time); sandbox_request->socket_address,
sandbox_request->start_time);
assert(sandbox); assert(sandbox);
free(sandbox_request); free(sandbox_request);
// Set the sandbox as runnable and place on the local runqueue // Set the sandbox as runnable and place on the local runqueue
@ -303,7 +304,7 @@ static inline void
worker_thread__run_queue__add_sandbox(struct sandbox *sandbox) worker_thread__run_queue__add_sandbox(struct sandbox *sandbox)
{ {
assert(ps_list_singleton_d(sandbox)); assert(ps_list_singleton_d(sandbox));
// fprintf(stderr, "(%d,%lu) %s: run %p, %s\n", sched_getcpu(), pthread_self(), __func__, s, // fprintf(stderr, "(%d,%lu) %s: run %p, %s\n", sched_getcpu(), pthread_self(), __func__, s,
// s->module->name); // s->module->name);
ps_list_head_append_d(&worker_thread__run_queue, sandbox); ps_list_head_append_d(&worker_thread__run_queue, sandbox);
} }
@ -327,8 +328,8 @@ worker_thread__run_queue__remove_sandbox(struct sandbox *sandbox)
struct sandbox * struct sandbox *
worker_thread__get_next_sandbox(int in_interrupt) worker_thread__get_next_sandbox(int in_interrupt)
{ {
// If the thread local runqueue is empty and we're not running in the context of an interupt, // If the thread local runqueue is empty and we're not running in the context of an interupt,
// pull a fresh batch of sandbox requests from the global queue // pull a fresh batch of sandbox requests from the global queue
if (ps_list_head_empty(&worker_thread__run_queue)) { if (ps_list_head_empty(&worker_thread__run_queue)) {
// this is in an interrupt context, don't steal work here! // this is in an interrupt context, don't steal work here!
if (in_interrupt) return NULL; if (in_interrupt) return NULL;
@ -341,7 +342,8 @@ worker_thread__get_next_sandbox(int in_interrupt)
// Execute Round Robin Scheduling Logic // Execute Round Robin Scheduling Logic
// Grab the sandbox at the head of the thread local runqueue, add it to the end, and return it // Grab the sandbox at the head of the thread local runqueue, add it to the end, and return it
struct sandbox *sandbox = ps_list_head_first_d(&worker_thread__run_queue, struct sandbox); struct sandbox *sandbox = ps_list_head_first_d(&worker_thread__run_queue, struct sandbox);
// We are assuming that any sandboxed in the RETURNED state should have been pulled from the local runqueue by now! // We are assuming that any sandboxed in the RETURNED state should have been pulled from the local runqueue by
// now!
assert(sandbox->state != RETURNED); assert(sandbox->state != RETURNED);
ps_list_rem_d(sandbox); ps_list_rem_d(sandbox);
ps_list_head_append_d(&worker_thread__run_queue, sandbox); ps_list_head_append_d(&worker_thread__run_queue, sandbox);
@ -379,7 +381,7 @@ worker_thread__completion_queue__free_sandboxes(unsigned int number_to_free)
} }
/** /**
* Tries to free a completed request, executes libuv callbacks, and then gets * Tries to free a completed request, executes libuv callbacks, and then gets
* and returns the standbox at the head of the thread-local runqueue * and returns the standbox at the head of the thread-local runqueue
* @return sandbox or NULL * @return sandbox or NULL
**/ **/
@ -402,7 +404,7 @@ worker_thread__single_loop(void)
/** /**
* The entry function for sandbox worker threads * The entry function for sandbox worker threads
* Initializes thread-local state, unmasks signals, sets up libuv loop and * Initializes thread-local state, unmasks signals, sets up libuv loop and
* @param return_code - argument provided by pthread API. We set to -1 on error * @param return_code - argument provided by pthread API. We set to -1 on error
**/ **/
void * void *
@ -412,7 +414,7 @@ worker_thread__main(void *return_code)
ps_list_head_init(&worker_thread__run_queue); ps_list_head_init(&worker_thread__run_queue);
ps_list_head_init(&worker_thread__completion_queue); ps_list_head_init(&worker_thread__completion_queue);
softint__is_disabled = 0; softint__is_disabled = 0;
worker_thread__next_context = NULL; worker_thread__next_context = NULL;
#ifndef PREEMPT_DISABLE #ifndef PREEMPT_DISABLE
softint__unmask(SIGALRM); softint__unmask(SIGALRM);

@ -17,7 +17,7 @@
static inline void static inline void
current_sandbox__setup_arguments(i32 argument_count) current_sandbox__setup_arguments(i32 argument_count)
{ {
struct sandbox *curr = current_sandbox__get(); struct sandbox *curr = current_sandbox__get();
char * arguments = current_sandbox__get_arguments(); char * arguments = current_sandbox__get_arguments();
// whatever gregor has, to be able to pass arguments to a module! // whatever gregor has, to be able to pass arguments to a module!
@ -46,7 +46,7 @@ current_sandbox__setup_arguments(i32 argument_count)
* @param sandbox the sandbox containing the req_resp data that we want to parse * @param sandbox the sandbox containing the req_resp data that we want to parse
* @param length The size of the request_response_data that we want to parse * @param length The size of the request_response_data that we want to parse
* @returns 0 * @returns 0
* *
* Globals: runtime__http_parser_settings * Globals: runtime__http_parser_settings
**/ **/
int int
@ -54,20 +54,21 @@ sandbox__parse_http_request(struct sandbox *sandbox, size_t length)
{ {
// Why is our start address sandbox->request_response_data + sandbox->request_response_data_length? // Why is our start address sandbox->request_response_data + sandbox->request_response_data_length?
// it's like a cursor to keep track of what we've read so far // it's like a cursor to keep track of what we've read so far
http_parser_execute(&sandbox->http_parser, &runtime__http_parser_settings, sandbox->request_response_data + sandbox->request_response_data_length, length); http_parser_execute(&sandbox->http_parser, &runtime__http_parser_settings,
sandbox->request_response_data + sandbox->request_response_data_length, length);
return 0; return 0;
} }
/** /**
* Receive and Parse the Request for the current sandbox * Receive and Parse the Request for the current sandbox
* @return 1 on success, 0 if no context, < 0 on failure. * @return 1 on success, 0 if no context, < 0 on failure.
**/ **/
static inline int static inline int
current_sandbox__receive_and_parse_client_request(void) current_sandbox__receive_and_parse_client_request(void)
{ {
struct sandbox *curr = current_sandbox__get(); struct sandbox *curr = current_sandbox__get();
curr->request_response_data_length = 0; curr->request_response_data_length = 0;
#ifndef USE_HTTP_UVIO #ifndef USE_HTTP_UVIO
int r = 0; int r = 0;
r = recv(curr->client_socket_descriptor, (curr->request_response_data), curr->module->max_request_size, 0); r = recv(curr->client_socket_descriptor, (curr->request_response_data), curr->module->max_request_size, 0);
@ -81,7 +82,8 @@ current_sandbox__receive_and_parse_client_request(void)
struct http_request *rh = &curr->http_request; struct http_request *rh = &curr->http_request;
if (rh->message_end) break; if (rh->message_end) break;
r = recv(curr->client_socket_descriptor, (curr->request_response_data + curr->request_response_data_length), r = recv(curr->client_socket_descriptor,
(curr->request_response_data + curr->request_response_data_length),
curr->module->max_request_size - curr->request_response_data_length, 0); curr->module->max_request_size - curr->request_response_data_length, 0);
if (r < 0) { if (r < 0) {
perror("recv2"); perror("recv2");
@ -89,7 +91,9 @@ current_sandbox__receive_and_parse_client_request(void)
} }
} }
#else #else
int r = uv_read_start((uv_stream_t *)&curr->client_libuv_stream, libuv_callbacks__on_allocate_setup_request_response_data, libuv_callbacks__on_read_parse_http_request); int r = uv_read_start((uv_stream_t *)&curr->client_libuv_stream,
libuv_callbacks__on_allocate_setup_request_response_data,
libuv_callbacks__on_read_parse_http_request);
worker_thread__process_io(); worker_thread__process_io();
if (curr->request_response_data_length == 0) return 0; if (curr->request_response_data_length == 0) return 0;
#endif #endif
@ -103,10 +107,10 @@ current_sandbox__receive_and_parse_client_request(void)
static inline int static inline int
current_sandbox__build_and_send_client_response(void) current_sandbox__build_and_send_client_response(void)
{ {
int sndsz = 0; int sndsz = 0;
struct sandbox *curr = current_sandbox__get(); struct sandbox *curr = current_sandbox__get();
int response_header_length = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN); int response_header_length = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN);
int body_length = curr->request_response_data_length - response_header_length; int body_length = curr->request_response_data_length - response_header_length;
memset(curr->request_response_data, 0, memset(curr->request_response_data, 0,
strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN)); strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN));
@ -119,8 +123,8 @@ current_sandbox__build_and_send_client_response(void)
strncpy(curr->request_response_data + sndsz + strlen("Content-type: "), HTTP_RESP_CONTTYPE_PLAIN, strncpy(curr->request_response_data + sndsz + strlen("Content-type: "), HTTP_RESP_CONTTYPE_PLAIN,
strlen(HTTP_RESP_CONTTYPE_PLAIN)); strlen(HTTP_RESP_CONTTYPE_PLAIN));
} else { } else {
strncpy(curr->request_response_data + sndsz + strlen("Content-type: "), curr->module->response_content_type, strncpy(curr->request_response_data + sndsz + strlen("Content-type: "),
strlen(curr->module->response_content_type)); curr->module->response_content_type, strlen(curr->module->response_content_type));
} }
sndsz += strlen(HTTP_RESP_CONTTYPE); sndsz += strlen(HTTP_RESP_CONTTYPE);
char len[10] = { 0 }; char len[10] = { 0 };
@ -155,7 +159,8 @@ done:
.data = curr, .data = curr,
}; };
uv_buf_t bufv = uv_buf_init(curr->request_response_data, sndsz); uv_buf_t bufv = uv_buf_init(curr->request_response_data, sndsz);
int r = uv_write(&req, (uv_stream_t *)&curr->client_libuv_stream, &bufv, 1, libuv_callbacks__on_write_wakeup_sandbox); int r = uv_write(&req, (uv_stream_t *)&curr->client_libuv_stream, &bufv, 1,
libuv_callbacks__on_write_wakeup_sandbox);
worker_thread__process_io(); worker_thread__process_io();
#endif #endif
return 0; return 0;
@ -163,7 +168,8 @@ done:
/** /**
* Sandbox execution logic * Sandbox execution logic
* Handles setup, request parsing, WebAssembly initialization, function execution, response building and sending, and cleanup * Handles setup, request parsing, WebAssembly initialization, function execution, response building and sending, and
*cleanup
**/ **/
void void
current_sandbox__main(void) current_sandbox__main(void)
@ -177,7 +183,7 @@ current_sandbox__main(void)
worker_thread__next_context = NULL; worker_thread__next_context = NULL;
softint__enable(); softint__enable();
} }
struct module *current_module = sandbox__get_module(current_sandbox); struct module *current_module = sandbox__get_module(current_sandbox);
int argument_count = module__get_argument_count(current_module); int argument_count = module__get_argument_count(current_module);
// for stdio // for stdio
@ -196,7 +202,7 @@ current_sandbox__main(void)
// Set the current_sandbox as the data the http-parser has access to // Set the current_sandbox as the data the http-parser has access to
current_sandbox->http_parser.data = current_sandbox; current_sandbox->http_parser.data = current_sandbox;
// NOTE: if more headers, do offset by that! // NOTE: if more headers, do offset by that!
int response_header_length = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN); int response_header_length = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN);
@ -210,13 +216,12 @@ current_sandbox__main(void)
current_sandbox->client_libuv_stream.data = current_sandbox; current_sandbox->client_libuv_stream.data = current_sandbox;
// Open the libuv TCP stream // Open the libuv TCP stream
r = uv_tcp_open((uv_tcp_t *)&current_sandbox->client_libuv_stream, current_sandbox->client_socket_descriptor); r = uv_tcp_open((uv_tcp_t *)&current_sandbox->client_libuv_stream, current_sandbox->client_socket_descriptor);
assert(r == 0); assert(r == 0);
#endif #endif
// If the HTTP Request returns 1, we've successfully received and parsed the HTTP request, so execute it! // If the HTTP Request returns 1, we've successfully received and parsed the HTTP request, so execute it!
if (current_sandbox__receive_and_parse_client_request() > 0) { if (current_sandbox__receive_and_parse_client_request() > 0) {
// //
current_sandbox->request_response_data_length = response_header_length; current_sandbox->request_response_data_length = response_header_length;
@ -229,7 +234,8 @@ current_sandbox__main(void)
current_sandbox__setup_arguments(argument_count); current_sandbox__setup_arguments(argument_count);
// Executing the function within the WebAssembly sandbox // Executing the function within the WebAssembly sandbox
current_sandbox->return_value = module__main(current_module, argument_count, current_sandbox->arguments_offset); current_sandbox->return_value = module__main(current_module, argument_count,
current_sandbox->arguments_offset);
// Retrieve the result from the WebAssembly sandbox, construct the HTTP response, and send to client // Retrieve the result from the WebAssembly sandbox, construct the HTTP response, and send to client
current_sandbox__build_and_send_client_response(); current_sandbox__build_and_send_client_response();
@ -279,15 +285,16 @@ sandbox__allocate_memory(struct module *module)
// can it include sandbox as well? // can it include sandbox as well?
sandbox->linear_memory_start = (char *)addr + sandbox_size; sandbox->linear_memory_start = (char *)addr + sandbox_size;
sandbox->linear_memory_size = linear_memory_size; sandbox->linear_memory_size = linear_memory_size;
sandbox->module = module; sandbox->module = module;
sandbox->sandbox_size = sandbox_size; sandbox->sandbox_size = sandbox_size;
module__acquire(module); module__acquire(module);
return sandbox; return sandbox;
} }
struct sandbox * struct sandbox *
sandbox__allocate(struct module *module, char *arguments, int socket_descriptor, const struct sockaddr *socket_address, u64 start_time) sandbox__allocate(struct module *module, char *arguments, int socket_descriptor, const struct sockaddr *socket_address,
u64 start_time)
{ {
if (!module__is_valid(module)) return NULL; if (!module__is_valid(module)) return NULL;
@ -300,7 +307,7 @@ sandbox__allocate(struct module *module, char *arguments, int socket_descriptor,
sandbox->start_time = start_time; sandbox->start_time = start_time;
// actual module instantiation! // actual module instantiation!
sandbox->arguments = (void *)arguments; sandbox->arguments = (void *)arguments;
sandbox->stack_size = module->stack_size; sandbox->stack_size = module->stack_size;
sandbox->stack_start = mmap(NULL, sandbox->stack_size, PROT_READ | PROT_WRITE, sandbox->stack_start = mmap(NULL, sandbox->stack_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0); MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
@ -314,7 +321,8 @@ sandbox__allocate(struct module *module, char *arguments, int socket_descriptor,
ps_list_init_d(sandbox); ps_list_init_d(sandbox);
// Setup the sandbox's context, stack, and instruction pointer // Setup the sandbox's context, stack, and instruction pointer
arch_context_init(&sandbox->ctxt, (reg_t)current_sandbox__main, (reg_t)(sandbox->stack_start + sandbox->stack_size)); arch_context_init(&sandbox->ctxt, (reg_t)current_sandbox__main,
(reg_t)(sandbox->stack_start + sandbox->stack_size));
return sandbox; return sandbox;
} }
@ -340,7 +348,8 @@ sandbox__free(struct sandbox *sandbox)
size_t stksz = sandbox->stack_size; size_t stksz = sandbox->stack_size;
// depending on the memory type // depending on the memory type
// free_linear_memory(sandbox->linear_memory_start, sandbox->linear_memory_size, sandbox->linear_memory_max_size); // free_linear_memory(sandbox->linear_memory_start, sandbox->linear_memory_size,
// sandbox->linear_memory_max_size);
int ret; int ret;
// mmaped memory includes sandbox structure in there. // mmaped memory includes sandbox structure in there.

@ -26,7 +26,7 @@ static const int softint__supported_signals[] = { SIGALRM, SIGUSR1 };
__thread static volatile sig_atomic_t softint__SIGALRM_count = 0; __thread static volatile sig_atomic_t softint__SIGALRM_count = 0;
__thread static volatile sig_atomic_t softint__SIGUSR_count = 0; __thread static volatile sig_atomic_t softint__SIGUSR_count = 0;
__thread volatile sig_atomic_t softint__is_disabled = 0; __thread volatile sig_atomic_t softint__is_disabled = 0;
/*************************************** /***************************************
* Externs * Externs
@ -192,7 +192,6 @@ softint__disarm_timer(void)
} }
/** /**
* Initialize software Interrupts * Initialize software Interrupts
* Register sonftint_handler to execute on SIGALRM and SIGUSR1 * Register sonftint_handler to execute on SIGALRM and SIGUSR1

Loading…
Cancel
Save