diff --git a/docs/rtpengine.md b/docs/rtpengine.md index e1fa9a175..fd172107e 100644 --- a/docs/rtpengine.md +++ b/docs/rtpengine.md @@ -370,6 +370,13 @@ call to inject-DTMF won't be sent to __\-\-dtmf-log-dest=__ or __\-\-listen-tcp- So for example, if this option is set to 4, in total 8 threads will be launched. +- __\-\-poller-size=__*INT* + + Set the maximum number of event items (file descriptors) to retrieve from + the underlying system poll mechanism per iteration. Defaults to 128. A + lower number can lead to improved load-balancing among a large number of + threads. + - __\-\-thread-stack=__*INT* Set the stack size of each thread to the value given in kB. Defaults to 2048 diff --git a/lib/auxlib.c b/lib/auxlib.c index 438644488..995e2eef3 100644 --- a/lib/auxlib.c +++ b/lib/auxlib.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "log.h" #include "loglib.h" @@ -212,6 +213,7 @@ void config_load(int *argc, char ***argv, GOptionEntry *app_entries, const char { "pidfile", 'p', 0, G_OPTION_ARG_FILENAME, &rtpe_common_config_ptr->pidfile, "Write PID to file", "FILE" }, { "foreground", 'f', 0, G_OPTION_ARG_NONE, &rtpe_common_config_ptr->foreground, "Don't fork to background", NULL }, { "thread-stack", 0,0, G_OPTION_ARG_INT, &rtpe_common_config_ptr->thread_stack, "Thread stack size in kB", "INT" }, + { "poller-size", 0,0, G_OPTION_ARG_INT, &rtpe_common_config_ptr->poller_size, "Max poller items per iteration", "INT" }, { "evs-lib-path", 0,0, G_OPTION_ARG_FILENAME, &rtpe_common_config_ptr->evs_lib_path, "Location of .so for 3GPP EVS codec", "FILE" }, { NULL, } }; @@ -387,6 +389,8 @@ out: if (rtpe_common_config_ptr->thread_stack == 0) rtpe_common_config_ptr->thread_stack = 2048; + if (rtpe_common_config_ptr->poller_size <= 0) + rtpe_common_config_ptr->poller_size = 128; return; diff --git a/lib/auxlib.h b/lib/auxlib.h index 191421f10..7d8807680 100644 --- a/lib/auxlib.h +++ b/lib/auxlib.h @@ -31,6 +31,7 @@ struct rtpengine_common_config { char *pidfile; int foreground; int thread_stack; + int poller_size; int max_log_line_length; char *evs_lib_path; }; diff --git a/lib/poller.c b/lib/poller.c index 3ac209646..9f75bd7ca 100644 --- a/lib/poller.c +++ b/lib/poller.c @@ -222,17 +222,17 @@ int poller_del_item(struct poller *p, int fd) { } -static int poller_poll(struct poller *p, int timeout) { +static int poller_poll(struct poller *p, int timeout, struct epoll_event *evs, int poller_size) { int ret, i; struct poller_item_int *it; - struct epoll_event evs[128], *ev, e; + struct epoll_event *ev, e; if (!p) return -1; errno = 0; thread_cancel_enable(); - ret = epoll_wait(p->fd, evs, sizeof(evs) / sizeof(*evs), timeout); + ret = epoll_wait(p->fd, evs, poller_size, timeout); thread_cancel_disable(); mutex_lock(&p->lock); @@ -378,10 +378,18 @@ void poller_loop(void *d) { void poller_loop2(void *d) { struct poller *p = d; + int poller_size = rtpe_common_config_ptr->poller_size; + struct epoll_event *evs; + + evs = g_malloc(sizeof(*evs) * poller_size); + + thread_cleanup_push(g_free, evs); while (!rtpe_shutdown) { - int ret = poller_poll(p, thread_sleep_time); + int ret = poller_poll(p, thread_sleep_time, evs, poller_size); if (ret < 0) usleep(20 * 1000); } + + thread_cleanup_pop(true); }