mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 22:01:31 +02:00
MEDIUM: poller: separate the wait time from the wake events
We have been abusing the do_poll()'s timeout for a while, making it zero whenever there is some known activity. The problem this poses is that it complicates activity diagnostic by incrementing the poll_exp field for each known activity. It also requires extra computations that could be avoided. This change passes a "wake" argument to say that the poller must not sleep. This simplifies the operations and allows one to differenciate expirations from activity.
This commit is contained in:
parent
d78d08f95b
commit
2ae84e445d
@ -142,7 +142,7 @@ struct fdinfo {
|
|||||||
* - <private> is initialized by the poller's init() function, and cleaned by
|
* - <private> is initialized by the poller's init() function, and cleaned by
|
||||||
* the term() function.
|
* the term() function.
|
||||||
* - clo() should be used to do indicate the poller that fd will be closed.
|
* - clo() should be used to do indicate the poller that fd will be closed.
|
||||||
* - poll() calls the poller, expiring at <exp>
|
* - poll() calls the poller, expiring at <exp>, or immediately if <wake> is set
|
||||||
* - flags indicate what the poller supports (HAP_POLL_F_*)
|
* - flags indicate what the poller supports (HAP_POLL_F_*)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ struct fdinfo {
|
|||||||
struct poller {
|
struct poller {
|
||||||
void *private; /* any private data for the poller */
|
void *private; /* any private data for the poller */
|
||||||
void REGPRM1 (*clo)(const int fd); /* mark <fd> as closed */
|
void REGPRM1 (*clo)(const int fd); /* mark <fd> as closed */
|
||||||
void REGPRM2 (*poll)(struct poller *p, int exp); /* the poller itself */
|
void REGPRM3 (*poll)(struct poller *p, int exp, int wake); /* the poller itself */
|
||||||
int REGPRM1 (*init)(struct poller *p); /* poller initialization */
|
int REGPRM1 (*init)(struct poller *p); /* poller initialization */
|
||||||
void REGPRM1 (*term)(struct poller *p); /* termination of this poller */
|
void REGPRM1 (*term)(struct poller *p); /* termination of this poller */
|
||||||
int REGPRM1 (*test)(struct poller *p); /* pre-init check of the poller */
|
int REGPRM1 (*test)(struct poller *p); /* pre-init check of the poller */
|
||||||
|
@ -103,7 +103,7 @@ static void _update_fd(int fd)
|
|||||||
/*
|
/*
|
||||||
* Linux epoll() poller
|
* Linux epoll() poller
|
||||||
*/
|
*/
|
||||||
REGPRM2 static void _do_poll(struct poller *p, int exp)
|
REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int fd;
|
int fd;
|
||||||
@ -147,7 +147,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
thread_harmless_now();
|
thread_harmless_now();
|
||||||
|
|
||||||
/* now let's wait for polled events */
|
/* now let's wait for polled events */
|
||||||
wait_time = compute_poll_timeout(exp);
|
wait_time = wake ? 0 : compute_poll_timeout(exp);
|
||||||
tv_entering_poll();
|
tv_entering_poll();
|
||||||
activity_count_runtime();
|
activity_count_runtime();
|
||||||
do {
|
do {
|
||||||
@ -160,7 +160,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
break;
|
break;
|
||||||
if (timeout || !wait_time)
|
if (timeout || !wait_time)
|
||||||
break;
|
break;
|
||||||
if (signal_queue_len)
|
if (signal_queue_len || wake)
|
||||||
break;
|
break;
|
||||||
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
|
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
|
||||||
break;
|
break;
|
||||||
|
@ -96,7 +96,7 @@ static void _update_fd(int fd)
|
|||||||
* "src/fd.c" for more information.
|
* "src/fd.c" for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
REGPRM2 static void _do_poll(struct poller *p, int exp)
|
REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int wait_time;
|
int wait_time;
|
||||||
@ -144,7 +144,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
/*
|
/*
|
||||||
* Determine how long to wait for events to materialise on the port.
|
* Determine how long to wait for events to materialise on the port.
|
||||||
*/
|
*/
|
||||||
wait_time = compute_poll_timeout(exp);
|
wait_time = wake ? 0 : compute_poll_timeout(exp);
|
||||||
tv_entering_poll();
|
tv_entering_poll();
|
||||||
activity_count_runtime();
|
activity_count_runtime();
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
break;
|
break;
|
||||||
if (timeout || !wait_time)
|
if (timeout || !wait_time)
|
||||||
break;
|
break;
|
||||||
if (signal_queue_len)
|
if (signal_queue_len || wake)
|
||||||
break;
|
break;
|
||||||
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
|
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
|
||||||
break;
|
break;
|
||||||
|
@ -74,7 +74,7 @@ static int _update_fd(int fd, int start)
|
|||||||
/*
|
/*
|
||||||
* kqueue() poller
|
* kqueue() poller
|
||||||
*/
|
*/
|
||||||
REGPRM2 static void _do_poll(struct poller *p, int exp)
|
REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int count, fd, wait_time;
|
int count, fd, wait_time;
|
||||||
@ -132,7 +132,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
fd_nbupdt = 0;
|
fd_nbupdt = 0;
|
||||||
|
|
||||||
/* now let's wait for events */
|
/* now let's wait for events */
|
||||||
wait_time = compute_poll_timeout(exp);
|
wait_time = wake ? 0 : compute_poll_timeout(exp);
|
||||||
fd = global.tune.maxpollevents;
|
fd = global.tune.maxpollevents;
|
||||||
tv_entering_poll();
|
tv_entering_poll();
|
||||||
activity_count_runtime();
|
activity_count_runtime();
|
||||||
@ -155,7 +155,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
break;
|
break;
|
||||||
if (timeout || !wait_time)
|
if (timeout || !wait_time)
|
||||||
break;
|
break;
|
||||||
if (signal_queue_len)
|
if (signal_queue_len || wake)
|
||||||
break;
|
break;
|
||||||
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
|
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
|
||||||
break;
|
break;
|
||||||
|
@ -88,7 +88,7 @@ static void _update_fd(int fd, int *max_add_fd)
|
|||||||
/*
|
/*
|
||||||
* Poll() poller
|
* Poll() poller
|
||||||
*/
|
*/
|
||||||
REGPRM2 static void _do_poll(struct poller *p, int exp)
|
REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int fd;
|
int fd;
|
||||||
@ -194,7 +194,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now let's wait for events */
|
/* now let's wait for events */
|
||||||
wait_time = compute_poll_timeout(exp);
|
wait_time = wake ? 0 : compute_poll_timeout(exp);
|
||||||
tv_entering_poll();
|
tv_entering_poll();
|
||||||
activity_count_runtime();
|
activity_count_runtime();
|
||||||
status = poll(poll_events, nbfd, wait_time);
|
status = poll(poll_events, nbfd, wait_time);
|
||||||
|
@ -79,7 +79,7 @@ static void _update_fd(int fd, int *max_add_fd)
|
|||||||
/*
|
/*
|
||||||
* Select() poller
|
* Select() poller
|
||||||
*/
|
*/
|
||||||
REGPRM2 static void _do_poll(struct poller *p, int exp)
|
REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int fd, i;
|
int fd, i;
|
||||||
@ -162,7 +162,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now let's wait for events */
|
/* now let's wait for events */
|
||||||
delta_ms = compute_poll_timeout(exp);
|
delta_ms = wake ? 0 : compute_poll_timeout(exp);
|
||||||
delta.tv_sec = (delta_ms / 1000);
|
delta.tv_sec = (delta_ms / 1000);
|
||||||
delta.tv_usec = (delta_ms % 1000) * 1000;
|
delta.tv_usec = (delta_ms % 1000) * 1000;
|
||||||
tv_entering_poll();
|
tv_entering_poll();
|
||||||
|
@ -2505,7 +2505,7 @@ void deinit(void)
|
|||||||
/* Runs the polling loop */
|
/* Runs the polling loop */
|
||||||
static void run_poll_loop()
|
static void run_poll_loop()
|
||||||
{
|
{
|
||||||
int next, exp;
|
int next, wake;
|
||||||
|
|
||||||
tv_update_date(0,1);
|
tv_update_date(0,1);
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -2525,7 +2525,7 @@ static void run_poll_loop()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* expire immediately if events are pending */
|
/* expire immediately if events are pending */
|
||||||
exp = now_ms;
|
wake = 1;
|
||||||
if (fd_cache_mask & tid_bit)
|
if (fd_cache_mask & tid_bit)
|
||||||
activity[tid].wake_cache++;
|
activity[tid].wake_cache++;
|
||||||
else if (active_tasks_mask & tid_bit)
|
else if (active_tasks_mask & tid_bit)
|
||||||
@ -2539,11 +2539,11 @@ static void run_poll_loop()
|
|||||||
activity[tid].wake_tasks++;
|
activity[tid].wake_tasks++;
|
||||||
_HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
|
_HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
|
||||||
} else
|
} else
|
||||||
exp = next;
|
wake = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The poller will ensure it returns around <next> */
|
/* The poller will ensure it returns around <next> */
|
||||||
cur_poller.poll(&cur_poller, exp);
|
cur_poller.poll(&cur_poller, next, wake);
|
||||||
if (sleeping_thread_mask & tid_bit)
|
if (sleeping_thread_mask & tid_bit)
|
||||||
_HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
|
_HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
|
||||||
fd_process_cached_events();
|
fd_process_cached_events();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user