chore: Assorted debugging enhancements

sledge_graph
Sean McBride 5 years ago
parent c8c7c6a000
commit 92c17d7717

@ -4,7 +4,8 @@ PAGE_SIZE=$(shell getconf PAGESIZE)
# Compiler Settings # Compiler Settings
CC=clang CC=clang
CC_OPTIONS = -O3 -flto -g -pthread -D_GNU_SOURCE # CC_OPTIONS = -O3 -flto -g -pthread -D_GNU_SOURCE
CC_OPTIONS = -O3 -g -pthread -D_GNU_SOURCE
BINARY_NAME=sledgert BINARY_NAME=sledgert
@ -35,8 +36,21 @@ CFLAGS += -DDEBUG
# CFLAGS += -DLOG_REQUEST_ALLOCATION # CFLAGS += -DLOG_REQUEST_ALLOCATION
# CFLAGS += -DLOG_PREEMPTION # CFLAGS += -DLOG_PREEMPTION
# CFLAGS += -DLOG_MODULE_LOADING # CFLAGS += -DLOG_MODULE_LOADING
# This flag dumps totals of incoming requests and outgoing responses, broken out by status code
# family, such as 2XX, 4XX, 5XX. It is useful to debug clients hanging waiting for a response.
# To log, run `call runtime_log_requests_responses()` while in GDB
# CFLAGS += -DLOG_TOTAL_REQS_RESPS # CFLAGS += -DLOG_TOTAL_REQS_RESPS
# This flag logs the total number of sandboxes in the various states
# It is useful to debug if sandboxes are "getting caught" in a particular state
# To log, run `call runtime_log_sandbox_states()` while in GDB
# CFLAGS += -DLOG_SANDBOX_TOTALS
# This flag enables an per-worker atomic count of sandbox's local runqueue count in thread local storage
# Useful to debug if sandboxes are "getting caught" or "leaking" while in a local runqueue
# CFLAGS += -DLOG_LOCAL_RUNQUEUE
# System Configuraiton Flags # System Configuraiton Flags
# Sets a flag equal to the processor architecture # Sets a flag equal to the processor architecture

@ -6,9 +6,8 @@
#include "types.h" #include "types.h"
#ifdef LOG_TOTAL_REQS_RESPS #if defined(LOG_TOTAL_REQS_RESPS) || defined(LOG_SANDBOX_TOTALS)
#include <stdatomic.h> #include <stdatomic.h>
#include "debuglog.h"
#endif #endif
#define LISTENER_THREAD_CORE_ID 0 /* Dedicated Listener Core */ #define LISTENER_THREAD_CORE_ID 0 /* Dedicated Listener Core */
@ -42,6 +41,19 @@ extern _Atomic uint32_t runtime_total_4XX_responses;
extern _Atomic uint32_t runtime_total_5XX_responses; extern _Atomic uint32_t runtime_total_5XX_responses;
#endif #endif
#ifdef LOG_SANDBOX_TOTALS
/* Counts to track sanboxes running through state transitions */
extern _Atomic uint32_t runtime_total_freed_requests;
extern _Atomic uint32_t runtime_total_initialized_sandboxes;
extern _Atomic uint32_t runtime_total_runnable_sandboxes;
extern _Atomic uint32_t runtime_total_blocked_sandboxes;
extern _Atomic uint32_t runtime_total_running_sandboxes;
extern _Atomic uint32_t runtime_total_preempted_sandboxes;
extern _Atomic uint32_t runtime_total_returned_sandboxes;
extern _Atomic uint32_t runtime_total_error_sandboxes;
extern _Atomic uint32_t runtime_total_complete_sandboxes;
#endif
/* /*
* Unitless estimate of the instantaneous fraction of system capacity required to complete all previously * Unitless estimate of the instantaneous fraction of system capacity required to complete all previously
* admitted work. This is used to calculate free capacity as part of admissions control * admitted work. This is used to calculate free capacity as part of admissions control
@ -78,17 +90,3 @@ runtime_is_worker()
return false; return false;
} }
#ifdef LOG_TOTAL_REQS_RESPS
static inline void
runtime_log_requests_responses()
{
int64_t total_responses = runtime_total_2XX_responses + runtime_total_4XX_responses
+ runtime_total_5XX_responses;
int64_t outstanding_requests = (int64_t)runtime_total_requests - total_responses;
debuglog("Requests: %u (%ld outstanding)\n\tResponses: %ld\n\t\t2XX: %u\n\t\t4XX: %u\n\t\t5XX: %u\n",
runtime_total_requests, outstanding_requests, total_responses, runtime_total_2XX_responses,
runtime_total_4XX_responses, runtime_total_5XX_responses);
};
#endif

@ -1,7 +1,17 @@
#ifdef LOG_LOCAL_RUNQUEUE
#include <stdatomic.h>
#include <stdint.h>
#endif
#include "local_runqueue.h" #include "local_runqueue.h"
static struct local_runqueue_config local_runqueue; static struct local_runqueue_config local_runqueue;
#ifdef LOG_LOCAL_RUNQUEUE
__thread _Atomic uint32_t local_runqueue_count = 0;
#endif
/* Initializes a concrete implementation of the sandbox request scheduler interface */ /* Initializes a concrete implementation of the sandbox request scheduler interface */
void void
local_runqueue_initialize(struct local_runqueue_config *config) local_runqueue_initialize(struct local_runqueue_config *config)
@ -17,6 +27,9 @@ void
local_runqueue_add(struct sandbox *sandbox) local_runqueue_add(struct sandbox *sandbox)
{ {
assert(local_runqueue.add_fn != NULL); assert(local_runqueue.add_fn != NULL);
#ifdef LOG_LOCAL_RUNQUEUE
local_runqueue_count++;
#endif
return local_runqueue.add_fn(sandbox); return local_runqueue.add_fn(sandbox);
} }
@ -28,6 +41,9 @@ void
local_runqueue_delete(struct sandbox *sandbox) local_runqueue_delete(struct sandbox *sandbox)
{ {
assert(local_runqueue.delete_fn != NULL); assert(local_runqueue.delete_fn != NULL);
#ifdef LOG_LOCAL_RUNQUEUE
local_runqueue_count--;
#endif
local_runqueue.delete_fn(sandbox); local_runqueue.delete_fn(sandbox);
} }

@ -22,10 +22,48 @@ int runtime_epoll_file_descriptor;
double runtime_admitted; double runtime_admitted;
#ifdef LOG_TOTAL_REQS_RESPS #ifdef LOG_TOTAL_REQS_RESPS
_Atomic uint32_t runtime_total_requests; _Atomic uint32_t runtime_total_requests = 0;
_Atomic uint32_t runtime_total_2XX_responses; _Atomic uint32_t runtime_total_2XX_responses = 0;
_Atomic uint32_t runtime_total_4XX_responses; _Atomic uint32_t runtime_total_4XX_responses = 0;
_Atomic uint32_t runtime_total_5XX_responses; _Atomic uint32_t runtime_total_5XX_responses = 0;
void
runtime_log_requests_responses()
{
int64_t total_responses = runtime_total_2XX_responses + runtime_total_4XX_responses
+ runtime_total_5XX_responses;
int64_t outstanding_requests = (int64_t)runtime_total_requests - total_responses;
debuglog("Requests: %u (%ld outstanding)\n\tResponses: %ld\n\t\t2XX: %u\n\t\t4XX: %u\n\t\t5XX: %u\n",
runtime_total_requests, outstanding_requests, total_responses, runtime_total_2XX_responses,
runtime_total_4XX_responses, runtime_total_5XX_responses);
};
#endif
#ifdef LOG_SANDBOX_TOTALS
_Atomic uint32_t runtime_total_freed_requests = 0;
_Atomic uint32_t runtime_total_initialized_sandboxes = 0;
_Atomic uint32_t runtime_total_runnable_sandboxes = 0;
_Atomic uint32_t runtime_total_blocked_sandboxes = 0;
_Atomic uint32_t runtime_total_running_sandboxes = 0;
_Atomic uint32_t runtime_total_preempted_sandboxes = 0;
_Atomic uint32_t runtime_total_returned_sandboxes = 0;
_Atomic uint32_t runtime_total_error_sandboxes = 0;
_Atomic uint32_t runtime_total_complete_sandboxes = 0;
/*
* Function intended to be interactively run in a debugger to look at sandbox totals
* via `call runtime_log_sandbox_states()`
*/
void
runtime_log_sandbox_states()
{
debuglog("Initialized: %u\n\tRunnable: %u\n\tBlocked: %u\n\tRunning: %u\n\tPreempted: %u\n\tReturned: "
"%u\n\tError: %u\n\tComplete: %u\n",
runtime_total_initialized_sandboxes, runtime_total_runnable_sandboxes, runtime_total_blocked_sandboxes,
runtime_total_running_sandboxes, runtime_total_preempted_sandboxes, runtime_total_returned_sandboxes,
runtime_total_error_sandboxes, runtime_total_complete_sandboxes);
};
#endif #endif
/****************************************** /******************************************
@ -42,15 +80,6 @@ runtime_initialize(void)
runtime_epoll_file_descriptor = epoll_create1(0); runtime_epoll_file_descriptor = epoll_create1(0);
assert(runtime_epoll_file_descriptor >= 0); assert(runtime_epoll_file_descriptor >= 0);
#ifdef LOG_TOTAL_REQS_RESPS
/* Setup Counts */
runtime_total_requests = 0;
runtime_total_2XX_responses = 0;
runtime_total_4XX_responses = 0;
runtime_total_5XX_responses = 0;
#endif
/* Allocate and Initialize the global deque /* Allocate and Initialize the global deque
TODO: Improve to expose variant as a config #Issue 93 TODO: Improve to expose variant as a config #Issue 93
*/ */
@ -85,8 +114,7 @@ listener_thread_reject(int client_socket)
int to_send = strlen(HTTP_RESPONSE_504_SERVICE_UNAVAILABLE); int to_send = strlen(HTTP_RESPONSE_504_SERVICE_UNAVAILABLE);
while (sent < to_send) { while (sent < to_send) {
rc = write(client_socket, HTTP_RESPONSE_504_SERVICE_UNAVAILABLE, rc = write(client_socket, &HTTP_RESPONSE_504_SERVICE_UNAVAILABLE[sent], to_send - sent);
strlen(HTTP_RESPONSE_504_SERVICE_UNAVAILABLE));
if (rc < 0) { if (rc < 0) {
if (errno == EAGAIN) continue; if (errno == EAGAIN) continue;
@ -97,7 +125,6 @@ listener_thread_reject(int client_socket)
#ifdef LOG_TOTAL_REQS_RESPS #ifdef LOG_TOTAL_REQS_RESPS
runtime_total_5XX_responses++; runtime_total_5XX_responses++;
runtime_log_requests_responses();
#endif #endif
close: close:
@ -128,15 +155,31 @@ listener_thread_main(void *dummy)
* Block indefinitely on the epoll file descriptor, waiting on up to a max number of events * Block indefinitely on the epoll file descriptor, waiting on up to a max number of events
* TODO: Is LISTENER_THREAD_MAX_EPOLL_EVENTS actually limited to the max number of modules? * TODO: Is LISTENER_THREAD_MAX_EPOLL_EVENTS actually limited to the max number of modules?
*/ */
int request_count = epoll_wait(runtime_epoll_file_descriptor, (struct epoll_event *)&epoll_events, int descriptor_count = epoll_wait(runtime_epoll_file_descriptor, (struct epoll_event *)&epoll_events,
LISTENER_THREAD_MAX_EPOLL_EVENTS, -1); LISTENER_THREAD_MAX_EPOLL_EVENTS, -1);
if (request_count < 0) panic("epoll_wait: %s", strerror(errno)); if (descriptor_count < 0) {
if (request_count == 0) panic("Unexpectedly returned with epoll_wait timeout not set\n"); if (errno == EINTR) continue;
panic("epoll_wait: %s", strerror(errno));
}
if (descriptor_count == 0) panic("Unexpectedly returned with epoll_wait timeout not set\n");
/* Capture Start Time to calculate absolute deadline */ /* Capture Start Time to calculate absolute deadline */
uint64_t request_arrival_timestamp = __getcycles(); uint64_t request_arrival_timestamp = __getcycles();
for (int i = 0; i < request_count; i++) { for (int i = 0; i < descriptor_count; i++) {
if (epoll_events[i].events & EPOLLERR) panic("epoll_wait: %s", strerror(errno)); /* Check Event to determine if epoll returned an error */
if ((epoll_events[i].events & EPOLLERR) == EPOLLERR) {
int error = 0;
socklen_t errlen = sizeof(error);
if (getsockopt(epoll_events[i].data.fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen)
== 0) {
panic("epoll_wait: %s\n", strerror(error));
}
assert(0);
};
/* Assumption: We have only registered EPOLLIN events, so we should see no others here */
assert((epoll_events[i].events & EPOLLIN) == EPOLLIN);
/* Unpack module from epoll event */ /* Unpack module from epoll event */
struct module *module = (struct module *)epoll_events[i].data.ptr; struct module *module = (struct module *)epoll_events[i].data.ptr;
@ -145,80 +188,73 @@ listener_thread_main(void *dummy)
/* Accept Client Request as a nonblocking socket, saving address information */ /* Accept Client Request as a nonblocking socket, saving address information */
struct sockaddr_in client_address; struct sockaddr_in client_address;
socklen_t address_length = sizeof(client_address); socklen_t address_length = sizeof(client_address);
int client_socket = accept4(module->socket_descriptor, (struct sockaddr *)&client_address,
&address_length, SOCK_NONBLOCK);
if (client_socket < 0) {
switch (errno) {
/* Note: Assumes EAGAIN and EWOULDBLOCK are identical, as on Linux */
case EWOULDBLOCK: {
/*
* According to accept(2), it is possible that a connection might
* have been removed between us receiving an event via epoll_wait
* and us calling accept. Thus we just want to gracefully ignore the
* epoll event.
*/
#ifdef LOG_EPOLL
debuglog("Encountered an epoll notification for %s that did not actually have "
"an associated request\n",
module->name);
#endif
continue; /*
} * Accept as many requests as possible, terminating when we would have blocked
default: * This inner loop is used in case there are more datagrams than epoll events for some reason
*/
while (true) {
int client_socket = accept4(module->socket_descriptor,
(struct sockaddr *)&client_address, &address_length,
SOCK_NONBLOCK);
if (client_socket < 0) {
if (errno == EWOULDBLOCK || errno == EAGAIN) break;
panic("accept4: %s", strerror(errno)); panic("accept4: %s", strerror(errno));
} }
};
/* /*
* According to accept(2), it is possible that the the sockaddr structure client_address may be * According to accept(2), it is possible that the the sockaddr structure client_address
* too small, resulting in data being truncated to fit. The appect call mutates the size value * may be too small, resulting in data being truncated to fit. The appect call mutates
* to indicate that this is the case. * the size value to indicate that this is the case.
*/ */
if (address_length > sizeof(client_address)) { if (address_length > sizeof(client_address)) {
debuglog("A client address to %s has been truncated because buffer was too small\n", debuglog("A client address to %s has been truncated because buffer was too "
module->name); "small\n",
} module->name);
}
#ifdef LOG_TOTAL_REQS_RESPS #ifdef LOG_TOTAL_REQS_RESPS
runtime_total_requests++; runtime_total_requests++;
runtime_log_requests_responses();
#endif #endif
/* Perform Admission Control */ /* Perform Admission Control */
uint32_t estimated_execution = perf_window_get_percentile(&module->perf_window, 0.5); uint32_t estimated_execution = perf_window_get_percentile(&module->perf_window, 0.5);
/* /*
* If this is the first execution, assume a default execution * If this is the first execution, assume a default execution
* TODO: Enhance module specification to provide "seed" value of estimated duration * TODO: Enhance module specification to provide "seed" value of estimated duration
*/ */
if (estimated_execution == -1) estimated_execution = 1000; if (estimated_execution == -1) estimated_execution = 1000;
double admissions_estimate = (double)estimated_execution / module->relative_deadline; double admissions_estimate = (double)estimated_execution / module->relative_deadline;
if (runtime_admitted + admissions_estimate >= runtime_worker_threads_count) { if (runtime_admitted + admissions_estimate >= runtime_worker_threads_count) {
listener_thread_reject(client_socket); listener_thread_reject(client_socket);
continue; continue;
} }
/* Allocate a Sandbox Request */ /* Allocate a Sandbox Request */
struct sandbox_request *sandbox_request = struct sandbox_request *sandbox_request =
sandbox_request_allocate(module, module->name, client_socket, sandbox_request_allocate(module, module->name, client_socket,
(const struct sockaddr *)&client_address, request_arrival_timestamp, (const struct sockaddr *)&client_address,
admissions_estimate); request_arrival_timestamp, admissions_estimate);
/* Add to the Global Sandbox Request Scheduler */ /* Clear the */
global_request_scheduler_add(sandbox_request); epoll_events[i].data.ptr = NULL;
/* Add to work accepted by the runtime */ /* Add to the Global Sandbox Request Scheduler */
runtime_admitted += admissions_estimate; global_request_scheduler_add(sandbox_request);
/* Add to work accepted by the runtime */
runtime_admitted += admissions_estimate;
#ifdef LOG_ADMISSIONS_CONTROL #ifdef LOG_ADMISSIONS_CONTROL
debuglog("Runtime Admitted: %f / %u\n", runtime_admitted, runtime_worker_threads_count); debuglog("Runtime Admitted: %f / %u\n", runtime_admitted, runtime_worker_threads_count);
#endif #endif
} } /* while true */
} } /* for loop */
} /* while true */
panic("Listener thread unexpectedly broke loop\n"); panic("Listener thread unexpectedly broke loop\n");
} }

@ -49,24 +49,24 @@ sandbox_setup_arguments(struct sandbox *sandbox)
/** /**
* Run the http-parser on the sandbox's request_response_data using the configured settings global * Run the http-parser on the sandbox's request_response_data using the configured settings global
* Success means that a "chunk" was fully parsed, not that parsing of a full request is complete
* @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 data that we want to parse
* @returns 0 on success, -1 on failure * @returns 0 on success, -1 on failure
*/ */
int int
sandbox_parse_http_request(struct sandbox *sandbox, size_t length) sandbox_parse_http_request(struct sandbox *sandbox, size_t length_read)
{ {
assert(sandbox != NULL); assert(sandbox != NULL);
if (length == 0) return 0; if (length_read == 0) return 0;
/* Why is our start address sandbox->request_response_data + sandbox->request_response_data_length? size_t length_parsed = http_parser_execute(&sandbox->http_parser, http_parser_settings_get(),
it's like a cursor to keep track of what we've read so far */ sandbox->request_response_data
size_t size_parsed = http_parser_execute(&sandbox->http_parser, http_parser_settings_get(), + sandbox->request_response_data_length,
sandbox->request_response_data + sandbox->request_response_data_length, length_read);
length);
if (size_parsed != length) return -1; if (length_parsed != length_read) return -1;
return 0; return 0;
} }
@ -81,28 +81,32 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
assert(sandbox->module->max_request_size > 0); assert(sandbox->module->max_request_size > 0);
assert(sandbox->request_response_data_length == 0); assert(sandbox->request_response_data_length == 0);
int rc;
#ifndef USE_HTTP_UVIO #ifndef USE_HTTP_UVIO
do { /* Read from the Socket */
/* Read from the Socket */ int length_read = recv(sandbox->client_socket_descriptor,
rc = read(sandbox->client_socket_descriptor, sandbox->request_response_data, &sandbox->request_response_data[sandbox->request_response_data_length],
sandbox->module->max_request_size); sandbox->module->max_request_size - sandbox->request_response_data_length, 0);
if (rc < 0) { if (length_read < 0) {
if (errno == EAGAIN) continue; if (errno == EAGAIN) goto eagain;
debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno)); /* All other errors */
goto err; debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno));
} goto err;
}
/* Parse what we've read */ /* Try to parse what we've read */
if (sandbox_parse_http_request(sandbox, rc) == -1) { if (sandbox_parse_http_request(sandbox, length_read) < 0) {
debuglog("Error parsing socket %d\n", sandbox->client_socket_descriptor); debuglog("Error parsing socket %d\n", sandbox->client_socket_descriptor);
goto err; goto err;
} }
sandbox->request_response_data_length += rc;
} while (rc > 0); sandbox->request_response_data_length += length_read;
if (!sandbox->http_request.message_end) goto eagain;
sandbox->request_length = sandbox->request_response_data_length;
#else #else
rc = uv_read_start((uv_stream_t *)&sandbox->client_libuv_stream, rc = uv_read_start((uv_stream_t *)&sandbox->client_libuv_stream,
@ -111,10 +115,7 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox)
worker_thread_process_io(); worker_thread_process_io();
#endif #endif
if (!sandbox->http_request.message_end) goto eagain; int rc = 0;
sandbox->request_length = sandbox->request_response_data_length;
rc = 0;
done: done:
return rc; return rc;
eagain: eagain:
@ -310,11 +311,10 @@ current_sandbox_main(void)
sandbox_open_http(sandbox); sandbox_open_http(sandbox);
/* Parse the request. Treat EAGAIN as an error after three retries*/ /* Parse the request, polling until complete */
int tries = 0;
do { do {
rc = sandbox_receive_and_parse_client_request(sandbox); rc = sandbox_receive_and_parse_client_request(sandbox);
} while (rc == -EAGAIN && tries < 3); } while (rc == -EAGAIN);
if (rc < 0) { if (rc < 0) {
error_message = "Unable to receive and parse client request\n"; error_message = "Unable to receive and parse client request\n";
@ -324,7 +324,7 @@ current_sandbox_main(void)
/* Initialize the module */ /* Initialize the module */
struct module *current_module = sandbox_get_module(sandbox); struct module *current_module = sandbox_get_module(sandbox);
int argument_count = module_get_argument_count(current_module); int argument_count = module_get_argument_count(current_module);
// alloc_linear_memory();
module_initialize_globals(current_module); module_initialize_globals(current_module);
module_initialize_memory(current_module); module_initialize_memory(current_module);
@ -344,7 +344,6 @@ current_sandbox_main(void)
#ifdef LOG_TOTAL_REQS_RESPS #ifdef LOG_TOTAL_REQS_RESPS
runtime_total_2XX_responses++; runtime_total_2XX_responses++;
runtime_log_requests_responses();
#endif #endif
sandbox->response_timestamp = __getcycles(); sandbox->response_timestamp = __getcycles();
@ -364,7 +363,7 @@ done:
*/ */
assert(0); assert(0);
err: err:
fprintf(stderr, "%s", error_message); debuglog("%s", error_message);
assert(sandbox->state == SANDBOX_RUNNING); assert(sandbox->state == SANDBOX_RUNNING);
int to_send = strlen(HTTP_RESPONSE_400_BAD_REQUEST); int to_send = strlen(HTTP_RESPONSE_400_BAD_REQUEST);
@ -385,7 +384,6 @@ err:
#ifdef LOG_TOTAL_REQS_RESPS #ifdef LOG_TOTAL_REQS_RESPS
runtime_total_4XX_responses++; runtime_total_4XX_responses++;
debuglog("At %llu, Sandbox %lu - 4XX\n", __getcycles(), sandbox->request_arrival_timestamp); debuglog("At %llu, Sandbox %lu - 4XX\n", __getcycles(), sandbox->request_arrival_timestamp);
runtime_log_requests_responses();
#endif #endif
software_interrupt_disable(); software_interrupt_disable();
sandbox_close_http(sandbox); sandbox_close_http(sandbox);
@ -525,6 +523,9 @@ sandbox_set_as_initialized(struct sandbox *sandbox, struct sandbox_request *sand
memcpy(&sandbox->client_address, sandbox_request->socket_address, sizeof(struct sockaddr)); memcpy(&sandbox->client_address, sandbox_request->socket_address, sizeof(struct sockaddr));
sandbox->state = SANDBOX_INITIALIZED; sandbox->state = SANDBOX_INITIALIZED;
#ifdef LOG_SANDBOX_TOTALS
runtime_total_initialized_sandboxes++;
#endif
} }
/** /**
@ -557,10 +558,18 @@ sandbox_set_as_runnable(struct sandbox *sandbox, sandbox_state_t last_state)
switch (last_state) { switch (last_state) {
case SANDBOX_INITIALIZED: { case SANDBOX_INITIALIZED: {
sandbox->initializing_duration += duration_of_last_state; sandbox->initializing_duration += duration_of_last_state;
#ifdef LOG_SANDBOX_TOTALS
runtime_total_initialized_sandboxes--;
runtime_total_runnable_sandboxes++;
#endif
break; break;
} }
case SANDBOX_BLOCKED: { case SANDBOX_BLOCKED: {
sandbox->blocked_duration += duration_of_last_state; sandbox->blocked_duration += duration_of_last_state;
#ifdef LOG_SANDBOX_TOTALS
runtime_total_blocked_sandboxes--;
runtime_total_runnable_sandboxes++;
#endif
break; break;
} }
default: { default: {
@ -605,10 +614,18 @@ sandbox_set_as_running(struct sandbox *sandbox, sandbox_state_t last_state)
switch (last_state) { switch (last_state) {
case SANDBOX_RUNNABLE: { case SANDBOX_RUNNABLE: {
sandbox->runnable_duration += duration_of_last_state; sandbox->runnable_duration += duration_of_last_state;
#ifdef LOG_SANDBOX_TOTALS
runtime_total_runnable_sandboxes--;
runtime_total_running_sandboxes++;
#endif
break; break;
} }
case SANDBOX_PREEMPTED: { case SANDBOX_PREEMPTED: {
sandbox->preempted_duration += duration_of_last_state; sandbox->preempted_duration += duration_of_last_state;
#ifdef LOG_SANDBOX_TOTALS
runtime_total_preempted_sandboxes--;
runtime_total_running_sandboxes++;
#endif
break; break;
} }
default: { default: {
@ -650,6 +667,10 @@ sandbox_set_as_preempted(struct sandbox *sandbox, sandbox_state_t last_state)
switch (last_state) { switch (last_state) {
case SANDBOX_RUNNING: { case SANDBOX_RUNNING: {
sandbox->running_duration += duration_of_last_state; sandbox->running_duration += duration_of_last_state;
#ifdef LOG_SANDBOX_TOTALS
runtime_total_running_sandboxes--;
runtime_total_preempted_sandboxes++;
#endif
break; break;
} }
default: { default: {
@ -689,6 +710,10 @@ sandbox_set_as_blocked(struct sandbox *sandbox, sandbox_state_t last_state)
case SANDBOX_RUNNING: { case SANDBOX_RUNNING: {
sandbox->running_duration += duration_of_last_state; sandbox->running_duration += duration_of_last_state;
local_runqueue_delete(sandbox); local_runqueue_delete(sandbox);
#ifdef LOG_SANDBOX_TOTALS
runtime_total_running_sandboxes--;
runtime_total_blocked_sandboxes++;
#endif
break; break;
} }
default: { default: {
@ -732,6 +757,10 @@ sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state)
sandbox->running_duration += duration_of_last_state; sandbox->running_duration += duration_of_last_state;
local_runqueue_delete(sandbox); local_runqueue_delete(sandbox);
sandbox_free_linear_memory(sandbox); sandbox_free_linear_memory(sandbox);
#ifdef LOG_SANDBOX_TOTALS
runtime_total_running_sandboxes--;
runtime_total_returned_sandboxes++;
#endif
break; break;
} }
default: { default: {
@ -774,10 +803,18 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state)
case SANDBOX_SET_AS_INITIALIZED: case SANDBOX_SET_AS_INITIALIZED:
/* Technically, this is a degenerate sandbox that we generate by hand */ /* Technically, this is a degenerate sandbox that we generate by hand */
sandbox->initializing_duration += duration_of_last_state; sandbox->initializing_duration += duration_of_last_state;
#ifdef LOG_SANDBOX_TOTALS
runtime_total_initialized_sandboxes--;
runtime_total_error_sandboxes++;
#endif
break; break;
case SANDBOX_RUNNING: { case SANDBOX_RUNNING: {
sandbox->running_duration += duration_of_last_state; sandbox->running_duration += duration_of_last_state;
local_runqueue_delete(sandbox); local_runqueue_delete(sandbox);
#ifdef LOG_SANDBOX_TOTALS
runtime_total_running_sandboxes--;
runtime_total_error_sandboxes++;
#endif
break; break;
} }
default: { default: {
@ -829,6 +866,10 @@ sandbox_set_as_complete(struct sandbox *sandbox, sandbox_state_t last_state)
case SANDBOX_RETURNED: { case SANDBOX_RETURNED: {
sandbox->completion_timestamp = now; sandbox->completion_timestamp = now;
sandbox->returned_duration += duration_of_last_state; sandbox->returned_duration += duration_of_last_state;
#ifdef LOG_SANDBOX_TOTALS
runtime_total_returned_sandboxes--;
runtime_total_complete_sandboxes++;
#endif
break; break;
} }
default: { default: {
@ -897,6 +938,9 @@ sandbox_allocate(struct sandbox_request *sandbox_request)
/* Set state to initializing */ /* Set state to initializing */
sandbox_set_as_initialized(sandbox, sandbox_request, now); sandbox_set_as_initialized(sandbox, sandbox_request, now);
#ifdef LOG_SANDBOX_TOTALS
runtime_total_freed_requests++;
#endif
free(sandbox_request); free(sandbox_request);
done: done:
return sandbox; return sandbox;

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
# fib(20) # fib(20)
# Perhaps this can be improved to pass a body without an additional file # Perhaps this can be improved to pass a body without an additional file
ab -n 100000 -c 100 -p client1_body.txt -v 4 -r localhost:10000/ ab -n 100000 -c 64 -s 999999999 -p client1_body.txt -v 4 -r localhost:10000/

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
# fib(10) # fib(10)
# Perhaps this can be improved to pass a body without an additional file # Perhaps this can be improved to pass a body without an additional file
ab -n 100000 -c 100 -p client2_body.txt -v 4 -r localhost:10001/ ab -n 100000 -c 64 -s 999999999 -p client2_body.txt -v 4 -r localhost:10001/

Loading…
Cancel
Save