mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-30 14:58:21 +00:00
MINOR: fd: centralize poll timeout computation in compute_poll_timeout()
The 4 pollers all contain the same code used to compute the poll timeout. This is pointless, let's centralize this into fd.h. This also gets rid of the useless SCHEDULER_RESOLUTION macro which used to work arond a very old linux 2.2 bug causing select() to wake up slightly before the timeout.
This commit is contained in:
parent
b75e828b29
commit
f37ba94768
@ -26,13 +26,6 @@
|
|||||||
#include <common/compat.h>
|
#include <common/compat.h>
|
||||||
#include <common/defaults.h>
|
#include <common/defaults.h>
|
||||||
|
|
||||||
/* this reduces the number of calls to select() by choosing appropriate
|
|
||||||
* sheduler precision in milliseconds. It should be near the minimum
|
|
||||||
* time that is needed by select() to collect all events. All timeouts
|
|
||||||
* are rounded up by adding this value prior to pass it to select().
|
|
||||||
*/
|
|
||||||
#define SCHEDULER_RESOLUTION 9
|
|
||||||
|
|
||||||
/* CONFIG_HAP_MEM_OPTIM
|
/* CONFIG_HAP_MEM_OPTIM
|
||||||
* This enables use of memory pools instead of malloc()/free(). There
|
* This enables use of memory pools instead of malloc()/free(). There
|
||||||
* is no reason to disable it, except perhaps for rare debugging.
|
* is no reason to disable it, except perhaps for rare debugging.
|
||||||
|
@ -28,8 +28,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <common/ticks.h>
|
||||||
|
#include <common/time.h>
|
||||||
|
|
||||||
#include <types/fd.h>
|
#include <types/fd.h>
|
||||||
|
#include <types/global.h>
|
||||||
|
|
||||||
/* public variables */
|
/* public variables */
|
||||||
|
|
||||||
@ -528,6 +531,30 @@ static inline void fd_insert(int fd, void *owner, void (*iocb)(int fd), unsigned
|
|||||||
HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
|
HA_SPIN_UNLOCK(FD_LOCK, &fdtab[fd].lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Computes the bounded poll() timeout based on the next expiration timer <next>
|
||||||
|
* by bounding it to MAX_DELAY_MS. <next> may equal TICK_ETERNITY. The pollers
|
||||||
|
* just needs to call this function right before polling to get their timeout
|
||||||
|
* value. Timeouts that are already expired (possibly due to a pending event)
|
||||||
|
* are accounted for in activity.poll_exp.
|
||||||
|
*/
|
||||||
|
static inline int compute_poll_timeout(int next)
|
||||||
|
{
|
||||||
|
int wait_time;
|
||||||
|
|
||||||
|
if (!tick_isset(next))
|
||||||
|
wait_time = MAX_DELAY_MS;
|
||||||
|
else if (tick_is_expired(next, now_ms)) {
|
||||||
|
activity[tid].poll_exp++;
|
||||||
|
wait_time = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wait_time = TICKS_TO_MS(tick_remain(now_ms, next)) + 1;
|
||||||
|
if (wait_time > MAX_DELAY_MS)
|
||||||
|
wait_time = MAX_DELAY_MS;
|
||||||
|
}
|
||||||
|
return wait_time;
|
||||||
|
}
|
||||||
|
|
||||||
/* These are replacements for FD_SET, FD_CLR, FD_ISSET, working on uints */
|
/* These are replacements for FD_SET, FD_CLR, FD_ISSET, working on uints */
|
||||||
static inline void hap_fd_set(int fd, unsigned int *evts)
|
static inline void hap_fd_set(int fd, unsigned int *evts)
|
||||||
{
|
{
|
||||||
|
@ -144,21 +144,8 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
|
|
||||||
thread_harmless_now();
|
thread_harmless_now();
|
||||||
|
|
||||||
/* compute the epoll_wait() timeout */
|
|
||||||
if (!exp)
|
|
||||||
wait_time = MAX_DELAY_MS;
|
|
||||||
else if (tick_is_expired(exp, now_ms)) {
|
|
||||||
activity[tid].poll_exp++;
|
|
||||||
wait_time = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
wait_time = TICKS_TO_MS(tick_remain(now_ms, exp)) + 1;
|
|
||||||
if (wait_time > MAX_DELAY_MS)
|
|
||||||
wait_time = MAX_DELAY_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now let's wait for polled events */
|
/* now let's wait for polled events */
|
||||||
|
wait_time = compute_poll_timeout(exp);
|
||||||
gettimeofday(&before_poll, NULL);
|
gettimeofday(&before_poll, NULL);
|
||||||
status = epoll_wait(epoll_fd[tid], epoll_events, global.tune.maxpollevents, wait_time);
|
status = epoll_wait(epoll_fd[tid], epoll_events, global.tune.maxpollevents, wait_time);
|
||||||
tv_update_date(wait_time, status);
|
tv_update_date(wait_time, status);
|
||||||
|
@ -129,23 +129,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
}
|
}
|
||||||
fd_nbupdt = 0;
|
fd_nbupdt = 0;
|
||||||
|
|
||||||
delta_ms = 0;
|
/* now let's wait for events */
|
||||||
|
delta_ms = compute_poll_timeout(exp);
|
||||||
if (!exp) {
|
timeout.tv_sec = (delta_ms / 1000);
|
||||||
delta_ms = MAX_DELAY_MS;
|
timeout.tv_nsec = (delta_ms % 1000) * 1000000;
|
||||||
timeout.tv_sec = (MAX_DELAY_MS / 1000);
|
|
||||||
timeout.tv_nsec = (MAX_DELAY_MS % 1000) * 1000000;
|
|
||||||
}
|
|
||||||
else if (!tick_is_expired(exp, now_ms)) {
|
|
||||||
delta_ms = TICKS_TO_MS(tick_remain(now_ms, exp)) + 1;
|
|
||||||
if (delta_ms > MAX_DELAY_MS)
|
|
||||||
delta_ms = MAX_DELAY_MS;
|
|
||||||
timeout.tv_sec = (delta_ms / 1000);
|
|
||||||
timeout.tv_nsec = (delta_ms % 1000) * 1000000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
activity[tid].poll_exp++;
|
|
||||||
|
|
||||||
fd = global.tune.maxpollevents;
|
fd = global.tune.maxpollevents;
|
||||||
gettimeofday(&before_poll, NULL);
|
gettimeofday(&before_poll, NULL);
|
||||||
status = kevent(kqueue_fd[tid], // int kq
|
status = kevent(kqueue_fd[tid], // int kq
|
||||||
|
@ -193,18 +193,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now let's wait for events */
|
/* now let's wait for events */
|
||||||
if (!exp)
|
wait_time = compute_poll_timeout(exp);
|
||||||
wait_time = MAX_DELAY_MS;
|
|
||||||
else if (tick_is_expired(exp, now_ms)) {
|
|
||||||
activity[tid].poll_exp++;
|
|
||||||
wait_time = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
wait_time = TICKS_TO_MS(tick_remain(now_ms, exp)) + 1;
|
|
||||||
if (wait_time > MAX_DELAY_MS)
|
|
||||||
wait_time = MAX_DELAY_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
gettimeofday(&before_poll, NULL);
|
gettimeofday(&before_poll, NULL);
|
||||||
status = poll(poll_events, nbfd, wait_time);
|
status = poll(poll_events, nbfd, wait_time);
|
||||||
tv_update_date(wait_time, status);
|
tv_update_date(wait_time, status);
|
||||||
|
@ -160,25 +160,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
writenotnull |= (*(((int*)tmp_evts[DIR_WR])+i) = *(((int*)fd_evts[DIR_WR])+i)) != 0;
|
writenotnull |= (*(((int*)tmp_evts[DIR_WR])+i) = *(((int*)fd_evts[DIR_WR])+i)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
delta_ms = 0;
|
/* now let's wait for events */
|
||||||
delta.tv_sec = 0;
|
delta_ms = compute_poll_timeout(exp);
|
||||||
delta.tv_usec = 0;
|
delta.tv_sec = (delta_ms / 1000);
|
||||||
|
delta.tv_usec = (delta_ms % 1000) * 1000;
|
||||||
if (!exp) {
|
|
||||||
delta_ms = MAX_DELAY_MS;
|
|
||||||
delta.tv_sec = (MAX_DELAY_MS / 1000);
|
|
||||||
delta.tv_usec = (MAX_DELAY_MS % 1000) * 1000;
|
|
||||||
}
|
|
||||||
else if (!tick_is_expired(exp, now_ms)) {
|
|
||||||
delta_ms = TICKS_TO_MS(tick_remain(now_ms, exp)) + SCHEDULER_RESOLUTION;
|
|
||||||
if (delta_ms > MAX_DELAY_MS)
|
|
||||||
delta_ms = MAX_DELAY_MS;
|
|
||||||
delta.tv_sec = (delta_ms / 1000);
|
|
||||||
delta.tv_usec = (delta_ms % 1000) * 1000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
activity[tid].poll_exp++;
|
|
||||||
|
|
||||||
gettimeofday(&before_poll, NULL);
|
gettimeofday(&before_poll, NULL);
|
||||||
status = select(maxfd,
|
status = select(maxfd,
|
||||||
readnotnull ? tmp_evts[DIR_RD] : NULL,
|
readnotnull ? tmp_evts[DIR_RD] : NULL,
|
||||||
|
Loading…
Reference in New Issue
Block a user