From 3adcae8ffbf247f1038bbb3b8281ea811799031e Mon Sep 17 00:00:00 2001
From: Gregory Nutt
Date: Mon, 18 May 2015 08:53:42 -0600
Subject: [PATCH] Update the type passed to watchdog timer handlers. Using
uint32_t is a problem for 64-bit machines.
---
Documentation/NuttxUserGuide.html | 34 +++++++++++++++----------------
include/nuttx/wdog.h | 24 +++++++++++++---------
sched/mqueue/mq_timedreceive.c | 4 ++--
sched/mqueue/mq_timedsend.c | 2 +-
sched/semaphore/sem_timedwait.c | 4 ++--
sched/signal/sig_timedwait.c | 10 ++++-----
sched/timer/timer_settime.c | 25 ++++++++++-------------
sched/wdog/wd_start.c | 14 ++++++-------
8 files changed, 59 insertions(+), 58 deletions(-)
diff --git a/Documentation/NuttxUserGuide.html b/Documentation/NuttxUserGuide.html
index 8eecc9052b2..26079b5752e 100644
--- a/Documentation/NuttxUserGuide.html
+++ b/Documentation/NuttxUserGuide.html
@@ -9743,25 +9743,25 @@ notify a task when a message is available on a queue.
Where argc is the number of uint32_t type arguments that follow.
- The arguments are passed as uint32_t values.
- For systems where the sizeof(pointer) < sizeof(uint32_t), the
- following union defines the alignment of the pointer within the
- uint32_t. For example, the SDCC MCS51 general pointer is
- 24-bits, but uint32_t is 32-bits (of course).
-
-
- union wdparm_u
- {
- void *pvarg;
- uint32_t *dwarg;
- };
- typedef union wdparm_u wdparm_t;
-
- For most 32-bit systems, pointers and uint32_t are the same size
- For systems where sizeof(pointer) > sizeof(uint32_t), we will
- have to do some redesign.
+ The arguments are passed as wdparm_t values. For systems where the sizeof(pointer) < sizeof(uint32_t), the following union defines the alignment of the pointer within the uint32_t. For example, the SDCC MCS51 general pointer is 24-bits, but uint32_t is 32-bits (of course).
+ We always have sizeof(pointer) <= sizeof(uintptr_t) by definitions.
+
+
+union wdparm_u
+{
+ FAR void *pvarg; /* The size one generic point */
+ uint32_t dwarg; /* Big enough for a 32-bit value in any case */
+ uintptr_t uiarg; /* sizeof(uintptr_t) >= sizeof(pointer) */
+};
+
+#if UINTPTR_MAX >= UINT32_MAX
+typedef uintptr_t wdparm_t;
+#else
+typedef uint32_t wdpartm_t;
+#endif
+
diff --git a/include/nuttx/wdog.h b/include/nuttx/wdog.h
index c249b850588..44774cd8507 100644
--- a/include/nuttx/wdog.h
+++ b/include/nuttx/wdog.h
@@ -1,7 +1,7 @@
/****************************************************************************
* include/nuttx/wdog.h
*
- * Copyright (C) 2007-2009, 2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2014-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -101,28 +101,32 @@
/****************************************************************************
* Public Type Declarations
****************************************************************************/
-/* The arguments are passed as uint32_t values. For systems where the
- * sizeof(pointer) < sizeof(uint32_t), the following union defines the
+/* The arguments are passed as scalar wdparm_t values. For systems where
+ * the sizeof(pointer) < sizeof(uint32_t), the following union defines the
* alignment of the pointer within the uint32_t. For example, the SDCC
* MCS51 general pointer is 24-bits, but uint32_t is 32-bits (of course).
*
- * For systems where sizeof(pointer) > sizeof(uint32_t), we will have to do
- * some redesign.
+ * We always have sizeof(pointer) <= sizeof(uintptr_t) by definitions.
*/
union wdparm_u
{
- FAR void *pvarg;
- FAR uint32_t *dwarg;
+ FAR void *pvarg; /* The size one generic point */
+ uint32_t dwarg; /* Big enough for a 32-bit value in any case */
+ uintptr_t uiarg; /* sizeof(uintptr_t) >= sizeof(pointer) */
};
-typedef union wdparm_u wdparm_t;
+#if UINTPTR_MAX >= UINT32_MAX
+typedef uintptr_t wdparm_t;
+#else
+typedef uint32_t wdparm_t;
+#endif
/* This is the form of the function that is called when the
* watchdog function expires. Up to four parameters may be passed.
*/
-typedef CODE void (*wdentry_t)(int argc, uint32_t arg1, ...);
+typedef CODE void (*wdentry_t)(int argc, wdparm_t arg1, ...);
/* This is the internal representation of the watchdog timer structure. The
* WDOG_ID is a pointer to a watchdog structure.
@@ -138,7 +142,7 @@ struct wdog_s
int lag; /* Timer associated with the delay */
uint8_t flags; /* See WDOGF_* definitions above */
uint8_t argc; /* The number of parameters to pass */
- uint32_t parm[CONFIG_MAX_WDOGPARMS];
+ wdparm_t parm[CONFIG_MAX_WDOGPARMS];
};
/* Watchdog 'handle' */
diff --git a/sched/mqueue/mq_timedreceive.c b/sched/mqueue/mq_timedreceive.c
index 858d9a3bf47..1d1c71aded5 100644
--- a/sched/mqueue/mq_timedreceive.c
+++ b/sched/mqueue/mq_timedreceive.c
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/mqueue/mq_timedreceive.c
*
- * Copyright (C) 2007-2009, 2011, 2013-2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2011, 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -92,7 +92,7 @@
*
****************************************************************************/
-static void mq_rcvtimeout(int argc, uint32_t pid)
+static void mq_rcvtimeout(int argc, wdparm_t pid)
{
FAR struct tcb_s *wtcb;
irqstate_t saved_state;
diff --git a/sched/mqueue/mq_timedsend.c b/sched/mqueue/mq_timedsend.c
index 134f04484e4..31855e6401f 100644
--- a/sched/mqueue/mq_timedsend.c
+++ b/sched/mqueue/mq_timedsend.c
@@ -92,7 +92,7 @@
*
****************************************************************************/
-static void mq_sndtimeout(int argc, uint32_t pid)
+static void mq_sndtimeout(int argc, wdparm_t pid)
{
FAR struct tcb_s *wtcb;
irqstate_t saved_state;
diff --git a/sched/semaphore/sem_timedwait.c b/sched/semaphore/sem_timedwait.c
index 4d5e583422b..a73e278051b 100644
--- a/sched/semaphore/sem_timedwait.c
+++ b/sched/semaphore/sem_timedwait.c
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/semaphore/sem_timedwait.c
*
- * Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -91,7 +91,7 @@
*
****************************************************************************/
-static void sem_timeout(int argc, uint32_t pid)
+static void sem_timeout(int argc, wdparm_t pid)
{
FAR struct tcb_s *wtcb;
irqstate_t flags;
diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_timedwait.c
index 66d4ccd05e9..a0abc47d933 100644
--- a/sched/signal/sig_timedwait.c
+++ b/sched/signal/sig_timedwait.c
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/signal/sig_timedwait.c
*
- * Copyright (C) 2007-2009, 2012-2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2012-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -90,7 +90,7 @@
*
****************************************************************************/
-static void sig_timeout(int argc, uint32_t itcb)
+static void sig_timeout(int argc, wdparm_t itcb)
{
/* On many small machines, pointers are encoded and cannot be simply cast
* from uint32_t to struct tcb_s*. The following union works around this
@@ -101,7 +101,7 @@ static void sig_timeout(int argc, uint32_t itcb)
union
{
FAR struct tcb_s *wtcb;
- uint32_t itcb;
+ wdparm_t itcb;
} u;
u.itcb = itcb;
@@ -269,13 +269,13 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info,
* see wdog.h.
*/
- wdparm_t wdparm;
+ union wdparm_u wdparm;
wdparm.pvarg = (FAR void *)rtcb;
/* Start the watchdog */
wd_start(rtcb->waitdog, waitticks, (wdentry_t)sig_timeout, 1,
- wdparm.dwarg);
+ wdparm.pvarg);
/* Now wait for either the signal or the watchdog */
diff --git a/sched/timer/timer_settime.c b/sched/timer/timer_settime.c
index 308240b88cb..432b6d20680 100644
--- a/sched/timer/timer_settime.c
+++ b/sched/timer/timer_settime.c
@@ -1,7 +1,7 @@
/********************************************************************************
* sched/timer/timer_settime.c
*
- * Copyright (C) 2007-2010, 2013-2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2010, 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -67,8 +67,8 @@
********************************************************************************/
static inline void timer_sigqueue(FAR struct posix_timer_s *timer);
-static inline void timer_restart(FAR struct posix_timer_s *timer, uint32_t itimer);
-static void timer_timeout(int argc, uint32_t itimer);
+static inline void timer_restart(FAR struct posix_timer_s *timer, wdparm_t itimer);
+static void timer_timeout(int argc, wdparm_t itimer);
/********************************************************************************
* Private Functions
@@ -128,11 +128,12 @@ static inline void timer_sigqueue(FAR struct posix_timer_s *timer)
* None
*
* Assumptions:
- * This function executes in the context of the watchod timer interrupt.
+ * This function executes in the context of the watchdog timer interrupt.
*
********************************************************************************/
-static inline void timer_restart(FAR struct posix_timer_s *timer, uint32_t itimer)
+static inline void timer_restart(FAR struct posix_timer_s *timer,
+ wdparm_t itimer)
{
/* If this is a repetitive timer, then restart the watchdog */
@@ -164,17 +165,17 @@ static inline void timer_restart(FAR struct posix_timer_s *timer, uint32_t itime
*
********************************************************************************/
-static void timer_timeout(int argc, uint32_t itimer)
+static void timer_timeout(int argc, wdparm_t itimer)
{
#ifndef CONFIG_CAN_PASS_STRUCTS
/* On many small machines, pointers are encoded and cannot be simply cast from
- * uint32_t to struct tcb_s*. The following union works around this (see wdogparm_t).
+ * wdparm_t to struct tcb_s*. The following union works around this (see wdogparm_t).
*/
union
{
FAR struct posix_timer_s *timer;
- uint32_t itimer;
+ wdparm_t itimer;
} u;
u.itimer = itimer;
@@ -198,11 +199,7 @@ static void timer_timeout(int argc, uint32_t itimer)
timer_restart(u.timer, itimer);
}
#else
- /* (casting to uintptr_t first eliminates complaints on some architectures
- * where the sizeof uint32_t is different from the size of a pointer).
- */
-
- FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)((uintptr_t)itimer);
+ FAR struct posix_timer_s *timer = (FAR struct posix_timer_s *)itimer;
/* Send the specified signal to the specified task. Increment the reference
* count on the timer first so that will not be deleted until after the
@@ -375,7 +372,7 @@ int timer_settime(timer_t timerid, int flags, FAR const struct itimerspec *value
{
timer->pt_last = delay;
ret = wd_start(timer->pt_wdog, delay, (wdentry_t)timer_timeout,
- 1, (uint32_t)((uintptr_t)timer));
+ 1, (uint32_t)((wdparm_t)timer));
}
irqrestore(state);
diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c
index 6faf0e6dfcc..ba7cc06aa28 100644
--- a/sched/wdog/wd_start.c
+++ b/sched/wdog/wd_start.c
@@ -71,18 +71,18 @@
typedef void (*wdentry0_t)(int argc);
#if CONFIG_MAX_WDOGPARMS > 0
-typedef void (*wdentry1_t)(int argc, uint32_t arg1);
+typedef void (*wdentry1_t)(int argc, wdparm_t arg1);
#endif
#if CONFIG_MAX_WDOGPARMS > 1
-typedef void (*wdentry2_t)(int argc, uint32_t arg1, uint32_t arg2);
+typedef void (*wdentry2_t)(int argc, wdparm_t arg1, wdparm_t arg2);
#endif
#if CONFIG_MAX_WDOGPARMS > 2
-typedef void (*wdentry3_t)(int argc, uint32_t arg1, uint32_t arg2,
- uint32_t arg3);
+typedef void (*wdentry3_t)(int argc, wdparm_t arg1, wdparm_t arg2,
+ wdparm_t arg3);
#endif
#if CONFIG_MAX_WDOGPARMS > 3
-typedef void (*wdentry4_t)(int argc, uint32_t arg1, uint32_t arg2,
- uint32_t arg3, uint32_t arg4);
+typedef void (*wdentry4_t)(int argc, wdparm_t arg1, wdparm_t arg2,
+ wdparm_t arg3, wdparm_t arg4);
#endif
/****************************************************************************
@@ -264,7 +264,7 @@ int wd_start(WDOG_ID wdog, int delay, wdentry_t wdentry, int argc, ...)
va_start(ap, argc);
for (i = 0; i < argc; i++)
{
- wdog->parm[i] = va_arg(ap, uint32_t);
+ wdog->parm[i] = va_arg(ap, wdparm_t);
}
#ifdef CONFIG_DEBUG
for (; i < CONFIG_MAX_WDOGPARMS; i++)