diff options
author | Arjan van de Ven <arjan@linux.intel.com> | 2008-09-07 16:08:55 -0700 |
---|---|---|
committer | Arjan van de Ven <arjan@linux.intel.com> | 2008-09-07 16:11:04 -0700 |
commit | 96d2ab484e7a9bafdab44b8c7d1ef5944319b18c (patch) | |
tree | 3938e40a4b70295d7318d6b14777d0f02004438d /fs/select.c | |
parent | 704af52bd13a5d9f3c60c496c68e752fafdfb434 (diff) |
hrtimer: fix signed/unsigned bug in slack estimator
the slack estimator used unsigned math; however for very short delay it's
possible that by the time you calculate the timeout, it's already passed and
you get a negative time/slack... in an unsigned variable... which then gets
turned into a 100 msec delay rather than zero.
This patch fixes this by using a signed typee in the right places.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Diffstat (limited to 'fs/select.c')
-rw-r--r-- | fs/select.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/select.c b/fs/select.c index fdd8584e536d..448e44001286 100644 --- a/fs/select.c +++ b/fs/select.c @@ -41,9 +41,9 @@ * better solutions.. */ -static unsigned long __estimate_accuracy(struct timespec *tv) +static long __estimate_accuracy(struct timespec *tv) { - unsigned long slack; + long slack; int divfactor = 1000; if (task_nice(current) > 0) @@ -54,10 +54,13 @@ static unsigned long __estimate_accuracy(struct timespec *tv) if (slack > 100 * NSEC_PER_MSEC) slack = 100 * NSEC_PER_MSEC; + + if (slack < 0) + slack = 0; return slack; } -static unsigned long estimate_accuracy(struct timespec *tv) +static long estimate_accuracy(struct timespec *tv) { unsigned long ret; struct timespec now; @@ -330,7 +333,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) timed_out = 1; } - if (end_time) + if (end_time && !timed_out) slack = estimate_accuracy(end_time); retval = 0; @@ -656,7 +659,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list, timed_out = 1; } - if (end_time) + if (end_time && !timed_out) slack = estimate_accuracy(end_time); for (;;) { |