diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index bd9d5ba..b684b61 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -8,8 +8,9 @@ #include "sandbox.h" #include "types.h" -extern int runtime_epoll_file_descriptor; -extern __thread uv_loop_t worker_thread_uvio_handle; +extern int runtime_epoll_file_descriptor; +extern __thread uv_loop_t worker_thread_uvio_handle; +extern float runtime_processor_speed_MHz; void alloc_linear_memory(void); void expand_memory(void); diff --git a/runtime/include/sandbox.h b/runtime/include/sandbox.h index ed2f728..1ac3101 100644 --- a/runtime/include/sandbox.h +++ b/runtime/include/sandbox.h @@ -46,6 +46,7 @@ struct sandbox { u64 total_time; u64 start_time; + u64 absolute_deadline; struct module *module; // the module this is an instance of @@ -97,7 +98,7 @@ extern void worker_thread_wakeup_sandbox(sandbox_t *sandbox); **************************/ struct sandbox *sandbox_allocate(struct module *module, char *arguments, int socket_descriptor, - const struct sockaddr *socket_address, u64 start_time); + const struct sockaddr *socket_address, u64 start_time, u64 absolute_deadline); void sandbox_free(struct sandbox *sandbox); int sandbox_parse_http_request(struct sandbox *sandbox, size_t length); diff --git a/runtime/include/sandbox_request.h b/runtime/include/sandbox_request.h index ffae5a2..ec5c143 100644 --- a/runtime/include/sandbox_request.h +++ b/runtime/include/sandbox_request.h @@ -10,7 +10,8 @@ struct sandbox_request { char * arguments; int socket_descriptor; struct sockaddr *socket_address; - u64 start_time; // cycles + u64 start_time; // cycles + u64 absolute_deadline; // cycles }; typedef struct sandbox_request sandbox_request_t; @@ -36,6 +37,10 @@ sandbox_request_allocate(struct module *module, char *arguments, int socket_desc sandbox_request->socket_descriptor = socket_descriptor; sandbox_request->socket_address = (struct sockaddr *)socket_address; sandbox_request->start_time = start_time; + sandbox_request->absolute_deadline = start_time + module->relative_deadline_us * runtime_processor_speed_MHz; + + // TODO: Refactor to log file + printf("Set absolute deadline of %lu\n", sandbox_request->absolute_deadline); debuglog("[%p: %s]\n", sandbox_request, sandbox_request->module->name); return sandbox_request; diff --git a/runtime/src/main.c b/runtime/src/main.c index 539fc6c..92fcb6e 100644 --- a/runtime/src/main.c +++ b/runtime/src/main.c @@ -18,10 +18,11 @@ i32 runtime_log_file_descriptor = -1; #endif -u32 runtime_total_online_processors = 0; -u32 runtime_total_worker_processors = 0; -u32 runtime_first_worker_processor = 0; -int runtime_worker_threads_argument[WORKER_THREAD_CORE_COUNT] = { 0 }; // The worker sets its argument to -1 on error +float runtime_processor_speed_MHz = 0; +u32 runtime_total_online_processors = 0; +u32 runtime_total_worker_processors = 0; +u32 runtime_first_worker_processor = 0; +int runtime_worker_threads_argument[WORKER_THREAD_CORE_COUNT] = { 0 }; // The worker sets its argument to -1 on error pthread_t runtime_worker_threads[WORKER_THREAD_CORE_COUNT]; @@ -88,8 +89,35 @@ runtime_allocate_available_cores() runtime_total_worker_processors = 1; } printf("Number of cores %u, sandboxing cores %u (start: %u) and module reqs %u\n", - runtime_total_online_processors, runtime_total_worker_processors, runtime_first_worker_processor, - LISTENER_THREAD_CORE_ID); + runtime_total_online_processors, runtime_total_worker_processors, runtime_first_worker_processor, + LISTENER_THREAD_CORE_ID); +} + +/** + * Returns a float of the cpu MHz entry for CPU0 in /proc/cpuinfo + * We are assuming all cores are the same clock speed, which is not true of many systems + * We are also assuming this value is static + * @return proceccor speed in MHz + **/ +static inline float +runtime_get_processor_speed_MHz(void) +{ + FILE *cmd = popen("grep '^cpu MHz' /proc/cpuinfo | head -n 1 | awk '{print $4}'", "r"); + + if (cmd == NULL) return -1; + + float processor_speed_MHz; + size_t n; + char buff[16]; + + if ((n = fread(buff, 1, sizeof(buff) - 1, cmd)) <= 0) return -1; + + buff[n] = '\0'; + if (sscanf(buff, "%f", &processor_speed_MHz) != 1) return -1; + + pclose(cmd); + + return processor_speed_MHz; } #ifdef DEBUG @@ -168,6 +196,9 @@ main(int argc, char **argv) memset(runtime_worker_threads, 0, sizeof(pthread_t) * WORKER_THREAD_CORE_COUNT); + runtime_processor_speed_MHz = runtime_get_processor_speed_MHz(); + printf("Detected processor speed of %f MHz\n", runtime_processor_speed_MHz); + runtime_set_resource_limits_to_max(); runtime_allocate_available_cores(); runtime_initialize(); diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index 006a51c..ba9d0b2 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -272,8 +272,8 @@ worker_thread_pull_and_process_sandbox_requests(void) // Actually allocate the sandbox for the requests that we've pulled struct sandbox *sandbox = sandbox_allocate(sandbox_request->module, sandbox_request->arguments, sandbox_request->socket_descriptor, - sandbox_request->socket_address, - sandbox_request->start_time); + sandbox_request->socket_address, sandbox_request->start_time, + sandbox_request->absolute_deadline); assert(sandbox); free(sandbox_request); // Set the sandbox as runnable and place on the local runqueue diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index e42cc16..7e856e1 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -139,7 +139,17 @@ current_sandbox_build_and_send_client_response(void) done: assert(sndsz == curr->request_response_data_length); // Get End Timestamp - curr->total_time = __getcycles() - curr->start_time; + u64 end_time = __getcycles(); + curr->total_time = end_time - curr->start_time; + // TODO: Refactor to log file + printf("Function returned in %lu cycles\n", curr->total_time); + if (end_time < curr->absolute_deadline) { + printf("Deadline Met with %f us to spare\n", + (curr->absolute_deadline - end_time) / runtime_processor_speed_MHz); + } else { + printf("Deadline NOT MET! Overran by %f us\n", + (end_time - curr->absolute_deadline) / runtime_processor_speed_MHz); + } #ifndef USE_HTTP_UVIO int r = send(curr->client_socket_descriptor, curr->request_response_data, sndsz, 0); @@ -296,7 +306,7 @@ sandbox_allocate_memory(struct module *module) struct sandbox * sandbox_allocate(struct module *module, char *arguments, int socket_descriptor, const struct sockaddr *socket_address, - u64 start_time) + u64 start_time, u64 absolute_deadline) { if (!module_is_valid(module)) return NULL; @@ -306,7 +316,8 @@ sandbox_allocate(struct module *module, char *arguments, int socket_descriptor, if (!sandbox) return NULL; // Assign the start time from the request - sandbox->start_time = start_time; + sandbox->start_time = start_time; + sandbox->absolute_deadline = absolute_deadline; // actual module instantiation! sandbox->arguments = (void *)arguments; diff --git a/runtime/src/sandbox_request_scheduler_ps.c b/runtime/src/sandbox_request_scheduler_ps.c index e9a6185..0f9e6f9 100644 --- a/runtime/src/sandbox_request_scheduler_ps.c +++ b/runtime/src/sandbox_request_scheduler_ps.c @@ -13,6 +13,7 @@ static sandbox_request_t * sandbox_request_scheduler_ps_add(void *sandbox_request_raw) { // TODO + return NULL; } /** @@ -23,6 +24,7 @@ static sandbox_request_t * sandbox_request_scheduler_ps_remove(void) { // TODO + return NULL; } /**