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;
int sock;
struct sockaddr *addr;
unsigned long long int start_time_in_cycles;
};
typedef struct sandbox_request sbox_request_t;
#else
@ -108,7 +109,12 @@ typedef struct sandbox sandbox_t;
void sandbox_run(sbox_request_t *s);
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
#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->sock = sock;
s->addr = (struct sockaddr *)addr;
s->start_time_in_cycles = start_time_in_cycles;
sandbox_run(s);
return s;
#else /* SBOX_SCALE_ALLOC */
@ -147,50 +154,56 @@ sandbox_current_set(struct sandbox *sbox)
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
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);
}
/**
* @return the module of the current sandbox
*/
static inline struct module *
sandbox_module(struct sandbox *s)
{
if (!s) return NULL;
return s->mod;
}
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
sandbox_switch(struct sandbox *next)
sandbox_switch(struct sandbox *next_sandbox)
{
arch_context_t *n = next == NULL ? NULL : &next->ctxt;
// disable interrupts (signals)
arch_context_t *next_register_context = next_sandbox == NULL ? NULL : &next_sandbox->ctxt;
softint_disable();
// switch sandbox (register context & base/bound/table)
struct sandbox *curr = sandbox_current();
arch_context_t *c = curr == NULL ? NULL : &curr->ctxt;
sandbox_current_set(next);
if (curr && curr->state == SANDBOX_RETURNED) sandbox_local_end(curr);
// save current's registers and restore next's registers.
next_context = n;
arch_context_switch(c, n);
next_context = NULL;
// enable interrupts (signals)
struct sandbox *current_sandbox = sandbox_current();
arch_context_t *current_register_context = current_sandbox == NULL ? NULL : &current_sandbox->ctxt;
sandbox_current_set(next_sandbox);
// If the current sandbox we're switching from is in a RETURNED state, add to completion queue
if (current_sandbox && current_sandbox->state == SANDBOX_RETURNED) sandbox_local_end(current_sandbox);
next_context = next_register_context;
arch_context_switch(current_register_context, next_register_context);
softint_enable();
}
/**
* @return the arguments of the current sandbox
*/
static inline char *
sandbox_args(void)
{
struct sandbox *c = sandbox_current();
return (char *)c->args;
}

@ -15,8 +15,8 @@ struct deque_sandbox *global_deque;
pthread_mutex_t global_deque_mutex = PTHREAD_MUTEX_INITIALIZER;
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 endq; // per-thread(core) completion queue (doubly-linked list)
__thread static struct ps_list_head local_run_queue;
__thread static struct ps_list_head local_completion_queue;
// current sandbox that is active..
__thread sandbox_t *current_sandbox = NULL;
@ -31,7 +31,7 @@ __thread arch_context_t base_context;
__thread uv_loop_t uvio;
/**
* Append the sandbox to the runqueue
* Append the sandbox to the local_run_queueueue
* @param s sandbox to add
*/
static inline void
@ -39,7 +39,7 @@ sandbox_local_run(struct sandbox *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);
ps_list_head_append_d(&runq, s);
ps_list_head_append_d(&local_run_queue, s);
}
static inline int
@ -94,7 +94,7 @@ struct sandbox *
sandbox_schedule(int interrupt)
{
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!
if (interrupt) return NULL;
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);
// round-robin
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);
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
sandbox_local_free(unsigned int n)
sandbox_local_free(unsigned int number_to_free)
{
int i = 0;
while (i < n && !ps_list_head_empty(&endq)) {
i++;
struct sandbox *s = ps_list_head_first_d(&endq, struct sandbox);
for (int i = 0; i < number_to_free; i++){
if (ps_list_head_empty(&local_completion_queue)) break;
struct sandbox *s = ps_list_head_first_d(&local_completion_queue, struct sandbox);
if (!s) break;
ps_list_rem_d(s);
sandbox_free(s);
@ -153,7 +156,7 @@ sandbox_wakeup(sandbox_t *s)
assert(s->state == SANDBOX_BLOCKED);
assert(ps_list_singleton_d(s));
s->state = SANDBOX_RUNNABLE;
ps_list_head_append_d(&runq, s);
ps_list_head_append_d(&local_run_queue, s);
done:
softint_enable();
#endif
@ -213,7 +216,7 @@ void
sandbox_local_end(struct sandbox *s)
{
assert(ps_list_singleton_d(s));
ps_list_head_append_d(&endq, s);
ps_list_head_append_d(&local_completion_queue, s);
}
void *
@ -221,8 +224,8 @@ sandbox_run_func(void *data)
{
arch_context_init(&base_context, 0, 0);
ps_list_head_init(&runq);
ps_list_head_init(&endq);
ps_list_head_init(&local_run_queue);
ps_list_head_init(&local_completion_queue);
softint_off = 0;
next_context = NULL;
#ifndef PREEMPT_DISABLE
@ -301,6 +304,7 @@ runtime_accept_thdfn(void *d)
int total_requests = 0;
while (true) {
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++) {
if (epoll_events[i].events & EPOLLERR) {
perror("epoll_wait");
@ -318,10 +322,10 @@ runtime_accept_thdfn(void *d)
assert(0);
}
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);
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);
}
}

Loading…
Cancel
Save