chore: rlimit cleanup

main
Sean McBride 4 years ago
parent 26e0a3d91d
commit de8def59cc

@ -56,7 +56,8 @@
"features.h": "c", "features.h": "c",
"time.h": "c", "time.h": "c",
"local_runqueue_minheap.h": "c", "local_runqueue_minheap.h": "c",
"global_request_scheduler.h": "c" "global_request_scheduler.h": "c",
"dlfcn.h": "c"
}, },
"files.exclude": { "files.exclude": {
"**/.git": true, "**/.git": true,

@ -42,18 +42,25 @@
#define RUNTIME_WORKER_THREAD_CORE_COUNT (NCORES > 1 ? NCORES - 1 : NCORES) #define RUNTIME_WORKER_THREAD_CORE_COUNT (NCORES > 1 ? NCORES - 1 : NCORES)
enum RUNTIME_SCHEDULER
{
RUNTIME_SCHEDULER_FIFO = 0,
RUNTIME_SCHEDULER_EDF = 1
};
enum RUNTIME_SIGALRM_HANDLER
{
RUNTIME_SIGALRM_HANDLER_BROADCAST = 0,
RUNTIME_SIGALRM_HANDLER_TRIAGED = 1
};
/* /*
* Descriptor of the epoll instance used to monitor the socket descriptors of registered * Descriptor of the epoll instance used to monitor the socket descriptors of registered
* serverless modules. The listener cores listens for incoming client requests through this. * serverless modules. The listener cores listens for incoming client requests through this.
*/ */
extern int runtime_epoll_file_descriptor; extern int runtime_epoll_file_descriptor;
extern int runtime_worker_threads_argument[RUNTIME_WORKER_THREAD_CORE_COUNT]; extern bool runtime_preemption_enabled;
extern uint64_t runtime_worker_threads_deadline[RUNTIME_WORKER_THREAD_CORE_COUNT];
/* Optional path to a file to log sandbox perf metrics */
extern FILE *runtime_sandbox_perf_log;
/* /*
* Assumption: All cores are the same speed * Assumption: All cores are the same speed
@ -61,17 +68,29 @@ extern FILE *runtime_sandbox_perf_log;
*/ */
extern uint32_t runtime_processor_speed_MHz; extern uint32_t runtime_processor_speed_MHz;
extern uint32_t runtime_quantum_us;
/* Optional path to a file to log sandbox perf metrics */
extern FILE *runtime_sandbox_perf_log;
extern enum RUNTIME_SCHEDULER runtime_scheduler;
extern enum RUNTIME_SIGALRM_HANDLER runtime_sigalrm_handler;
/* Count of worker threads and array of their pthread identifiers */ /* Count of worker threads and array of their pthread identifiers */
extern pthread_t runtime_worker_threads[]; extern pthread_t runtime_worker_threads[];
extern uint32_t runtime_worker_threads_count; extern uint32_t runtime_worker_threads_count;
extern int runtime_worker_threads_argument[RUNTIME_WORKER_THREAD_CORE_COUNT];
extern uint64_t runtime_worker_threads_deadline[RUNTIME_WORKER_THREAD_CORE_COUNT];
void alloc_linear_memory(void); extern void alloc_linear_memory(void);
void expand_memory(void); extern void expand_memory(void);
INLINE char *get_function_from_table(uint32_t idx, uint32_t type_id); INLINE char *get_function_from_table(uint32_t idx, uint32_t type_id);
INLINE char *get_memory_ptr_for_runtime(uint32_t offset, uint32_t bounds_check); INLINE char *get_memory_ptr_for_runtime(uint32_t offset, uint32_t bounds_check);
void runtime_initialize(void); extern void listener_thread_initialize(void);
void listener_thread_initialize(void); extern void runtime_initialize(void);
void stub_init(int32_t offset); extern void runtime_set_resource_limits_to_max();
extern void stub_init(int32_t offset);
unsigned long long __getcycles(void); unsigned long long __getcycles(void);
@ -90,12 +109,6 @@ runtime_is_worker()
return false; return false;
} }
enum RUNTIME_SCHEDULER
{
RUNTIME_SCHEDULER_FIFO = 0,
RUNTIME_SCHEDULER_EDF = 1
};
static inline char * static inline char *
print_runtime_scheduler(enum RUNTIME_SCHEDULER variant) print_runtime_scheduler(enum RUNTIME_SCHEDULER variant)
{ {
@ -107,13 +120,6 @@ print_runtime_scheduler(enum RUNTIME_SCHEDULER variant)
} }
}; };
enum RUNTIME_SIGALRM_HANDLER
{
RUNTIME_SIGALRM_HANDLER_BROADCAST = 0,
RUNTIME_SIGALRM_HANDLER_TRIAGED = 1
};
static inline char * static inline char *
print_runtime_sigalrm_handler(enum RUNTIME_SIGALRM_HANDLER variant) print_runtime_sigalrm_handler(enum RUNTIME_SIGALRM_HANDLER variant)
{ {
@ -124,8 +130,3 @@ print_runtime_sigalrm_handler(enum RUNTIME_SIGALRM_HANDLER variant)
return "TRIAGED"; return "TRIAGED";
} }
}; };
extern enum RUNTIME_SCHEDULER runtime_scheduler;
extern enum RUNTIME_SIGALRM_HANDLER runtime_sigalrm_handler;
extern bool runtime_preemption_enabled;
extern uint32_t runtime_quantum_us;

@ -5,7 +5,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <sched.h> #include <sched.h>
#include <sys/resource.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
@ -25,7 +24,6 @@
/* Conditionally used by debuglog when NDEBUG is not set */ /* Conditionally used by debuglog when NDEBUG is not set */
int32_t debuglog_file_descriptor = -1; int32_t debuglog_file_descriptor = -1;
uint32_t runtime_processor_speed_MHz = 0; uint32_t runtime_processor_speed_MHz = 0;
uint32_t runtime_total_online_processors = 0; uint32_t runtime_total_online_processors = 0;
uint32_t runtime_worker_threads_count = 0; uint32_t runtime_worker_threads_count = 0;
@ -52,34 +50,6 @@ runtime_usage(char *cmd)
printf("%s <modules_file>\n", cmd); printf("%s <modules_file>\n", cmd);
} }
/**
* 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 resource_limit;
if (getrlimit(RLIMIT_DATA, &resource_limit) < 0) {
perror("getrlimit RLIMIT_DATA");
exit(-1);
}
resource_limit.rlim_cur = resource_limit.rlim_max;
if (setrlimit(RLIMIT_DATA, &resource_limit) < 0) {
perror("setrlimit RLIMIT_DATA");
exit(-1);
}
if (getrlimit(RLIMIT_NOFILE, &resource_limit) < 0) {
perror("getrlimit RLIMIT_NOFILE");
exit(-1);
}
resource_limit.rlim_cur = resource_limit.rlim_max;
if (setrlimit(RLIMIT_NOFILE, &resource_limit) < 0) {
perror("setrlimit RLIMIT_NOFILE");
exit(-1);
}
}
/** /**
* Check the number of cores and the compiler flags and allocate available cores * Check the number of cores and the compiler flags and allocate available cores
*/ */

@ -1,6 +1,7 @@
#include <signal.h> #include <signal.h>
#include <sched.h> #include <sched.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/resource.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "admissions_control.h" #include "admissions_control.h"
@ -38,6 +39,45 @@ runtime_cleanup()
exit(EXIT_SUCCESS); 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 * Initialize runtime global state, mask signals, and init http parser
*/ */
@ -99,8 +139,8 @@ listener_thread_stop_lock_overhead_measurement()
} }
/** /**
* @brief Execution Loop of the listener core, io_handles HTTP requests, allocates sandbox request objects, and pushes * @brief Execution Loop of the listener core, io_handles HTTP requests, allocates sandbox request objects, and
* the sandbox object to the global dequeue * pushes the sandbox object to the global dequeue
* @param dummy data pointer provided by pthreads API. Unused in this function * @param dummy data pointer provided by pthreads API. Unused in this function
* @return NULL * @return NULL
* *
@ -125,7 +165,8 @@ listener_thread_main(void *dummy)
panic("epoll_wait: %s", strerror(errno)); panic("epoll_wait: %s", strerror(errno));
} }
/* Assumption: Because epoll_wait is set to not timeout, we should always have descriptors here */ /* Assumption: Because epoll_wait is set to not timeout, we should always have descriptors here
*/
assert(descriptor_count > 0); assert(descriptor_count > 0);
uint64_t request_arrival_timestamp = __getcycles(); uint64_t request_arrival_timestamp = __getcycles();
@ -142,7 +183,8 @@ listener_thread_main(void *dummy)
panic("epoll_wait"); panic("epoll_wait");
}; };
/* Assumption: We have only registered EPOLLIN events, so we should see no others here */ /* Assumption: We have only registered EPOLLIN events, so we should see no others here
*/
assert((epoll_events[i].events & EPOLLIN) == EPOLLIN); assert((epoll_events[i].events & EPOLLIN) == EPOLLIN);
/* Unpack module from epoll event */ /* Unpack module from epoll event */
@ -161,7 +203,8 @@ listener_thread_main(void *dummy)
/* /*
* Accept as many requests as possible, terminating when we would have blocked * 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 * This inner loop is used in case there are more datagrams than epoll events for some
* reason
*/ */
while (true) { while (true) {
int client_socket = accept4(module->socket_descriptor, int client_socket = accept4(module->socket_descriptor,
@ -179,13 +222,12 @@ listener_thread_main(void *dummy)
assert(client_socket != STDERR_FILENO); assert(client_socket != STDERR_FILENO);
/* /*
* According to accept(2), it is possible that the the sockaddr structure client_address * According to accept(2), it is possible that the the sockaddr structure
* may be too small, resulting in data being truncated to fit. The accept call mutates * client_address may be too small, resulting in data being truncated to fit.
* the size value to indicate that this is the case. * The accept call mutates 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 " debuglog("Client address %s truncated because buffer was too small\n",
"small\n",
module->name); module->name);
} }

Loading…
Cancel
Save