From 92c17d7717beae2ad16e45c32c32c154adbaa560 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Sun, 23 Aug 2020 13:39:41 -0400 Subject: [PATCH] chore: Assorted debugging enhancements --- runtime/Makefile | 16 ++- runtime/include/runtime.h | 30 ++--- runtime/src/local_runqueue.c | 16 +++ runtime/src/runtime.c | 194 +++++++++++++++++----------- runtime/src/sandbox.c | 118 +++++++++++------ runtime/tests/preemption/client1.sh | 2 +- runtime/tests/preemption/client2.sh | 2 +- 7 files changed, 243 insertions(+), 135 deletions(-) diff --git a/runtime/Makefile b/runtime/Makefile index c83dc17..f855084 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -4,7 +4,8 @@ PAGE_SIZE=$(shell getconf PAGESIZE) # Compiler Settings 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 @@ -35,8 +36,21 @@ CFLAGS += -DDEBUG # CFLAGS += -DLOG_REQUEST_ALLOCATION # CFLAGS += -DLOG_PREEMPTION # 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 +# 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 # Sets a flag equal to the processor architecture diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index 011eb33..309652d 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -6,9 +6,8 @@ #include "types.h" -#ifdef LOG_TOTAL_REQS_RESPS +#if defined(LOG_TOTAL_REQS_RESPS) || defined(LOG_SANDBOX_TOTALS) #include -#include "debuglog.h" #endif #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; #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 * admitted work. This is used to calculate free capacity as part of admissions control @@ -78,17 +90,3 @@ runtime_is_worker() 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 diff --git a/runtime/src/local_runqueue.c b/runtime/src/local_runqueue.c index 1817a0a..53162c0 100644 --- a/runtime/src/local_runqueue.c +++ b/runtime/src/local_runqueue.c @@ -1,7 +1,17 @@ + +#ifdef LOG_LOCAL_RUNQUEUE +#include +#include +#endif + #include "local_runqueue.h" 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 */ void local_runqueue_initialize(struct local_runqueue_config *config) @@ -17,6 +27,9 @@ void local_runqueue_add(struct sandbox *sandbox) { assert(local_runqueue.add_fn != NULL); +#ifdef LOG_LOCAL_RUNQUEUE + local_runqueue_count++; +#endif return local_runqueue.add_fn(sandbox); } @@ -28,6 +41,9 @@ void local_runqueue_delete(struct sandbox *sandbox) { assert(local_runqueue.delete_fn != NULL); +#ifdef LOG_LOCAL_RUNQUEUE + local_runqueue_count--; +#endif local_runqueue.delete_fn(sandbox); } diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index 34a7a1a..7552f6c 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -22,10 +22,48 @@ int runtime_epoll_file_descriptor; double runtime_admitted; #ifdef LOG_TOTAL_REQS_RESPS -_Atomic uint32_t runtime_total_requests; -_Atomic uint32_t runtime_total_2XX_responses; -_Atomic uint32_t runtime_total_4XX_responses; -_Atomic uint32_t runtime_total_5XX_responses; +_Atomic uint32_t runtime_total_requests = 0; +_Atomic uint32_t runtime_total_2XX_responses = 0; +_Atomic uint32_t runtime_total_4XX_responses = 0; +_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 /****************************************** @@ -42,15 +80,6 @@ runtime_initialize(void) runtime_epoll_file_descriptor = epoll_create1(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 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); while (sent < to_send) { - rc = write(client_socket, HTTP_RESPONSE_504_SERVICE_UNAVAILABLE, - strlen(HTTP_RESPONSE_504_SERVICE_UNAVAILABLE)); + rc = write(client_socket, &HTTP_RESPONSE_504_SERVICE_UNAVAILABLE[sent], to_send - sent); if (rc < 0) { if (errno == EAGAIN) continue; @@ -97,7 +125,6 @@ listener_thread_reject(int client_socket) #ifdef LOG_TOTAL_REQS_RESPS runtime_total_5XX_responses++; - runtime_log_requests_responses(); #endif 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 * 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, - LISTENER_THREAD_MAX_EPOLL_EVENTS, -1); - if (request_count < 0) panic("epoll_wait: %s", strerror(errno)); - if (request_count == 0) panic("Unexpectedly returned with epoll_wait timeout not set\n"); + int descriptor_count = epoll_wait(runtime_epoll_file_descriptor, (struct epoll_event *)&epoll_events, + LISTENER_THREAD_MAX_EPOLL_EVENTS, -1); + if (descriptor_count < 0) { + 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 */ uint64_t request_arrival_timestamp = __getcycles(); - for (int i = 0; i < request_count; i++) { - if (epoll_events[i].events & EPOLLERR) panic("epoll_wait: %s", strerror(errno)); + for (int i = 0; i < descriptor_count; i++) { + /* 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 */ 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 */ struct sockaddr_in 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; - } - default: + /* + * Accept as many requests as possible, terminating when we would have blocked + * 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)); } - }; - /* - * According to accept(2), it is possible that the the sockaddr structure client_address may be - * too small, resulting in data being truncated to fit. The appect call mutates the size value - * to indicate that this is the case. - */ - if (address_length > sizeof(client_address)) { - debuglog("A client address to %s has been truncated because buffer was too small\n", - module->name); - } + /* + * According to accept(2), it is possible that the the sockaddr structure client_address + * may be too small, resulting in data being truncated to fit. The appect call mutates + * the size value to indicate that this is the case. + */ + if (address_length > sizeof(client_address)) { + debuglog("A client address to %s has been truncated because buffer was too " + "small\n", + module->name); + } #ifdef LOG_TOTAL_REQS_RESPS - runtime_total_requests++; - runtime_log_requests_responses(); + runtime_total_requests++; #endif - /* Perform Admission Control */ + /* Perform Admission Control */ - uint32_t estimated_execution = perf_window_get_percentile(&module->perf_window, 0.5); - /* - * If this is the first execution, assume a default execution - * TODO: Enhance module specification to provide "seed" value of estimated duration - */ - if (estimated_execution == -1) estimated_execution = 1000; + uint32_t estimated_execution = perf_window_get_percentile(&module->perf_window, 0.5); + /* + * If this is the first execution, assume a default execution + * TODO: Enhance module specification to provide "seed" value of estimated duration + */ + 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) { - listener_thread_reject(client_socket); - continue; - } + if (runtime_admitted + admissions_estimate >= runtime_worker_threads_count) { + listener_thread_reject(client_socket); + continue; + } - /* Allocate a Sandbox Request */ - struct sandbox_request *sandbox_request = - sandbox_request_allocate(module, module->name, client_socket, - (const struct sockaddr *)&client_address, request_arrival_timestamp, - admissions_estimate); + /* Allocate a Sandbox Request */ + struct sandbox_request *sandbox_request = + sandbox_request_allocate(module, module->name, client_socket, + (const struct sockaddr *)&client_address, + request_arrival_timestamp, admissions_estimate); - /* Add to the Global Sandbox Request Scheduler */ - global_request_scheduler_add(sandbox_request); + /* Clear the */ + epoll_events[i].data.ptr = NULL; - /* Add to work accepted by the runtime */ - runtime_admitted += admissions_estimate; + /* Add to the Global Sandbox Request Scheduler */ + global_request_scheduler_add(sandbox_request); + + /* Add to work accepted by the runtime */ + runtime_admitted += admissions_estimate; #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 - } - } + } /* while true */ + } /* for loop */ + } /* while true */ panic("Listener thread unexpectedly broke loop\n"); } diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index 8b793a9..39ef2b1 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -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 + * 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 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 */ 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); - 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? - it's like a cursor to keep track of what we've read so far */ - size_t size_parsed = http_parser_execute(&sandbox->http_parser, http_parser_settings_get(), - sandbox->request_response_data + sandbox->request_response_data_length, - length); + size_t length_parsed = http_parser_execute(&sandbox->http_parser, http_parser_settings_get(), + sandbox->request_response_data + + sandbox->request_response_data_length, + length_read); - if (size_parsed != length) return -1; + if (length_parsed != length_read) return -1; return 0; } @@ -81,28 +81,32 @@ sandbox_receive_and_parse_client_request(struct sandbox *sandbox) assert(sandbox->module->max_request_size > 0); assert(sandbox->request_response_data_length == 0); - int rc; #ifndef USE_HTTP_UVIO - do { - /* Read from the Socket */ - rc = read(sandbox->client_socket_descriptor, sandbox->request_response_data, - sandbox->module->max_request_size); - if (rc < 0) { - if (errno == EAGAIN) continue; + /* Read from the Socket */ + int length_read = recv(sandbox->client_socket_descriptor, + &sandbox->request_response_data[sandbox->request_response_data_length], + sandbox->module->max_request_size - sandbox->request_response_data_length, 0); + if (length_read < 0) { + if (errno == EAGAIN) goto eagain; - debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno)); - goto err; - } + /* All other errors */ + debuglog("Error reading socket %d - %s\n", sandbox->client_socket_descriptor, strerror(errno)); + goto err; + } - /* Parse what we've read */ - if (sandbox_parse_http_request(sandbox, rc) == -1) { - debuglog("Error parsing socket %d\n", sandbox->client_socket_descriptor); - goto err; - } - sandbox->request_response_data_length += rc; - } while (rc > 0); + /* Try to parse what we've read */ + if (sandbox_parse_http_request(sandbox, length_read) < 0) { + debuglog("Error parsing socket %d\n", sandbox->client_socket_descriptor); + goto err; + } + + sandbox->request_response_data_length += length_read; + + if (!sandbox->http_request.message_end) goto eagain; + + sandbox->request_length = sandbox->request_response_data_length; #else 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(); #endif - if (!sandbox->http_request.message_end) goto eagain; - - sandbox->request_length = sandbox->request_response_data_length; - rc = 0; + int rc = 0; done: return rc; eagain: @@ -310,11 +311,10 @@ current_sandbox_main(void) sandbox_open_http(sandbox); - /* Parse the request. Treat EAGAIN as an error after three retries*/ - int tries = 0; + /* Parse the request, polling until complete */ do { rc = sandbox_receive_and_parse_client_request(sandbox); - } while (rc == -EAGAIN && tries < 3); + } while (rc == -EAGAIN); if (rc < 0) { error_message = "Unable to receive and parse client request\n"; @@ -324,7 +324,7 @@ current_sandbox_main(void) /* Initialize the module */ struct module *current_module = sandbox_get_module(sandbox); int argument_count = module_get_argument_count(current_module); - // alloc_linear_memory(); + module_initialize_globals(current_module); module_initialize_memory(current_module); @@ -344,7 +344,6 @@ current_sandbox_main(void) #ifdef LOG_TOTAL_REQS_RESPS runtime_total_2XX_responses++; - runtime_log_requests_responses(); #endif sandbox->response_timestamp = __getcycles(); @@ -364,7 +363,7 @@ done: */ assert(0); err: - fprintf(stderr, "%s", error_message); + debuglog("%s", error_message); assert(sandbox->state == SANDBOX_RUNNING); int to_send = strlen(HTTP_RESPONSE_400_BAD_REQUEST); @@ -385,7 +384,6 @@ err: #ifdef LOG_TOTAL_REQS_RESPS runtime_total_4XX_responses++; debuglog("At %llu, Sandbox %lu - 4XX\n", __getcycles(), sandbox->request_arrival_timestamp); - runtime_log_requests_responses(); #endif software_interrupt_disable(); 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)); 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) { case SANDBOX_INITIALIZED: { sandbox->initializing_duration += duration_of_last_state; +#ifdef LOG_SANDBOX_TOTALS + runtime_total_initialized_sandboxes--; + runtime_total_runnable_sandboxes++; +#endif break; } case SANDBOX_BLOCKED: { sandbox->blocked_duration += duration_of_last_state; +#ifdef LOG_SANDBOX_TOTALS + runtime_total_blocked_sandboxes--; + runtime_total_runnable_sandboxes++; +#endif break; } default: { @@ -605,10 +614,18 @@ sandbox_set_as_running(struct sandbox *sandbox, sandbox_state_t last_state) switch (last_state) { case SANDBOX_RUNNABLE: { sandbox->runnable_duration += duration_of_last_state; +#ifdef LOG_SANDBOX_TOTALS + runtime_total_runnable_sandboxes--; + runtime_total_running_sandboxes++; +#endif break; } case SANDBOX_PREEMPTED: { sandbox->preempted_duration += duration_of_last_state; +#ifdef LOG_SANDBOX_TOTALS + runtime_total_preempted_sandboxes--; + runtime_total_running_sandboxes++; +#endif break; } default: { @@ -650,6 +667,10 @@ sandbox_set_as_preempted(struct sandbox *sandbox, sandbox_state_t last_state) switch (last_state) { case SANDBOX_RUNNING: { sandbox->running_duration += duration_of_last_state; +#ifdef LOG_SANDBOX_TOTALS + runtime_total_running_sandboxes--; + runtime_total_preempted_sandboxes++; +#endif break; } default: { @@ -689,6 +710,10 @@ sandbox_set_as_blocked(struct sandbox *sandbox, sandbox_state_t last_state) case SANDBOX_RUNNING: { sandbox->running_duration += duration_of_last_state; local_runqueue_delete(sandbox); +#ifdef LOG_SANDBOX_TOTALS + runtime_total_running_sandboxes--; + runtime_total_blocked_sandboxes++; +#endif break; } default: { @@ -732,6 +757,10 @@ sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state) sandbox->running_duration += duration_of_last_state; local_runqueue_delete(sandbox); sandbox_free_linear_memory(sandbox); +#ifdef LOG_SANDBOX_TOTALS + runtime_total_running_sandboxes--; + runtime_total_returned_sandboxes++; +#endif break; } default: { @@ -774,10 +803,18 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state) case SANDBOX_SET_AS_INITIALIZED: /* Technically, this is a degenerate sandbox that we generate by hand */ sandbox->initializing_duration += duration_of_last_state; +#ifdef LOG_SANDBOX_TOTALS + runtime_total_initialized_sandboxes--; + runtime_total_error_sandboxes++; +#endif break; case SANDBOX_RUNNING: { sandbox->running_duration += duration_of_last_state; local_runqueue_delete(sandbox); +#ifdef LOG_SANDBOX_TOTALS + runtime_total_running_sandboxes--; + runtime_total_error_sandboxes++; +#endif break; } default: { @@ -829,6 +866,10 @@ sandbox_set_as_complete(struct sandbox *sandbox, sandbox_state_t last_state) case SANDBOX_RETURNED: { sandbox->completion_timestamp = now; sandbox->returned_duration += duration_of_last_state; +#ifdef LOG_SANDBOX_TOTALS + runtime_total_returned_sandboxes--; + runtime_total_complete_sandboxes++; +#endif break; } default: { @@ -897,6 +938,9 @@ sandbox_allocate(struct sandbox_request *sandbox_request) /* Set state to initializing */ sandbox_set_as_initialized(sandbox, sandbox_request, now); +#ifdef LOG_SANDBOX_TOTALS + runtime_total_freed_requests++; +#endif free(sandbox_request); done: return sandbox; diff --git a/runtime/tests/preemption/client1.sh b/runtime/tests/preemption/client1.sh index 53aab66..79a2f2e 100755 --- a/runtime/tests/preemption/client1.sh +++ b/runtime/tests/preemption/client1.sh @@ -1,4 +1,4 @@ #!/bin/bash # fib(20) # 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/ diff --git a/runtime/tests/preemption/client2.sh b/runtime/tests/preemption/client2.sh index d028742..efa09f6 100755 --- a/runtime/tests/preemption/client2.sh +++ b/runtime/tests/preemption/client2.sh @@ -1,4 +1,4 @@ #!/bin/bash # fib(10) # 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/