From 8c28718bcb9ad62f1101383c23c7eb3befb6903b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 19 Nov 2014 09:25:00 -0600 Subject: [PATCH] alling mq_timedreceived with immediate timeout was getting stuck and not timeout. Immediate timeout is achieved by setting absolute timeout value to past time, for example abstime={ .tv_sec=0, .tv_nsec=0 }. However absolute time was converted to relative time using unsigned integer arithmetic and resulted large ticks count by clock_abstime2ticks, instead of expected negative ticks value. Patch corrects clock_abstime2ticks to return negative ticks, if absolute time is in the past. Signed-off-by: Jussi Kivilinna --- sched/clock/clock_abstime2ticks.c | 41 +++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/sched/clock/clock_abstime2ticks.c b/sched/clock/clock_abstime2ticks.c index 1f8845d05d..46b1086856 100644 --- a/sched/clock/clock_abstime2ticks.c +++ b/sched/clock/clock_abstime2ticks.c @@ -1,7 +1,7 @@ /******************************************************************************** * sched/clock/clock_abstime2ticks.c * - * Copyright (C) 2007, 2008, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -64,6 +64,32 @@ * Private Functions ********************************************************************************/ +/******************************************************************************** + * Name: compare_timespec + * + * Description: + * Return < 0 if time a is before time b + * Return > 0 if time b is before time a + * Return 0 if time a is the same as time b + * + ********************************************************************************/ + +static long compare_timespec(FAR const struct timespec *a, + FAR const struct timespec *b) +{ + if (a->tv_sec < b->tv_sec) + { + return -1; + } + + if (a->tv_sec > b->tv_sec) + { + return 1; + } + + return (long)a->tv_nsec -(long)b->tv_nsec; +} + /******************************************************************************** * Public Functions ********************************************************************************/ @@ -100,11 +126,22 @@ int clock_abstime2ticks(clockid_t clockid, FAR const struct timespec *abstime, */ ret = clock_gettime(clockid, &currtime); - if (ret) + if (ret != OK) { return EINVAL; } + if (compare_timespec(abstime, &currtime) < 0) + { + /* Every caller of clock_abstime2ticks check 'ticks < 0' to see if + * absolute time is in the past. So lets just return negative tick + * here. + */ + + *ticks = -1; + return OK; + } + /* The relative time to wait is the absolute time minus the current time. */ reltime.tv_nsec = (abstime->tv_nsec - currtime.tv_nsec);