From 35c5bb8e0f177643ec8d182d5a8fe2a813a3a2ad Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 10 Jan 2013 14:07:30 +0000 Subject: [PATCH] Fix rounding in clock_time2ticks(). From Mike Smith. git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5502 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/ChangeLog | 2 ++ nuttx/sched/clock_time2ticks.c | 42 ++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 3d124073b8..758e8c862e 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3897,4 +3897,6 @@ arch/arm/src/lm so that is can support other members of the Stellaris family. * libc/spawn: Add file action interfaces needed by posix_spawn(). + * sched/clock_time2ticks.c: Another case where time was being + rounded down instead of up (from Mikek Smith). diff --git a/nuttx/sched/clock_time2ticks.c b/nuttx/sched/clock_time2ticks.c index 383264d513..012f4e4f1a 100644 --- a/nuttx/sched/clock_time2ticks.c +++ b/nuttx/sched/clock_time2ticks.c @@ -89,14 +89,48 @@ int clock_time2ticks(FAR const struct timespec *reltime, FAR int *ticks) { +#ifdef CONFIG_HAVE_LONG_LONG + int64_t relnsec; + + /* Convert the relative time into nanoseconds. The range of the int64_t is + * sufficiently large that there is no real need for range checking. + */ + + relnsec = (int64_t)reltime->tv_sec * NSEC_PER_SEC + + (int64_t)reltime->tv_nsec; + + /* Convert nanoseconds to clock ticks, rounding up to the smallest integer + * that is greater than or equal to the exact number of tick. + */ + + *ticks = (int)((relnsec + NSEC_PER_TICK - 1) / NSEC_PER_TICK); + return OK; +#else int32_t relusec; - /* Convert the relative time into microseconds.*/ + /* This function uses an int32_t to only the relative time in microseconds. + * that means that the maximum supported relative time is 2,147,487.647 + * seconds + */ - relusec = reltime->tv_sec * USEC_PER_SEC + reltime->tv_nsec / NSEC_PER_USEC; +#if 0 // overkill + DEBUGASSERT(reltime->tv_sec < 2147487 || + reltime->tv_sec == 2147487 && + reltime->tv_nsec <= 647 * NSEC_PER_MSEC); +#endif - /* Convert microseconds to clock ticks */ + /* Convert the relative time into microseconds, rounding up to the smallest + * value that is greater than or equal to the exact number of microseconds. + */ - *ticks = relusec / USEC_PER_TICK; + relusec = reltime->tv_sec * USEC_PER_SEC + + (reltime->tv_nsec + NSEC_PER_USEC - 1) / NSEC_PER_USEC; + + /* Convert microseconds to clock ticks, rounding up to the smallest integer + * that is greater than or equal to the exact number of tick. + */ + + *ticks = (int)((relusec + USEC_PER_TICK - 1) / USEC_PER_TICK); return OK; +#endif }