summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-12-24 14:31:02 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-12-24 14:31:02 +0000
commit50cadb430489789f1d42d6f8b17f09470a409f14 (patch)
tree14f4f3d92f62412efbce32c15f24e5fbbcc784ae /nuttx
parentedec60f187e9f0297f3acaa6fb4574b3606e74f5 (diff)
downloadnuttx-50cadb430489789f1d42d6f8b17f09470a409f14.tar.gz
nuttx-50cadb430489789f1d42d6f8b17f09470a409f14.tar.bz2
nuttx-50cadb430489789f1d42d6f8b17f09470a409f14.zip
Correct round-to-ticks logic in sigtimedwait()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5457 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/ChangeLog3
-rw-r--r--nuttx/sched/sig_timedwait.c22
2 files changed, 22 insertions, 3 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 56edf9487..6c6fd7843 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -3812,4 +3812,7 @@
* include/pthread.h: In sys/prctl.h because it is needed by
pthread_[set|get]name_np()
* tools/kconfig.bat: Kludge to run kconfig-frontends from a DOS shell.
+ * sched/sig_timedwait.c: Should always move the time up to the next
+ largest number of system ticks. The logic was rounding. Noted by
+ Petteri Aimonen.
diff --git a/nuttx/sched/sig_timedwait.c b/nuttx/sched/sig_timedwait.c
index 1b8dfd162..d03611610 100644
--- a/nuttx/sched/sig_timedwait.c
+++ b/nuttx/sched/sig_timedwait.c
@@ -238,10 +238,25 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info,
if (timeout)
{
- /* Convert the timespec to milliseconds */
+ /* Convert the timespec to system clock ticks, making sure that
+ * the resultint delay is greater than or equal to the requested
+ * time in nanoseconds.
+ */
- waitticks = MSEC2TICK(timeout->tv_sec * MSEC_PER_SEC
- + timeout->tv_nsec / NSEC_PER_MSEC);
+#ifdef CONFIG_HAVE_LONG_LONG
+ uint64_t waitticks64 = (timeout->tv_sec * NSEC_PER_SEC +
+ timeout->tv_nsec + NSEC_PER_TICK - 1) /
+ NSEC_PER_TICK;
+ DEBUGASSERT(waitticks64 <= UINT32_MAX);
+ waitticks = (uint32_t)waitticks64;
+#else
+ uint32_t waitmsec;
+
+ DEBUGASSERT(timeout->tv_sec < UINT32_MAX / MSEC_PER_SEC);
+ waitmsec = timeout->tv_sec * MSEC_PER_SEC +
+ (timeout->tv_nsec + NSEC_PER_MSEC - 1) / NSEC_PER_MSEC;
+ waitticks = (waitmsec + MSEC_PER_TICK - 1) / MSEC_PER_TICK;
+#endif
/* Create a watchdog */
@@ -326,6 +341,7 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info,
{
memcpy(info, &rtcb->sigunbinfo, sizeof(struct siginfo));
}
+
irqrestore(saved_state);
}