From 5d432a27b1e32bf8591d3ea68329c1b1d5bccc1d Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Thu, 21 Jul 2011 19:59:46 +0200 Subject: [PATCH] sched: Optimize the case of zero timeouts. If a pre_select method calls sched_min_delay() there is no point in calling the pre_select hooks of the other tasks since these can not decrease the timeout any further, and adding file descriptors to the fd sets makes no sense either. So we may break out early in sched_preselect() in this case. If the timeout is zero we may even omit the entire select call as well as the subsequent gettimeofday() since select() will return immediately anyway. This patch teaches sched_postselect() to do so which saves at least two system calls (plus locking in case of para_server) in a rather hot path. --- sched.c | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/sched.c b/sched.c index 7b5ca63d..ca365f17 100644 --- a/sched.c +++ b/sched.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "para.h" #include "ipc.h" @@ -46,14 +47,25 @@ static void unregister_task(struct task *t) list_del(&t->post_select_node); } +static inline bool timeout_is_zero(struct sched *s) +{ + struct timeval *tv = &s->select_timeout; + return tv->tv_sec == 0 && tv->tv_usec == 0; +} + static void sched_preselect(struct sched *s) { struct task *t, *tmp; list_for_each_entry_safe(t, tmp, &pre_select_list, pre_select_node) { - if (t->pre_select) - t->pre_select(s, t); - if (t->error < 0) + if (t->error < 0) { unregister_task(t); + continue; + } + if (!t->pre_select) + continue; + t->pre_select(s, t); + if (timeout_is_zero(s)) + break; } } @@ -131,21 +143,23 @@ again: sched_preselect(s); if (list_empty(&pre_select_list) && list_empty(&post_select_list)) return 0; - ret = s->select_function(s->max_fileno + 1, &s->rfds, &s->wfds, - &s->select_timeout); - if (ret < 0) - return ret; - if (ret == 0) { - /* - * APUE: Be careful not to check the descriptor sets on return - * unless the return value is greater than zero. The return - * state of the descriptor sets is implementation dependent if - * either a signal is caught or the timer expires. - */ - FD_ZERO(&s->rfds); - FD_ZERO(&s->wfds); + if (!timeout_is_zero(s)) { + ret = s->select_function(s->max_fileno + 1, &s->rfds, &s->wfds, + &s->select_timeout); + if (ret < 0) + return ret; + if (ret == 0) { + /* + * APUE: Be careful not to check the descriptor sets on return + * unless the return value is greater than zero. The return + * state of the descriptor sets is implementation dependent if + * either a signal is caught or the timer expires. + */ + FD_ZERO(&s->rfds); + FD_ZERO(&s->wfds); + } + gettimeofday(now, NULL); } - gettimeofday(now, NULL); sched_post_select(s); if (list_empty(&pre_select_list) && list_empty(&post_select_list)) return 0; -- 2.39.5