#include #include #include #include #include #include "admissions_control.h" #include "arch/context.h" #include "client_socket.h" #include "debuglog.h" #include "global_request_scheduler_deque.h" #include "global_request_scheduler_minheap.h" #include "http_parser_settings.h" #include "http_response.h" #include "listener_thread.h" #include "module.h" #include "runtime.h" #include "sandbox_request.h" #include "software_interrupt.h" /*************************** * Shared Process State * **************************/ pthread_t runtime_worker_threads[RUNTIME_WORKER_THREAD_CORE_COUNT]; int runtime_worker_threads_argument[RUNTIME_WORKER_THREAD_CORE_COUNT] = { 0 }; /* The active deadline of the sandbox running on each worker thread */ uint64_t runtime_worker_threads_deadline[RUNTIME_WORKER_THREAD_CORE_COUNT] = { UINT64_MAX }; /****************************************** * Shared Process / Listener Thread Logic * *****************************************/ void runtime_cleanup() { if (runtime_sandbox_perf_log != NULL) fflush(runtime_sandbox_perf_log); exit(EXIT_SUCCESS); } /** * Sets the process data segment (RLIMIT_DATA) and # file descriptors * (RLIMIT_NOFILE) soft limit to its hard limit (see man getrlimit) */ void runtime_set_resource_limits_to_max() { struct rlimit limit; const size_t uint64_t_max_digits = 20; char lim[uint64_t_max_digits + 1]; char max[uint64_t_max_digits + 1]; uint64_t resources[] = { RLIMIT_DATA, RLIMIT_NOFILE }; char * resource_names[] = { "RLIMIT_DATA", "RLIMIT_NOFILE" }; for (int i = 0; i < sizeof(resources) / sizeof(resources[0]); i++) { int resource = resources[i]; if (getrlimit(resource, &limit) < 0) panic_err(); if (limit.rlim_cur == RLIM_INFINITY) { strncpy(lim, "Infinite", uint64_t_max_digits); } else { snprintf(lim, uint64_t_max_digits, "%lu", limit.rlim_cur); } if (limit.rlim_max == RLIM_INFINITY) { strncpy(max, "Infinite", uint64_t_max_digits); } else { snprintf(max, uint64_t_max_digits, "%lu", limit.rlim_max); } if (limit.rlim_cur == limit.rlim_max) { printf("\t%s: %s\n", resource_names[i], max); } else { limit.rlim_cur = limit.rlim_max; if (setrlimit(resource, &limit) < 0) panic_err(); printf("\t%s: %s (Increased from %s)\n", resource_names[i], max, lim); } } } /** * Initialize runtime global state, mask signals, and init http parser */ void runtime_initialize(void) { http_total_init(); sandbox_request_count_initialize(); sandbox_count_initialize(); /* Setup Scheduler */ switch (runtime_scheduler) { case RUNTIME_SCHEDULER_EDF: global_request_scheduler_minheap_initialize(); break; case RUNTIME_SCHEDULER_FIFO: global_request_scheduler_deque_initialize(); break; default: panic("Invalid scheduler policy set: %u\n", runtime_scheduler); } /* Configure Signals */ signal(SIGPIPE, SIG_IGN); signal(SIGTERM, runtime_cleanup); /* These should only be unmasked by workers */ software_interrupt_mask_signal(SIGUSR1); software_interrupt_mask_signal(SIGALRM); http_parser_settings_initialize(); admissions_control_initialize(); }