phani 5 years ago
commit a63af01ceb

@ -16,6 +16,7 @@ CFLAGS += -D_GNU_SOURCE
#CFLAGS += -DNOSTDIO
#CFLAGS += -DSTANDALONE
CFLAGS += -DUSE_UVIO
CFLAGS += -DUSE_HTTP_UVIO #-DUSE_HTTP_SYNC
CFLAGS += -DSBOX_SCALE_ALLOC
#CFLAGS += -DUSE_SYSCALL
#CFLAGS += -DPREEMPT_DISABLE

@ -58,6 +58,24 @@ get_i64(i32 offset)
return *(i64 *)address;
}
INLINE i32
get_global_i32(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
return *(i32 *)address;
}
INLINE i64
get_global_i64(i32 offset)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
return *(i64 *)address;
}
// Now setting routines
INLINE void
set_f32(i32 offset, float v)
@ -113,6 +131,24 @@ set_i64(i32 offset, i64 v)
*(i64 *)address = v;
}
INLINE void
set_global_i32(i32 offset, i32 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
*(i32 *)address = v;
}
INLINE void
set_global_i64(i32 offset, i64 v)
{
char *mem_as_chars = (char *)sandbox_lmbase;
void *address = &mem_as_chars[offset];
*(i64 *)address = v;
}
// Table handling functionality
INLINE char *
get_function_from_table(u32 idx, u32 type_id)

@ -4,6 +4,7 @@
#include <http_parser.h>
#include <types.h>
#include <uv.h>
#include <sys/uio.h>
/* all in-memory ptrs.. don't mess around with that! */
struct http_header {
@ -34,7 +35,11 @@ struct http_response {
int bodylen;
char *status;
int stlen;
#ifdef USE_HTTP_UVIO
uv_buf_t bufs[HTTP_HEADERS_MAX * 2 + 3]; //max headers, one line for status code, remaining for body!
#else
struct iovec bufs[HTTP_HEADERS_MAX * 2 + 3];
#endif
};
#endif /* SFRT_HTTP_H */

@ -8,7 +8,7 @@ int http_request_parse_sb(struct sandbox *s, size_t l);
int http_response_header_set_sb(struct sandbox *s, char *h, int len);
int http_response_body_set_sb(struct sandbox *s, char *body, int len);
int http_response_status_set_sb(struct sandbox *s, char *status, int len);
int http_response_uv_sb(struct sandbox *s);
int http_response_vector_sb(struct sandbox *s);
void http_init(void);
@ -37,9 +37,9 @@ http_response_status_set(char *status, int len)
}
static inline int
http_response_uv(void)
http_response_vector(void)
{
return http_response_uv_sb(sandbox_current());
return http_response_vector_sb(sandbox_current());
}
static inline int

@ -13,6 +13,7 @@ struct module {
mod_glb_fn_t glb_init_fn;
mod_mem_fn_t mem_init_fn;
mod_tbl_fn_t tbl_init_fn;
mod_libc_fn_t libc_init_fn;
struct indirect_table_entry indirect_table[INDIRECT_TABLE_SIZE];
@ -71,12 +72,26 @@ module_is_valid(struct module *mod)
}
static inline void
module_table_init(struct module *mod)
module_globals_init(struct module *mod)
{
// called in a sandbox.
mod->glb_init_fn();
}
static inline void
module_table_init(struct module *mod)
{
// called at module creation time (once only per module).
mod->tbl_init_fn();
}
static inline void
module_libc_init(struct module *mod, i32 env, i32 args)
{
// called in a sandbox.
mod->libc_init_fn(env, args);
}
static inline void
module_memory_init(struct module *mod)
{

@ -42,7 +42,7 @@ get_memory_string(u32 offset)
INLINE char *get_function_from_table(u32 idx, u32 type_id);
// libc/* might need to do some setup for the libc setup
void stub_init(char *modulename, i32 offset, mod_init_libc_fn_t fn);
void stub_init(i32 offset);
void runtime_init(void);
void runtime_thd_init(void);

@ -144,6 +144,15 @@ sandbox_current_set(struct sandbox *sbox)
module_indirect_table = sbox->mod->indirect_table;
}
static inline void
sandbox_current_check(void)
{
struct sandbox *c = sandbox_current();
assert(c && c->linear_start == sandbox_lmbase && c->linear_size == sandbox_lmbound);
assert(c->mod->indirect_table == module_indirect_table);
}
static inline struct module *
sandbox_module(struct sandbox *s)
{
@ -184,9 +193,12 @@ sandbox_args(void)
//void sandbox_run(struct sandbox *s);
void *sandbox_run_func(void *data);
struct sandbox *sandbox_schedule(void);
struct sandbox *sandbox_schedule(int interrupt);
void sandbox_block(void);
void sandbox_wakeup(sandbox_t *sb);
// called in sandbox_entry() before and after fn() execution
// for http request/response processing using uvio
void sandbox_block_http(void);
void sandbox_response(void);
// should be the entry-point for each sandbox so it can do per-sandbox mem/etc init.

@ -71,7 +71,7 @@ void populate_table(void);
// memory/* also provides the table access functions
// TODO: Change this to use a compiled in size
#define INDIRECT_TABLE_SIZE 1024
#define INDIRECT_TABLE_SIZE (1<<10)
struct indirect_table_entry {
u32 type_id;
@ -90,7 +90,7 @@ typedef i32 (*mod_main_fn_t)(i32 a, i32 b);
typedef void (*mod_glb_fn_t)(void);
typedef void (*mod_mem_fn_t)(void);
typedef void (*mod_tbl_fn_t)(void);
typedef void (*mod_init_libc_fn_t)(i32, i32);
typedef void (*mod_libc_fn_t)(i32, i32);
typedef enum {
MOD_ARG_MODPATH = 0,
@ -104,7 +104,7 @@ typedef enum {
#define MOD_GLB_FN "populate_globals"
#define MOD_MEM_FN "populate_memory"
#define MOD_TBL_FN "populate_table"
#define MOD_INIT_LIBC_FN "wasmf___init_libc"
#define MOD_LIBC_FN "wasmf___init_libc"
#define MOD_MAX_ARGS 16
#define MOD_ARG_MAX_SZ 64
@ -116,7 +116,7 @@ typedef enum {
#define JSON_ELE_MAX 16
// FIXME: some naive work-stealing here..
#define SBOX_PULL_MAX 16
#define SBOX_PULL_MAX 1
#define SBOX_MAX_OPEN 32
#define SBOX_PREOPEN_MAGIC (707707707) // reads lol lol lol upside down
@ -157,4 +157,9 @@ typedef enum {
#define HTTP_HEADER_MAXSZ 32
#define HTTP_HEADERVAL_MAXSZ 64
#define HTTP_RESP_200OK "HTTP/1.1 200 OK\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_CONTTYPE_PLAIN "text/plain"
#endif /* SFRT_TYPES_H */

@ -163,12 +163,13 @@ http_response_status_set_sb(struct sandbox *c, char *status, int len)
}
int
http_response_uv_sb(struct sandbox *c)
http_response_vector_sb(struct sandbox *c)
{
int nb = 0;
#ifndef STANDALONE
struct http_response *r = &c->rsi;
#ifdef USE_HTTP_UVIO
r->bufs[nb] = uv_buf_init(r->status, r->stlen);
nb++;
@ -183,6 +184,27 @@ http_response_uv_sb(struct sandbox *c)
r->bufs[nb] = uv_buf_init(r->status + r->stlen - 2, 2); //for crlf
nb++;
}
#else
r->bufs[nb].iov_base = r->status;
r->bufs[nb].iov_len = r->stlen;
nb++;
for (int i = 0; i < r->nheaders; i++) {
r->bufs[nb].iov_base = r->headers[i].hdr;
r->bufs[nb].iov_len = r->headers[i].len;
nb++;
}
if (r->body) {
r->bufs[nb].iov_base = r->body;
r->bufs[nb].iov_len = r->bodylen;
nb++;
r->bufs[nb].iov_base = r->status + r->stlen - 2;
r->bufs[nb].iov_len = 2;
nb++;
}
#endif
#endif
return nb;

@ -2,6 +2,7 @@
/* code from https://github.com/gwsystems/silverfish/blob/master/runtime/libc/libc_backing.c */
#include <runtime.h>
#include <sandbox.h>
#include <sys/types.h>
#include <sys/socket.h>
@ -32,9 +33,41 @@
// offset = a WASM ptr to memory the runtime can use
void
stub_init(char *program_name, i32 offset, mod_init_libc_fn_t libcfn)
stub_init(i32 offset)
{
printf("Don't think we should reinit libc! so ignore for now!\n");
// What program name will we put in the auxiliary vectors
char *program_name = sandbox_current()->mod->name;
// Copy the program name into WASM accessible memory
i32 program_name_offset = offset;
strcpy(get_memory_ptr_for_runtime(offset, sizeof(program_name)), program_name);
offset += sizeof(program_name);
// The construction of this is:
// evn1, env2, ..., NULL, auxv_n1, auxv_1, auxv_n2, auxv_2 ..., NULL
i32 env_vec[] = {
// Env variables would live here, but we don't supply any
0,
// We supply only the bare minimum AUX vectors
AT_PAGESZ,
WASM_PAGE_SIZE,
AT_UID,
UID,
AT_EUID,
UID,
AT_GID,
GID,
AT_EGID,
GID,
AT_SECURE,
0,
AT_RANDOM,
(i32) rand(), // It's pretty stupid to use rand here, but w/e
0,
};
i32 env_vec_offset = offset;
memcpy(get_memory_ptr_for_runtime(env_vec_offset, sizeof(env_vec)), env_vec, sizeof(env_vec));
module_libc_init(sandbox_current()->mod, env_vec_offset, program_name_offset);
}
// Emulated syscall implementations

@ -1,5 +1,6 @@
#ifdef USE_UVIO
#include <runtime.h>
#include <sandbox.h>
#include <uv.h>
#include <http.h>
@ -30,9 +31,41 @@
// offset = a WASM ptr to memory the runtime can use
void
stub_init(char *program_name, i32 offset, mod_init_libc_fn_t libcfn)
stub_init(i32 offset)
{
printf("Don't think we should reinit libc! so ignore for now!\n");
// What program name will we put in the auxiliary vectors
char *program_name = sandbox_current()->mod->name;
// Copy the program name into WASM accessible memory
i32 program_name_offset = offset;
strcpy(get_memory_ptr_for_runtime(offset, sizeof(program_name)), program_name);
offset += sizeof(program_name);
// The construction of this is:
// evn1, env2, ..., NULL, auxv_n1, auxv_1, auxv_n2, auxv_2 ..., NULL
i32 env_vec[] = {
// Env variables would live here, but we don't supply any
0,
// We supply only the bare minimum AUX vectors
AT_PAGESZ,
WASM_PAGE_SIZE,
AT_UID,
UID,
AT_EUID,
UID,
AT_GID,
GID,
AT_EGID,
GID,
AT_SECURE,
0,
AT_RANDOM,
(i32) rand(), // It's pretty stupid to use rand here, but w/e
0,
};
i32 env_vec_offset = offset;
memcpy(get_memory_ptr_for_runtime(env_vec_offset, sizeof(env_vec)), env_vec, sizeof(env_vec));
module_libc_init(sandbox_current()->mod, env_vec_offset, program_name_offset);
}
// Emulated syscall implementations
@ -120,13 +153,11 @@ wasm_write(i32 fd, i32 buf_offset, i32 buf_size)
uv_fs_t req = UV_FS_REQ_INIT();
char* buf = get_memory_ptr_void(buf_offset, buf_size);
printf("[%p] start[%d:%d, n%d]\n", uv_fs_get_data(&req), fd, f, buf_size);
uv_buf_t bufv = uv_buf_init(buf, buf_size);
uv_fs_write(runtime_uvio(), &req, f, &bufv, 1, -1, wasm_fs_callback);
sandbox_block();
int ret = uv_fs_get_result(&req);
printf("[%p] end[%d]\n", uv_fs_get_data(&req), ret);
uv_fs_req_cleanup(&req);
return ret;

@ -20,6 +20,18 @@ u32 ncores = 0, sbox_ncores = 0, sbox_core_st = 0;
pthread_t rtthd[SBOX_NCORES];
static unsigned long long
get_time()
{
struct timeval Tp;
int stat;
stat = gettimeofday (&Tp, NULL);
if (stat != 0)
printf ("Error return from gettimeofday: %d", stat);
return (Tp.tv_sec * 1000000 + Tp.tv_usec);
}
static void
usage(char *cmd)
{
@ -141,7 +153,11 @@ main(int argc, char** argv)
/* in current dir! */
struct module *m = module_alloc(args, args, ac, 0, 0, 0, 0, 0, 0);
assert(m);
//unsigned long long st = get_time(), en;
struct sandbox *s = sandbox_alloc(m, args, 0, NULL);
//en = get_time();
//fprintf(stderr, "%llu\n", en - st);
exit(0);
#endif

@ -91,9 +91,8 @@ module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap,
mod->entry_fn = (mod_main_fn_t)dlsym(mod->dl_handle, MOD_MAIN_FN);
if (mod->entry_fn == NULL) goto dl_error;
// TODO: don't think this is necessary or implemented.
//mod->glb_init_fn = (mod_glb_fn_t)dlsym(mod->dl_handle, MOD_GLB_FN);
//if (mod->glb_init_fn == NULL) goto dl_error;
mod->glb_init_fn = (mod_glb_fn_t)dlsym(mod->dl_handle, MOD_GLB_FN);
if (mod->glb_init_fn == NULL) goto dl_error;
mod->mem_init_fn = (mod_mem_fn_t)dlsym(mod->dl_handle, MOD_MEM_FN);
if (mod->mem_init_fn == NULL) goto dl_error;
@ -101,6 +100,9 @@ module_alloc(char *modname, char *modpath, i32 nargs, u32 stacksz, u32 maxheap,
mod->tbl_init_fn = (mod_tbl_fn_t)dlsym(mod->dl_handle, MOD_TBL_FN);
if (mod->tbl_init_fn == NULL) goto dl_error;
mod->libc_init_fn = (mod_libc_fn_t)dlsym(mod->dl_handle, MOD_LIBC_FN);
if (mod->libc_init_fn == NULL) goto dl_error;
strncpy(mod->name, modname, MOD_NAME_MAX);
strncpy(mod->path, modpath, MOD_PATH_MAX);

@ -1,4 +1,5 @@
#include <runtime.h>
#include <sys/mman.h>
#include <types.h>
#include <sandbox.h>
#include <arch/context.h>
@ -87,10 +88,12 @@ sandbox_io_nowait(void)
}
struct sandbox *
sandbox_schedule(void)
sandbox_schedule(int interrupt)
{
struct sandbox *s = NULL;
if (ps_list_head_empty(&runq)) {
// this is in an interrupt context, don't steal work here!
if (interrupt) return NULL;
if (sandbox_pull() == 0) {
//debuglog("[null: null]\n");
return NULL;
@ -113,7 +116,7 @@ sandbox_local_free(unsigned int n)
{
int i = 0;
while (i < n) {
while (i < n && !ps_list_head_empty(&endq)) {
i++;
struct sandbox *s = ps_list_head_first_d(&endq, struct sandbox);
if (!s) break;
@ -130,7 +133,7 @@ sandbox_schedule_io(void)
if (!in_callback) sandbox_io_nowait();
softint_disable();
struct sandbox *s = sandbox_schedule();
struct sandbox *s = sandbox_schedule(0);
softint_enable();
assert(s == NULL || s->state == SANDBOX_RUNNABLE);
@ -143,11 +146,12 @@ sandbox_wakeup(sandbox_t *s)
#ifndef STANDALONE
softint_disable();
debuglog("[%p: %s]\n", s, s->mod->name);
// perhaps 2 lists in the sandbox to make sure sandbox is either in runlist or waitlist..
if (s->state != SANDBOX_BLOCKED) goto done;
assert(s->state == SANDBOX_BLOCKED);
assert(ps_list_singleton_d(s));
s->state = SANDBOX_RUNNABLE;
ps_list_head_append_d(&runq, s);
done:
softint_enable();
#endif
}
@ -156,13 +160,12 @@ void
sandbox_block(void)
{
#ifndef STANDALONE
// perhaps 2 lists in the sandbox to make sure sandbox is either in runlist or waitlist..
assert(in_callback == 0);
softint_disable();
struct sandbox *c = sandbox_current();
ps_list_rem_d(c);
c->state = SANDBOX_BLOCKED;
struct sandbox *s = sandbox_schedule();
struct sandbox *s = sandbox_schedule(0);
debuglog("[%p: %s, %p: %s]\n", c, c->mod->name, s, s ? s->mod->name: "");
softint_enable();
sandbox_switch(s);
@ -171,6 +174,24 @@ sandbox_block(void)
#endif
}
void
sandbox_block_http(void)
{
#ifdef USE_HTTP_UVIO
#ifdef USE_HTTP_SYNC
// realistically, we're processing all async I/O on this core when a sandbox blocks on http processing, not 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!
uv_run(runtime_uvio(), UV_RUN_DEFAULT);
#else
sandbox_block();
#endif
#else
assert(0);
//it should not be called if not using uvio for http
#endif
}
void __attribute__((noinline)) __attribute__((noreturn))
sandbox_switch_preempt(void)
{
@ -248,9 +269,11 @@ sandbox_exit(void)
sandbox_local_stop(curr);
curr->state = SANDBOX_RETURNED;
// free resources from "main function execution", as stack still in use.
struct sandbox *n = sandbox_schedule();
struct sandbox *n = sandbox_schedule(0);
assert(n != curr);
softint_enable();
//unmap linear memory only!
munmap(curr->linear_start, SBOX_MAX_MEM + PAGE_SIZE);
//sandbox_local_end(curr);
sandbox_switch(n);
#else

@ -21,7 +21,7 @@ sandbox_memory_map(struct module *m)
if (lm_sz + sb_sz > mem_sz) return NULL;
assert(round_up_to_page(sb_sz) == sb_sz);
unsigned long rw_sz = sb_sz + lm_sz;
void *addr = mmap(NULL, mem_sz + /* guard page */ PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
void *addr = mmap(NULL, sb_sz + mem_sz + /* guard page */ PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) return NULL;
void *addr_rw = mmap(addr, sb_sz + lm_sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
@ -46,7 +46,6 @@ sandbox_args_setup(i32 argc)
{
struct sandbox *curr = sandbox_current();
char *args = sandbox_args();
if (!args) return;
// whatever gregor has, to be able to pass args to a module!
curr->args_offset = sandbox_lmbound;
@ -66,6 +65,7 @@ sandbox_args_setup(i32 argc)
string_off += str_sz;
}
stub_init(string_off);
}
static inline void
@ -133,11 +133,11 @@ sandbox_client_request_get(void)
struct sandbox *curr = sandbox_current();
curr->rr_data_len = 0;
#ifndef USE_UVIO
#ifndef USE_HTTP_UVIO
int r = 0;
r = recv(curr->csock, (curr->req_resp_data), curr->mod->max_req_sz, 0);
if (r <= 0) {
perror("recv");
if (r < 0) perror("recv1");
return r;
}
while (r > 0) {
@ -146,15 +146,15 @@ sandbox_client_request_get(void)
struct http_request *rh = &curr->rqi;
if (rh->message_end) break;
r = recv(curr->csock, (curr->req_resp_data + r), curr->mod->max_req_sz - r, 0);
r = recv(curr->csock, (curr->req_resp_data + curr->rr_data_len), curr->mod->max_req_sz - curr->rr_data_len, 0);
if (r < 0) {
perror("recv");
perror("recv2");
return r;
}
}
#else
int r = uv_read_start((uv_stream_t *)&curr->cuv, sb_alloc_callback, sb_read_callback);
sandbox_block();
sandbox_block_http();
if (curr->rr_data_len == 0) return 0;
#endif
@ -168,66 +168,118 @@ static inline int
sandbox_client_response_set(void)
{
#ifndef STANDALONE
int sndsz = 0;
struct sandbox *curr = sandbox_current();
#ifndef USE_UVIO
strcpy(curr->req_resp_data + curr->rr_data_len, "HTTP/1.1 200 OK\r\n");
// TODO: response set in req_resp_data
curr->rr_data_len += strlen("HTTP/1.1 200 OK\r\n");
int r = send(curr->csock, curr->req_resp_data, curr->rr_data_len, 0);
if (r < 0) perror("send");
#else
int bodylen = curr->rr_data_len;
if (bodylen > 0) {
http_response_body_set(curr->req_resp_data, bodylen);
char len[16] = { 0 };
sprintf(len, "%d", bodylen);
//content-length = body length
char *key = curr->req_resp_data + curr->rr_data_len;
int lenlen = strlen("content-length: "), dlen = strlen(len);
strcpy(key, "content-length: ");
strncat(key + lenlen, len, dlen);
strncat(key + lenlen + dlen, "\r\n", 2);
http_response_header_set(key, lenlen + dlen + 2);
curr->rr_data_len += lenlen + dlen + 2;
//content-type as set in the headers.
key = curr->req_resp_data + curr->rr_data_len;
strcpy(key, "content-type: ");
lenlen = strlen("content-type: ");
dlen = strlen(curr->mod->rspctype);
if (dlen == 0) {
int l = strlen("text/plain\r\n\r\n");
strncat(key + lenlen, "text/plain\r\n\r\n", l);
http_response_header_set(key, lenlen + l);
curr->rr_data_len += lenlen + l;
} else {
strncat(key + lenlen, curr->mod->rspctype, dlen);
strncat(key + lenlen + dlen, "\r\n\r\n", 4);
http_response_header_set(key, lenlen + dlen + 4);
curr->rr_data_len += lenlen + dlen + 4;
int rsp_hdr_len = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN);
int bodylen = curr->rr_data_len - rsp_hdr_len;
memset(curr->req_resp_data, 0, strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN));
strncpy(curr->req_resp_data, HTTP_RESP_200OK, strlen(HTTP_RESP_200OK));
sndsz += strlen(HTTP_RESP_200OK);
if (bodylen == 0) goto done;
strncpy(curr->req_resp_data + sndsz, HTTP_RESP_CONTTYPE, strlen(HTTP_RESP_CONTTYPE));
if (strlen(curr->mod->rspctype) <= 0) {
strncpy(curr->req_resp_data + sndsz + strlen("Content-type: "), HTTP_RESP_CONTTYPE_PLAIN, strlen(HTTP_RESP_CONTTYPE_PLAIN));
} else {
strncpy(curr->req_resp_data + sndsz + strlen("Content-type: "), curr->mod->rspctype, strlen(curr->mod->rspctype));
}
sndsz += strlen(HTTP_RESP_CONTTYPE);
char len[10] = { 0 };
sprintf(len, "%d", bodylen);
strncpy(curr->req_resp_data + sndsz, HTTP_RESP_CONTLEN, strlen(HTTP_RESP_CONTLEN));
strncpy(curr->req_resp_data + sndsz + strlen("Content-length: "), len, strlen(len));
sndsz += strlen(HTTP_RESP_CONTLEN);
sndsz += bodylen;
done:
assert(sndsz == curr->rr_data_len);
#ifndef USE_HTTP_UVIO
int r = send(curr->csock, curr->req_resp_data, sndsz, 0);
if (r < 0) {
perror("send");
return -1;
}
while (r < sndsz) {
int s = send(curr->csock, curr->req_resp_data + r, sndsz - r, 0);
if (s < 0) {
perror("send");
return -1;
}
//TODO - other headers requested in module!
r += s;
}
char *st = curr->req_resp_data + curr->rr_data_len;
strcpy(st, "HTTP/1.1 200 OK\r\n");
curr->rr_data_len += strlen("HTTP/1.1 200 OK\r\n");
http_response_status_set(st, strlen("HTTP/1.1 200 OK\r\n"));
#else
uv_write_t req = { .data = curr, };
int n = http_response_uv();
int r = uv_write(&req, (uv_stream_t *)&curr->cuv, curr->rsi.bufs, n, sb_write_callback);
sandbox_block();
uv_buf_t bufv = uv_buf_init(curr->req_resp_data, sndsz);
int r = uv_write(&req, (uv_stream_t *)&curr->cuv, &bufv, 1, sb_write_callback);
sandbox_block_http();
#endif
return r;
#else
return 0;
#endif
}
//static inline int
//sandbox_client_response_set(void)
//{
//#ifndef STANDALONE
// struct sandbox *curr = sandbox_current();
//
// int bodylen = curr->rr_data_len;
// if (bodylen > 0) {
// http_response_body_set(curr->req_resp_data, bodylen);
// char len[16] = { 0 };
// sprintf(len, "%d", bodylen);
// //content-length = body length
// char *key = curr->req_resp_data + curr->rr_data_len;
// int lenlen = strlen("content-length: "), dlen = strlen(len);
// strcpy(key, "content-length: ");
// strncat(key + lenlen, len, dlen);
// strncat(key + lenlen + dlen, "\r\n", 2);
// http_response_header_set(key, lenlen + dlen + 2);
// curr->rr_data_len += lenlen + dlen + 2;
//
// //content-type as set in the headers.
// key = curr->req_resp_data + curr->rr_data_len;
// strcpy(key, "content-type: ");
// lenlen = strlen("content-type: ");
// dlen = strlen(curr->mod->rspctype);
// if (dlen == 0) {
// int l = strlen("text/plain\r\n\r\n");
// strncat(key + lenlen, "text/plain\r\n\r\n", l);
// http_response_header_set(key, lenlen + l);
// curr->rr_data_len += lenlen + l;
// } else {
// strncat(key + lenlen, curr->mod->rspctype, dlen);
// strncat(key + lenlen + dlen, "\r\n\r\n", 4);
// http_response_header_set(key, lenlen + dlen + 4);
// curr->rr_data_len += lenlen + dlen + 4;
// }
// //TODO - other headers requested in module!
// }
//
// char *st = curr->req_resp_data + curr->rr_data_len;
// strcpy(st, "HTTP/1.1 200 OK\r\n");
// curr->rr_data_len += strlen("HTTP/1.1 200 OK\r\n");
//
// http_response_status_set(st, strlen("HTTP/1.1 200 OK\r\n"));
// int n = http_response_vector();
//#ifndef USE_HTTP_UVIO
// int r = writev(curr->csock, curr->rsi.bufs, n);
// if (r < 0) perror("writev");
//#else
// uv_write_t req = { .data = curr, };
// int r = uv_write(&req, (uv_stream_t *)&curr->cuv, curr->rsi.bufs, n, sb_write_callback);
// sandbox_block_http();
//#endif
// return 0;
//#else
// return 0;
//#endif
//}
void
sandbox_entry(void)
{
@ -249,12 +301,17 @@ sandbox_entry(void)
assert(f == 1);
f = io_handle_open(2);
assert(f == 2);
sandbox_args_setup(argc);
#ifndef STANDALONE
http_parser_init(&curr->hp, HTTP_REQUEST);
curr->hp.data = curr;
#ifdef USE_UVIO
// NOTE: if more headers, do offset by that!
int rsp_hdr_len = strlen(HTTP_RESP_200OK) + strlen(HTTP_RESP_CONTTYPE) + strlen(HTTP_RESP_CONTLEN);
#ifdef USE_HTTP_UVIO
#ifndef USE_UVIO
printf("UVIO not enabled!\n");
assert(0);
#endif
int r = uv_tcp_init(runtime_uvio(), (uv_tcp_t *)&curr->cuv);
assert(r == 0);
curr->cuv.data = curr;
@ -264,21 +321,27 @@ sandbox_entry(void)
if (sandbox_client_request_get() > 0)
#endif
{
curr->rr_data_len = 0; // TODO: do this on first write to body.
#ifndef STANDALONE
curr->rr_data_len = rsp_hdr_len; // TODO: do this on first write to body.
#else
curr->rr_data_len = 0;
#endif
alloc_linear_memory();
// perhaps only initialized for the first instance? or TODO!
//module_table_init(curr_mod);
module_globals_init(curr_mod);
module_memory_init(curr_mod);
sandbox_args_setup(argc);
curr->retval = module_entry(curr_mod, argc, curr->args_offset);
sandbox_client_response_set();
}
#ifndef STANDALONE
#ifdef USE_UVIO
#ifdef USE_HTTP_UVIO
uv_close((uv_handle_t *)&curr->cuv, sb_close_callback);
sandbox_block();
sandbox_block_http();
#else
close(curr->csock);
#endif
@ -335,6 +398,10 @@ sandbox_free(struct sandbox *sb)
// TODO: this needs to be enhanced. you may be killing a sandbox when its in any other execution states.
if (sb->state != SANDBOX_RETURNED) return;
int sz = sizeof(struct sandbox);
#ifndef STANDALONE
sz += sb->mod->max_rr_sz;
#endif
module_release(sb->mod);
// TODO free(sb->args);
@ -342,10 +409,10 @@ sandbox_free(struct sandbox *sb)
size_t stksz = sb->stack_size;
// depending on the memory type
free_linear_memory(sb->linear_start, sb->linear_size, sb->linear_max_size);
//free_linear_memory(sb->linear_start, sb->linear_size, sb->linear_max_size);
// mmaped memory includes sandbox structure in there.
ret = munmap(sb, SBOX_MAX_MEM + PAGE_SIZE);
ret = munmap(sb, sz);
if (ret) perror("munmap sandbox");
// remove stack!

@ -67,7 +67,7 @@ softint_alarm_schedule(void *u)
if (curr == NULL) goto done;
// find a next sandbox to run..
struct sandbox *next = sandbox_schedule();
struct sandbox *next = sandbox_schedule(1);
if (next == NULL) goto done;
if (next == curr) goto done; // only this sandbox to schedule.. return to it!
// save the current sandbox, state from uc!

@ -2,7 +2,7 @@ include Makefile.inc
BENCH_DIR=../../silverfish/code_benches/
TESTS=fibonacci #empty work
TESTS=fibonacci empty work work1k work10k work100k work1m
#TESTS=forever filesys sockserver sockclient empty
TESTSRT=$(TESTS:%=%_rt)
BENCHES=adpcm basic_math binarytrees bitcount blowfish crc dijkstra fft function_pointers \
@ -38,6 +38,7 @@ clean:
${WASMCC} ${$(@:%_sf=%)_CFLAGS} ${WASMCFLAGS} ${OPTFLAGS} ${BENCH_DIR}/$(@:%_sf=%)/*.c $(DUMMY) -o ${TMP_DIR}/$(@:%_sf=%).wasm
${SFCC} ${TMP_DIR}/$(@:%_sf=%).wasm -o ${TMP_DIR}/$(@:%_sf=%).bc
${CC} ${CFLAGS} ${OPTFLAGS} -D${USE_MEM} ${TMP_DIR}/$(@:%_sf=%).bc ${MEMC} ${RT_LIBC} ${RT_RT} -lm -o ${TMP_DIR}/$(@:%_sf=%)_wasm.out
${SFCC} --inline-constant-globals --runtime-globals ${TMP_DIR}/$(@:%_sf=%).wasm -o ${TMP_DIR}/$(@:%_sf=%).bc
${CC} --shared -fPIC ${OPTFLAGS} -I${ART_INC} -D${USE_MEM} ${TMP_DIR}/$(@:%_sf=%).bc ${AMEMC} ${WASMISA} -lm -o ${TMP_DIR}/$(@:%_sf=%)_wasm.so
@cp ${TMP_DIR}/$(@:%_sf=%)_wasm.so ${ABIN_DIR}
# @rm -rf ${TMP_DIR}
@ -48,6 +49,7 @@ clean:
${WASMCC} ${$(@:%_rt=%)_CFLAGS} ${WASMCFLAGS} ${OPTFLAGS} $(@:%_rt=%)/*.c $(DUMMY) -o ${TMP_DIR}/$(@:%_rt=%).wasm
${SFCC} ${TMP_DIR}/$(@:%_rt=%).wasm -o ${TMP_DIR}/$(@:%_rt=%).bc
${CC} ${CFLAGS} ${OPTFLAGS} -D${USE_MEM} ${TMP_DIR}/$(@:%_rt=%).bc ${MEMC} ${RT_LIBC} ${RT_RT} -o ${TMP_DIR}/$(@:%_rt=%)_wasm.out
${SFCC} --inline-constant-globals --runtime-globals ${TMP_DIR}/$(@:%_rt=%).wasm -o ${TMP_DIR}/$(@:%_rt=%).bc
${CC} --shared -fPIC ${OPTFLAGS} -I${ART_INC} -D${USE_MEM} ${TMP_DIR}/$(@:%_rt=%).bc ${AMEMC} ${WASMISA} -o ${TMP_DIR}/$(@:%_rt=%)_wasm.so
@cp ${TMP_DIR}/$(@:%_rt=%)_wasm.so ${ABIN_DIR}
# @rm -rf ${TMP_DIR}

@ -13,11 +13,11 @@ main(int argc, char **argv)
{
unsigned long n = 0, r;
scanf("%lu", &n);
unsigned long long st = get_time(), en;
// unsigned long long st = get_time(), en;
r = fib(n);
en = get_time();
fprintf(stderr, "%lu\n", r);
// en = get_time();
printf("%lu\n", r);
print_time(st, en);
// print_time(st, en);
return 0;
}

@ -25,7 +25,7 @@ MAXNUM=$2
tmp1_cnt=${MAXNUM}
while [ ${tmp1_cnt} -gt 0 ]; do
while [ ${tmp1_cnt} -gt 28 ]; do
testeach ./fibonacci_$1.out ${tmp1_cnt}
tmp1_cnt=$((tmp1_cnt - 1))
done

@ -0,0 +1,13 @@
{
"active" : "yes",
"name" : "fibonacci",
"path" : "fibonacci_wasm.so",
"port" : 10000,
"argsize" : 1,
"http-req-headers" : [ ],
"http-req-content-type" : "text/plain",
"http-req-size": 1024,
"http-resp-headers" : [ ],
"http-resp-size" : 1024,
"http-resp-content-type" : "text/plain"
}

@ -6,7 +6,7 @@
"argsize" : 1,
"http-req-headers" : [ ],
"http-req-content-type" : "text/plain",
"http-req-size": 1048576,
"http-req-size": 1048776,
"http-resp-headers" : [ ],
"http-resp-size" : 1048776,
"http-resp-content-type" : "text/plain"

@ -0,0 +1,13 @@
{
"active" : "yes",
"name" : "work100k",
"path" : "work100k_wasm.so",
"port" : 10000,
"argsize" : 1,
"http-req-headers" : [ ],
"http-req-content-type" : "text/plain",
"http-req-size": 102600,
"http-resp-headers" : [ ],
"http-resp-size" : 102600,
"http-resp-content-type" : "text/plain"
}

@ -0,0 +1,13 @@
{
"active" : "yes",
"name" : "work10k",
"path" : "work10k_wasm.so",
"port" : 10000,
"argsize" : 1,
"http-req-headers" : [ ],
"http-req-content-type" : "text/plain",
"http-req-size": 10480,
"http-resp-headers" : [ ],
"http-resp-size" : 10480,
"http-resp-content-type" : "text/plain"
}

@ -0,0 +1,13 @@
{
"active" : "yes",
"name" : "work1k",
"path" : "work1k_wasm.so",
"port" : 10000,
"argsize" : 1,
"http-req-headers" : [ ],
"http-req-content-type" : "text/plain",
"http-req-size": 1200,
"http-resp-headers" : [ ],
"http-resp-size" : 1200,
"http-resp-content-type" : "text/plain"
}

@ -0,0 +1,13 @@
{
"active" : "yes",
"name" : "work1m",
"path" : "work1m_wasm.so",
"port" : 10000,
"argsize" : 1,
"http-req-headers" : [ ],
"http-req-content-type" : "text/plain",
"http-req-size": 1048776,
"http-resp-headers" : [ ],
"http-resp-size" : 1048776,
"http-resp-content-type" : "text/plain"
}

@ -2,24 +2,9 @@
#include <stdio.h>
#include <string.h>
#define CPU_CYCS 2100
#ifndef MAX_BUF
#define MAX_BUF (1024*1024*1) //1m
#define ITERS_15US 125500
#define MULTIPLE 5
#define SPIN_ITERS (ITERS_15US*MULTIPLE)
__attribute__((optnone)) static void
wrk(void)
{
unsigned int spin = 0;
while (spin < SPIN_ITERS) {
//__asm__ __volatile__("nop": : :"memory");
spin++;
}
}
#endif
//__attribute__((optnone)) int
int

@ -0,0 +1,24 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_BUF 102400
//__attribute__((optnone)) int
int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
return 0;
}

@ -0,0 +1,24 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_BUF 10240
//__attribute__((optnone)) int
int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
return 0;
}

@ -0,0 +1,24 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_BUF 1024
//__attribute__((optnone)) int
int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
return 0;
}

@ -0,0 +1,24 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_BUF (1024*1024*1) //1m
//__attribute__((optnone)) int
int
main(void)
{
char *d = malloc(MAX_BUF + 1);
int r = read(0, d, MAX_BUF);
// unsigned long long st = rdtsc(), en = 0;
// wrk();
// en = rdtsc();
// if (r <= 0) printf("%llu\n", en > st ? (en - st)/CPU_CYCS : -1);
if (r < 0) printf("E\n");
else if (r <= 1) printf("D\n");
else write(1, d, r);
return 0;
}
Loading…
Cancel
Save