refactor: Assorted refactors and add start_time to request

main
Sean McBride 5 years ago
parent 6946b08644
commit ae93435e2a

@ -84,6 +84,7 @@ struct sandbox_request {
char * args; char * args;
int sock; int sock;
struct sockaddr *addr; struct sockaddr *addr;
unsigned long long int start_time_in_cycles;
}; };
typedef struct sandbox_request sbox_request_t; typedef struct sandbox_request sbox_request_t;
#else #else
@ -108,7 +109,12 @@ typedef struct sandbox sandbox_t;
void sandbox_run(sbox_request_t *s); void sandbox_run(sbox_request_t *s);
static inline sbox_request_t * static inline sbox_request_t *
sbox_request_alloc(struct module *mod, char *args, int sock, const struct sockaddr *addr) sbox_request_alloc(
struct module *mod,
char *args,
int sock,
const struct sockaddr *addr,
unsigned long long int start_time_in_cycles)
{ {
#ifndef STANDALONE #ifndef STANDALONE
#ifdef SBOX_SCALE_ALLOC #ifdef SBOX_SCALE_ALLOC
@ -118,6 +124,7 @@ sbox_request_alloc(struct module *mod, char *args, int sock, const struct sockad
s->args = args; s->args = args;
s->sock = sock; s->sock = sock;
s->addr = (struct sockaddr *)addr; s->addr = (struct sockaddr *)addr;
s->start_time_in_cycles = start_time_in_cycles;
sandbox_run(s); sandbox_run(s);
return s; return s;
#else /* SBOX_SCALE_ALLOC */ #else /* SBOX_SCALE_ALLOC */
@ -147,50 +154,56 @@ sandbox_current_set(struct sandbox *sbox)
module_indirect_table = sbox->mod->indirect_table; module_indirect_table = sbox->mod->indirect_table;
} }
/**
* @brief Safety checks around linear memory base and bounds and the Wasm function indirect table
*/
static inline void static inline void
sandbox_current_check(void) sandbox_current_check(void)
{ {
struct sandbox *c = sandbox_current(); struct sandbox *c = sandbox_current();
assert(c && c->linear_start == sandbox_lmbase && c->linear_size == sandbox_lmbound); assert(c && c->linear_start == sandbox_lmbase && c->linear_size == sandbox_lmbound);
assert(c->mod->indirect_table == module_indirect_table); assert(c->mod->indirect_table == module_indirect_table);
} }
/**
* @return the module of the current sandbox
*/
static inline struct module * static inline struct module *
sandbox_module(struct sandbox *s) sandbox_module(struct sandbox *s)
{ {
if (!s) return NULL; if (!s) return NULL;
return s->mod; return s->mod;
} }
extern void sandbox_local_end(struct sandbox *s); extern void sandbox_local_end(struct sandbox *s);
/**
* @brief Switches to the next sandbox, placing the current sandbox of the completion queue if in RETURNED state
* @param next The Sandbox Context to switch to or NULL
* @return void
*/
static inline void static inline void
sandbox_switch(struct sandbox *next) sandbox_switch(struct sandbox *next_sandbox)
{ {
arch_context_t *n = next == NULL ? NULL : &next->ctxt; arch_context_t *next_register_context = next_sandbox == NULL ? NULL : &next_sandbox->ctxt;
// disable interrupts (signals)
softint_disable(); softint_disable();
// switch sandbox (register context & base/bound/table) struct sandbox *current_sandbox = sandbox_current();
struct sandbox *curr = sandbox_current(); arch_context_t *current_register_context = current_sandbox == NULL ? NULL : &current_sandbox->ctxt;
arch_context_t *c = curr == NULL ? NULL : &curr->ctxt; sandbox_current_set(next_sandbox);
sandbox_current_set(next); // If the current sandbox we're switching from is in a RETURNED state, add to completion queue
if (curr && curr->state == SANDBOX_RETURNED) sandbox_local_end(curr); if (current_sandbox && current_sandbox->state == SANDBOX_RETURNED) sandbox_local_end(current_sandbox);
// save current's registers and restore next's registers. next_context = next_register_context;
next_context = n; arch_context_switch(current_register_context, next_register_context);
arch_context_switch(c, n);
next_context = NULL;
// enable interrupts (signals)
softint_enable(); softint_enable();
} }
/**
* @return the arguments of the current sandbox
*/
static inline char * static inline char *
sandbox_args(void) sandbox_args(void)
{ {
struct sandbox *c = sandbox_current(); struct sandbox *c = sandbox_current();
return (char *)c->args; return (char *)c->args;
} }

@ -15,8 +15,8 @@ struct deque_sandbox *global_deque;
pthread_mutex_t global_deque_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t global_deque_mutex = PTHREAD_MUTEX_INITIALIZER;
int epoll_file_descriptor; int epoll_file_descriptor;
__thread static struct ps_list_head runq; // per-thread(core) run queue (doubly-linked list) __thread static struct ps_list_head local_run_queue;
__thread static struct ps_list_head endq; // per-thread(core) completion queue (doubly-linked list) __thread static struct ps_list_head local_completion_queue;
// current sandbox that is active.. // current sandbox that is active..
__thread sandbox_t *current_sandbox = NULL; __thread sandbox_t *current_sandbox = NULL;
@ -31,7 +31,7 @@ __thread arch_context_t base_context;
__thread uv_loop_t uvio; __thread uv_loop_t uvio;
/** /**
* Append the sandbox to the runqueue * Append the sandbox to the local_run_queueueue
* @param s sandbox to add * @param s sandbox to add
*/ */
static inline void static inline void
@ -39,7 +39,7 @@ sandbox_local_run(struct sandbox *s)
{ {
assert(ps_list_singleton_d(s)); assert(ps_list_singleton_d(s));
// fprintf(stderr, "(%d,%lu) %s: run %p, %s\n", sched_getcpu(), pthread_self(), __func__, s, s->mod->name); // fprintf(stderr, "(%d,%lu) %s: run %p, %s\n", sched_getcpu(), pthread_self(), __func__, s, s->mod->name);
ps_list_head_append_d(&runq, s); ps_list_head_append_d(&local_run_queue, s);
} }
static inline int static inline int
@ -94,7 +94,7 @@ struct sandbox *
sandbox_schedule(int interrupt) sandbox_schedule(int interrupt)
{ {
struct sandbox *s = NULL; struct sandbox *s = NULL;
if (ps_list_head_empty(&runq)) { if (ps_list_head_empty(&local_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 (interrupt) return NULL; if (interrupt) return NULL;
if (sandbox_pull() == 0) { if (sandbox_pull() == 0) {
@ -103,25 +103,28 @@ sandbox_schedule(int interrupt)
} }
} }
s = ps_list_head_first_d(&runq, struct sandbox); s = ps_list_head_first_d(&local_run_queue, struct sandbox);
assert(s->state != SANDBOX_RETURNED); assert(s->state != SANDBOX_RETURNED);
// round-robin // round-robin
ps_list_rem_d(s); ps_list_rem_d(s);
ps_list_head_append_d(&runq, s); ps_list_head_append_d(&local_run_queue, s);
debuglog("[%p: %s]\n", s, s->mod->name); debuglog("[%p: %s]\n", s, s->mod->name);
return s; return s;
} }
/**
* @brief Remove and free n requests from the completion queue
* @param number_to_free The number of requests to free
* @return void
*/
static inline void static inline void
sandbox_local_free(unsigned int n) sandbox_local_free(unsigned int number_to_free)
{ {
int i = 0; for (int i = 0; i < number_to_free; i++){
if (ps_list_head_empty(&local_completion_queue)) break;
while (i < n && !ps_list_head_empty(&endq)) { struct sandbox *s = ps_list_head_first_d(&local_completion_queue, struct sandbox);
i++;
struct sandbox *s = ps_list_head_first_d(&endq, struct sandbox);
if (!s) break; if (!s) break;
ps_list_rem_d(s); ps_list_rem_d(s);
sandbox_free(s); sandbox_free(s);
@ -153,7 +156,7 @@ sandbox_wakeup(sandbox_t *s)
assert(s->state == SANDBOX_BLOCKED); assert(s->state == SANDBOX_BLOCKED);
assert(ps_list_singleton_d(s)); assert(ps_list_singleton_d(s));
s->state = SANDBOX_RUNNABLE; s->state = SANDBOX_RUNNABLE;
ps_list_head_append_d(&runq, s); ps_list_head_append_d(&local_run_queue, s);
done: done:
softint_enable(); softint_enable();
#endif #endif
@ -213,7 +216,7 @@ void
sandbox_local_end(struct sandbox *s) sandbox_local_end(struct sandbox *s)
{ {
assert(ps_list_singleton_d(s)); assert(ps_list_singleton_d(s));
ps_list_head_append_d(&endq, s); ps_list_head_append_d(&local_completion_queue, s);
} }
void * void *
@ -221,8 +224,8 @@ sandbox_run_func(void *data)
{ {
arch_context_init(&base_context, 0, 0); arch_context_init(&base_context, 0, 0);
ps_list_head_init(&runq); ps_list_head_init(&local_run_queue);
ps_list_head_init(&endq); ps_list_head_init(&local_completion_queue);
softint_off = 0; softint_off = 0;
next_context = NULL; next_context = NULL;
#ifndef PREEMPT_DISABLE #ifndef PREEMPT_DISABLE
@ -301,6 +304,7 @@ runtime_accept_thdfn(void *d)
int total_requests = 0; int total_requests = 0;
while (true) { while (true) {
int ready = epoll_wait(epoll_file_descriptor, epoll_events, EPOLL_MAX, -1); int ready = epoll_wait(epoll_file_descriptor, epoll_events, EPOLL_MAX, -1);
unsigned long long int start_time_in_cycles = rdtsc();
for (int i = 0; i < ready; i++) { for (int i = 0; i < ready; i++) {
if (epoll_events[i].events & EPOLLERR) { if (epoll_events[i].events & EPOLLERR) {
perror("epoll_wait"); perror("epoll_wait");
@ -318,10 +322,10 @@ runtime_accept_thdfn(void *d)
assert(0); assert(0);
} }
total_requests++; total_requests++;
printf("Handling Request %d\n", total_requests); printf("Received Request %d at %lld\n", total_requests, start_time_in_cycles);
// struct sandbox *sb = sandbox_alloc(m, m->name, s, (const struct sockaddr *)&client); // struct sandbox *sb = sandbox_alloc(m, m->name, s, (const struct sockaddr *)&client);
sbox_request_t *sb = sbox_request_alloc(m, m->name, s, (const struct sockaddr *)&client); sbox_request_t *sb = sbox_request_alloc(m, m->name, s, (const struct sockaddr *)&client, start_time_in_cycles);
assert(sb); assert(sb);
} }
} }

Loading…
Cancel
Save