From: Andre Noll Date: Sat, 30 Mar 2013 22:43:38 +0000 (+0000) Subject: sched: Get rid of (pre)select shortcuts. X-Git-Tag: v0.4.13~39^2~43 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=01f8023b7fe59abc29072c7b84caec5961f8f14b;hp=5bb44a414084464f133beb8810027a18b4254d1f sched: Get rid of (pre)select shortcuts. These shortcuts let the scheduler skip any subsequent ->pre_select() calls as well as the actual call to select(2) if the current task's ->pre_select() requested a zero timeout. This idea turned out to be dubios at best. The main problem is that ->post_select no longer knows whether ->pre_select() and select() have been called. For example, if ->pre_select() monitors some file descriptor, ->post_select() might find it not ready for I/O even when it actually is because ->pre_select() or select() was optimized away. Another problem are tasks whose ->post_select() method expects that ->pre_select() sets some variable in a shared data structure. This patch removes the scheduler optimizations so that all ->pre_select() methods of all tasks are called once per scheduler interval. --- diff --git a/sched.c b/sched.c index 7ee77027..05851621 100644 --- a/sched.c +++ b/sched.c @@ -50,20 +50,12 @@ static inline bool timeout_is_zero(struct sched *s) static void sched_preselect(struct sched *s) { struct task *t, *tmp; + list_for_each_entry_safe(t, tmp, &s->pre_select_list, pre_select_node) { - if (t->error < 0) { - unregister_task(t); - continue; - } - if (t->notification != 0) { + if (t->notification != 0) sched_min_delay(s); - break; - } - if (!t->pre_select) - continue; - t->pre_select(s, t); - if (timeout_is_zero(s)) - break; + if (t->pre_select) + t->pre_select(s, t); } } @@ -130,28 +122,21 @@ again: s->max_fileno = -1; gettimeofday(now, NULL); sched_preselect(s); - if (list_empty(&s->pre_select_list) && list_empty(&s->post_select_list)) - return 0; - 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); - } else { + 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); sched_post_select(s); if (list_empty(&s->pre_select_list) && list_empty(&s->post_select_list)) return 0;