phani 5 years ago
commit 362e8b0a67

@ -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

@ -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

@ -193,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.

@ -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

@ -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;

@ -87,10 +87,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;
@ -130,7 +132,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 +145,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 +159,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 +173,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,7 +268,7 @@ 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();
//sandbox_local_end(curr);

@ -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) {
@ -148,13 +148,13 @@ sandbox_client_request_get(void)
r = recv(curr->csock, (curr->req_resp_data + r), curr->mod->max_req_sz - r, 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
@ -170,15 +170,6 @@ sandbox_client_response_set(void)
#ifndef STANDALONE
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);
@ -217,10 +208,14 @@ sandbox_client_response_set(void)
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 n = http_response_uv();
int r = uv_write(&req, (uv_stream_t *)&curr->cuv, curr->rsi.bufs, n, sb_write_callback);
sandbox_block();
sandbox_block_http();
#endif
return r;
#else
@ -253,7 +248,11 @@ sandbox_entry(void)
#ifndef STANDALONE
http_parser_init(&curr->hp, HTTP_REQUEST);
curr->hp.data = curr;
#ifdef USE_UVIO
#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;
@ -277,9 +276,9 @@ sandbox_entry(void)
}
#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

@ -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!

Loading…
Cancel
Save