Date: Sat, 12 Jan 2013 19:58:45 +0000
Subject: Fix a *critical* bug in the task exit logic. Implements SIGCHILD
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5513 42af7a65-404d-4744-a932-0658087f49c3
---
apps/ChangeLog.txt | 2 +
apps/examples/ostest/sighand.c | 58 ++++++++++++++++++
nuttx/ChangeLog | 11 ++++
nuttx/Documentation/NuttxPortingGuide.html | 50 ++++++++++++++--
nuttx/configs/README.txt | 24 +++++++-
nuttx/configs/amber/hello/defconfig | 2 +-
nuttx/configs/avr32dev1/nsh/defconfig | 2 +-
nuttx/configs/avr32dev1/ostest/defconfig | 2 +-
nuttx/configs/cloudctrl/nsh/defconfig | 2 +-
nuttx/configs/demo9s12ne64/ostest/defconfig | 2 +-
nuttx/configs/ea3131/nsh/defconfig | 2 +-
nuttx/configs/ea3131/ostest/defconfig | 2 +-
nuttx/configs/ea3131/pgnsh/defconfig | 2 +-
nuttx/configs/ea3131/usbserial/defconfig | 2 +-
nuttx/configs/ea3131/usbstorage/defconfig | 2 +-
nuttx/configs/ea3152/ostest/defconfig | 2 +-
nuttx/configs/fire-stm32v2/nsh/defconfig | 2 +-
nuttx/configs/hymini-stm32v/buttons/defconfig | 2 +-
nuttx/configs/hymini-stm32v/nsh/defconfig | 2 +-
nuttx/configs/hymini-stm32v/nsh2/defconfig | 2 +-
nuttx/configs/hymini-stm32v/nx/defconfig | 2 +-
nuttx/configs/hymini-stm32v/nxlines/defconfig | 2 +-
nuttx/configs/hymini-stm32v/usbserial/defconfig | 2 +-
nuttx/configs/hymini-stm32v/usbstorage/defconfig | 2 +-
nuttx/configs/kwikstik-k40/ostest/defconfig | 2 +-
nuttx/configs/lincoln60/nsh/defconfig | 2 +-
nuttx/configs/lincoln60/ostest/defconfig | 2 +-
nuttx/configs/lpc4330-xplorer/nsh/defconfig | 2 +-
nuttx/configs/lpc4330-xplorer/ostest/defconfig | 2 +-
nuttx/configs/lpcxpresso-lpc1768/dhcpd/defconfig | 2 +-
nuttx/configs/lpcxpresso-lpc1768/nsh/defconfig | 2 +-
nuttx/configs/lpcxpresso-lpc1768/nx/defconfig | 2 +-
nuttx/configs/lpcxpresso-lpc1768/ostest/defconfig | 2 +-
nuttx/configs/lpcxpresso-lpc1768/thttpd/defconfig | 2 +-
.../lpcxpresso-lpc1768/usbstorage/defconfig | 2 +-
nuttx/configs/mbed/hidkbd/defconfig | 2 +-
nuttx/configs/mbed/nsh/defconfig | 2 +-
nuttx/configs/micropendous3/hello/defconfig | 2 +-
nuttx/configs/mirtoo/nsh/defconfig | 2 +-
nuttx/configs/mirtoo/nxffs/defconfig | 2 +-
nuttx/configs/mirtoo/ostest/defconfig | 2 +-
nuttx/configs/ne64badge/ostest/defconfig | 2 +-
nuttx/configs/nucleus2g/nsh/defconfig | 2 +-
nuttx/configs/nucleus2g/ostest/defconfig | 2 +-
nuttx/configs/nucleus2g/usbserial/defconfig | 2 +-
nuttx/configs/nucleus2g/usbstorage/defconfig | 2 +-
nuttx/configs/olimex-lpc1766stk/ftpc/defconfig | 2 +-
nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig | 2 +-
nuttx/configs/olimex-lpc1766stk/nettest/defconfig | 2 +-
nuttx/configs/olimex-lpc1766stk/nsh/defconfig | 2 +-
nuttx/configs/olimex-lpc1766stk/nx/defconfig | 2 +-
nuttx/configs/olimex-lpc1766stk/ostest/defconfig | 2 +-
.../configs/olimex-lpc1766stk/slip-httpd/defconfig | 2 +-
nuttx/configs/olimex-lpc1766stk/thttpd/defconfig | 2 +-
.../configs/olimex-lpc1766stk/usbserial/defconfig | 2 +-
.../configs/olimex-lpc1766stk/usbstorage/defconfig | 2 +-
nuttx/configs/olimex-stm32-p107/nsh/defconfig | 2 +-
nuttx/configs/olimex-stm32-p107/ostest/defconfig | 2 +-
nuttx/configs/olimex-strp711/nettest/defconfig | 2 +-
nuttx/configs/pcblogic-pic32mx/nsh/defconfig | 2 +-
nuttx/configs/pcblogic-pic32mx/ostest/defconfig | 2 +-
nuttx/configs/pic32-starterkit/nsh/defconfig | 2 +-
nuttx/configs/pic32-starterkit/nsh2/defconfig | 2 +-
nuttx/configs/pic32-starterkit/ostest/defconfig | 2 +-
nuttx/configs/pic32mx7mmb/nsh/defconfig | 2 +-
nuttx/configs/pic32mx7mmb/ostest/defconfig | 2 +-
nuttx/configs/sam3u-ek/knsh/defconfig | 2 +-
nuttx/configs/sam3u-ek/nsh/defconfig | 2 +-
nuttx/configs/sam3u-ek/nx/defconfig | 2 +-
nuttx/configs/sam3u-ek/ostest/defconfig | 2 +-
nuttx/configs/sam3u-ek/touchscreen/defconfig | 2 +-
nuttx/configs/shenzhou/nsh/defconfig | 2 +-
nuttx/configs/shenzhou/nxwm/defconfig | 2 +-
nuttx/configs/shenzhou/thttpd/defconfig | 2 +-
nuttx/configs/sim/nsh/defconfig | 2 +-
nuttx/configs/sim/nsh2/defconfig | 2 +-
nuttx/configs/sim/ostest/defconfig | 13 +++-
nuttx/configs/stm3210e-eval/RIDE/defconfig | 2 +-
nuttx/configs/stm3210e-eval/buttons/defconfig | 2 +-
nuttx/configs/stm3210e-eval/composite/defconfig | 2 +-
nuttx/configs/stm3210e-eval/nsh/defconfig | 2 +-
nuttx/configs/stm3210e-eval/nsh2/defconfig | 2 +-
nuttx/configs/stm3210e-eval/nx/defconfig | 2 +-
nuttx/configs/stm3210e-eval/nxconsole/defconfig | 2 +-
nuttx/configs/stm3210e-eval/nxlines/defconfig | 2 +-
nuttx/configs/stm3210e-eval/nxtext/defconfig | 2 +-
nuttx/configs/stm3210e-eval/ostest/defconfig | 2 +-
nuttx/configs/stm3210e-eval/pm/defconfig | 2 +-
nuttx/configs/stm3210e-eval/usbserial/defconfig | 2 +-
nuttx/configs/stm3210e-eval/usbstorage/defconfig | 2 +-
nuttx/configs/stm3220g-eval/dhcpd/defconfig | 2 +-
nuttx/configs/stm3220g-eval/nettest/defconfig | 2 +-
nuttx/configs/stm3220g-eval/nsh/defconfig | 2 +-
nuttx/configs/stm3220g-eval/nsh2/defconfig | 2 +-
nuttx/configs/stm3220g-eval/nxwm/defconfig | 2 +-
nuttx/configs/stm3220g-eval/ostest/defconfig | 2 +-
nuttx/configs/stm3220g-eval/telnetd/defconfig | 2 +-
nuttx/configs/stm3240g-eval/dhcpd/defconfig | 2 +-
nuttx/configs/stm3240g-eval/nettest/defconfig | 2 +-
nuttx/configs/stm3240g-eval/nsh/defconfig | 2 +-
nuttx/configs/stm3240g-eval/nsh2/defconfig | 2 +-
nuttx/configs/stm3240g-eval/nxconsole/defconfig | 2 +-
nuttx/configs/stm3240g-eval/nxwm/defconfig | 2 +-
nuttx/configs/stm3240g-eval/ostest/defconfig | 2 +-
nuttx/configs/stm3240g-eval/telnetd/defconfig | 2 +-
nuttx/configs/stm3240g-eval/webserver/defconfig | 2 +-
nuttx/configs/stm32f100rc_generic/nsh/defconfig | 2 +-
nuttx/configs/stm32f4discovery/README.txt | 26 ++++++++
nuttx/configs/stm32f4discovery/nsh/defconfig | 2 +-
nuttx/configs/stm32f4discovery/pm/defconfig | 2 +-
.../configs/stm32f4discovery/posix_spawn/defconfig | 2 +-
nuttx/configs/sure-pic32mx/nsh/defconfig | 2 +-
nuttx/configs/sure-pic32mx/ostest/defconfig | 2 +-
nuttx/configs/sure-pic32mx/usbnsh/defconfig | 2 +-
nuttx/configs/teensy/hello/defconfig | 2 +-
nuttx/configs/teensy/nsh/defconfig | 2 +-
nuttx/configs/teensy/usbstorage/defconfig | 2 +-
nuttx/configs/twr-k60n512/nsh/defconfig | 2 +-
nuttx/configs/twr-k60n512/ostest/defconfig | 2 +-
nuttx/configs/ubw32/nsh/defconfig | 2 +-
nuttx/configs/ubw32/ostest/defconfig | 2 +-
nuttx/configs/vsn/nsh/defconfig | 2 +-
nuttx/include/nuttx/sched.h | 3 +
nuttx/include/nuttx/wqueue.h | 2 +-
nuttx/include/signal.h | 68 +++++++++++++--------
nuttx/libc/Kconfig | 5 +-
nuttx/sched/Kconfig | 69 +++++++++++++++++++---
nuttx/sched/sched_unlock.c | 1 +
nuttx/sched/sig_kill.c | 7 +++
nuttx/sched/sig_mqnotempty.c | 7 +++
nuttx/sched/sig_queue.c | 13 +++-
nuttx/sched/sig_timedwait.c | 4 ++
nuttx/sched/task_deletecurrent.c | 16 ++++-
nuttx/sched/task_exithook.c | 55 +++++++++++++++++
nuttx/sched/task_setup.c | 36 ++++++++++-
nuttx/sched/timer_settime.c | 4 ++
136 files changed, 540 insertions(+), 164 deletions(-)
(limited to 'nuttx/sched')
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index 6b63527a7..65d4d6134 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -462,4 +462,6 @@
* apps/examples/wlan: Remove non-functional example.
* apps/examples/ostest/vfork.c: Added a test of vfork().
* apps/exampes/posix_spawn: Added a test of poxis_spawn().
+ * apps/examples/ostest: Extend signal handler test to catch
+ death-of-child signals (SIGCHLD).
diff --git a/apps/examples/ostest/sighand.c b/apps/examples/ostest/sighand.c
index eabfe5646..63d9590d9 100644
--- a/apps/examples/ostest/sighand.c
+++ b/apps/examples/ostest/sighand.c
@@ -54,12 +54,32 @@ static sem_t sem;
static bool sigreceived = false;
static bool threadexited = false;
+#ifdef CONFIG_SCHED_HAVE_PARENT
+static void death_of_child(int signo, siginfo_t *info, void *ucontext)
+{
+ /* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
+
+ if (info)
+ {
+ printf("death_of_child: PID %d received signal=%d code=%d pid=%d status=%d\n",
+ getpid(), signo, info->si_code, info->si_pid, info->si_status);
+ }
+ else
+ {
+ printf("death_of_child: PID %d received signal=%d (no info?)\n",
+ getpid(), signo);
+ }
+}
+#endif
+
static void wakeup_action(int signo, siginfo_t *info, void *ucontext)
{
sigset_t oldset;
sigset_t allsigs;
int status;
+ /* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
+
printf("wakeup_action: Received signal %d\n" , signo);
sigreceived = true;
@@ -186,6 +206,11 @@ static int waiter_main(int argc, char *argv[])
void sighand_test(void)
{
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ struct sigaction act;
+ struct sigaction oact;
+ sigset_t sigset;
+#endif
struct sched_param param;
union sigval sigvalue;
pid_t waiterpid;
@@ -195,6 +220,32 @@ void sighand_test(void)
printf("sighand_test: Initializing semaphore to 0\n" );
sem_init(&sem, 0, 0);
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ printf("sighand_test: Unmasking SIGCHLD\n");
+
+ (void)sigemptyset(&sigset);
+ (void)sigaddset(&sigset, SIGCHLD);
+ status = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+ if (status != OK)
+ {
+ printf("sighand_test: ERROR sigprocmask failed, status=%d\n",
+ status);
+ }
+
+ printf("sighand_test: Registering SIGCHLD handler\n" );
+ act.sa_sigaction = death_of_child;
+ act.sa_flags = SA_SIGINFO;
+
+ (void)sigfillset(&act.sa_mask);
+ (void)sigdelset(&act.sa_mask, SIGCHLD);
+
+ status = sigaction(SIGCHLD, &act, &oact);
+ if (status != OK)
+ {
+ printf("waiter_main: ERROR sigaction failed, status=%d\n" , status);
+ }
+#endif
+
/* Start waiter thread */
printf("sighand_test: Starting waiter task\n" );
@@ -262,6 +313,13 @@ void sighand_test(void)
printf("sighand_test: ERROR signal handler did not run\n" );
}
+ /* Detach the signal handler */
+
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ act.sa_sigaction = SIG_DFL;
+ status = sigaction(SIGCHLD, &act, &oact);
+#endif
+
printf("sighand_test: done\n" );
FFLUSH();
}
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 40a24d8f1..921b7014b 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -3911,3 +3911,14 @@
lib_fread() was passed a bad stream. Needed to move the
releasing of a semaphore inside of some conditional logic
(cosmetic).
+ * include/nuttx/sched.h, sched/task_setup.c, and sched/task_exithook.c:
+ Add support for remembering the parent task and sending
+ SIGCHLD to the parent when the task exists.
+ * sched/task_exithook.c: Fixed a *critical* bug. Here is
+ the scenario: (1) sched_lock() is called increments the lockcount
+ on the current TCB (i.e., the one at the head of the ready to run
+ list), (2) sched_mergepending is called which may change the task
+ at the head of the readytorun list, then (2) sched_lock() is called
+ which decrements the lockcount on the wrong TCB. The failure case
+ that I saw was that pre-emption got disabled in the IDLE thread,
+ locking up the whole system.
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index b1664f3f0..0b67eddb7 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -12,7 +12,7 @@
NuttX RTOS Porting Guide
- Last Updated: January 4, 2013
+ Last Updated: January 12, 2013
@@ -4480,6 +4480,11 @@ build
task name to save in the TCB. Useful if scheduler
instrumentation is selected. Set to zero to disable.
+
+ CONFIG_SCHED_HAVE_PARENT
: Remember the ID of the parent thread when a new child thread is created.
+ This support enables a few minor features (such as SIGCHLD
) and slightly increases the size of the Task Control Block (TCB) of every task to hold the ID of the parent thread.
+ Default: disabled.
+
CONFIG_SYSTEM_TIME16
:
The range of system time is, by default, 32-bits.
@@ -4582,7 +4587,7 @@ build
CONFIG_SIG_SIGWORK
: The signal number that will be used to wake-up
- the worker thread. Default: 4
+ the worker thread. Default: 17
CONFIG_SCHED_LPWORK
: If CONFIG_SCHED_WORKQUEUE is defined, then a single work queue is created by default.
@@ -4624,9 +4629,41 @@ build
user_start
.
+
+ Signal Numbers:
+
+
+ -
+
CONFIG_SIG_SIGUSR1
:
+ Value of standard user signal 1 (SIGUSR1
). Default: 1
+
+ -
+
CONFIG_SIG_SIGUSR2
:
+ Value of standard user signal 2 (SIGUSR2
). Default: 2
+
+ -
+
CONFIG_SIG_SIGALARM
:
+ Default the standard signal used with POSIX timers (SIGALRM
). Default: 3
+
+ -
+
CONFIG_SIG_SIGCHLD
:
+ The SIGCHLD
signal is sent to the parent of a child process when it exits, is interrupted (stopped), or resumes after being interrupted.
+ Default: 4
+
+ -
+
CONFIG_SIG_SIGCONDTIMEDOUT
:
+ This non-standard signal number is used in the implementation of pthread_cond_timedwait()
.
+ Default 16.
+
+ -
+
CONFIG_SIG_SIGWORK
:
+ SIGWORK
is a non-standard signal used to wake up the internal NuttX worker thread.
+ Default: 17.
+
+
- Binary Loaders:
+ Binary Loaders:
-
@@ -4680,7 +4717,7 @@ build
- System Logging:
+ System Logging:
-
@@ -4737,7 +4774,7 @@ build
- Kernel build options:
+ Kernel build options:
-
@@ -4748,7 +4785,7 @@ build
- OS setup related to on-demand paging:
+ OS setup related to on-demand paging:
-
@@ -4906,6 +4943,7 @@ build
+ Disabling OS Features.
The following can be used to disable categories of APIs supported
by the OS. If the compiler supports weak functions, then it
should not be necessary to disable functions unless you want to
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index 6e7526ed0..2724cf5a3 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -334,6 +334,11 @@ defconfig -- This is a configuration file similar to the Linux
CONFIG_TASK_NAME_SIZE - Specifies that maximum size of a
task name to save in the TCB. Useful if scheduler
instrumentation is selected. Set to zero to disable.
+ CONFIG_SCHED_HAVE_PARENT - Remember the ID of the parent thread
+ when a new child thread is created. This support enables a
+ few minor features (such as SIGCHLD) and slightly increases
+ the size of the Task Control Block (TCB) of every task to hold
+ the ID of the parent thread. Default: disabled.
CONFIG_START_YEAR, CONFIG_START_MONTH, CONFIG_START_DAY -
Used to initialize the internal time logic.
CONFIG_GREGORIAN_TIME - Enables Gregorian time conversions.
@@ -400,7 +405,7 @@ defconfig -- This is a configuration file similar to the Linux
CONFIG_SCHED_WORKSTACKSIZE - The stack size allocated for the worker
thread. Default: CONFIG_IDLETHREAD_STACKSIZE.
CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up
- the worker thread. Default: 4
+ the worker thread. Default: 17
CONFIG_SCHED_LPWORK. If CONFIG_SCHED_WORKQUEUE is defined, then a single
work queue is created by default. If CONFIG_SCHED_LPWORK is also defined
then an additional, lower-priority work queue will also be created. This
@@ -426,6 +431,23 @@ defconfig -- This is a configuration file similar to the Linux
where 'app' is the application name. If not defined, CONFIG_USER_ENTRYPOINT
defaults to user_start.
+ Signal Numbers:
+
+ CONFIG_SIG_SIGUSR1 - Value of standard user signal 1 (SIGUSR1).
+ Default: 1
+ CONFIG_SIG_SIGUSR2 - Value of standard user signal 2 (SIGUSR2).
+ Default: 2
+ CONFIG_SIG_SIGALARM - Default the standard signal used with POSIX
+ timers (SIGALRM). Default: 3
+ CONFIG_SIG_SIGCHLD - The SIGCHLD signal is sent to the parent of a child
+ process when it exits, is interrupted (stopped), or resumes after being
+ interrupted. Default: 4
+
+ CONFIG_SIG_SIGCONDTIMEDOUT - This non-standard signal number is used in
+ the implementation of pthread_cond_timedwait(). Default 16.
+ CONFIG_SIG_SIGWORK - SIGWORK is a non-standard signal used to wake up
+ the internal NuttX worker thread. Default: 17.
+
Binary Loaders:
CONFIG_BINFMT_DISABLE - By default, support for loadable binary formats
is built.
diff --git a/nuttx/configs/amber/hello/defconfig b/nuttx/configs/amber/hello/defconfig
index 5d028e321..7e3d4ad70 100644
--- a/nuttx/configs/amber/hello/defconfig
+++ b/nuttx/configs/amber/hello/defconfig
@@ -142,7 +142,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/avr32dev1/nsh/defconfig b/nuttx/configs/avr32dev1/nsh/defconfig
index 2b66316c3..acca1fbac 100755
--- a/nuttx/configs/avr32dev1/nsh/defconfig
+++ b/nuttx/configs/avr32dev1/nsh/defconfig
@@ -168,7 +168,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/avr32dev1/ostest/defconfig b/nuttx/configs/avr32dev1/ostest/defconfig
index 9b67be09e..084c66233 100755
--- a/nuttx/configs/avr32dev1/ostest/defconfig
+++ b/nuttx/configs/avr32dev1/ostest/defconfig
@@ -168,7 +168,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/cloudctrl/nsh/defconfig b/nuttx/configs/cloudctrl/nsh/defconfig
index 99c7eb790..8f145d3ab 100644
--- a/nuttx/configs/cloudctrl/nsh/defconfig
+++ b/nuttx/configs/cloudctrl/nsh/defconfig
@@ -273,7 +273,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
# CONFIG_SCHED_LPWORK is not set
CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_ATEXIT is not set
diff --git a/nuttx/configs/demo9s12ne64/ostest/defconfig b/nuttx/configs/demo9s12ne64/ostest/defconfig
index 9c9668aac..79224989f 100755
--- a/nuttx/configs/demo9s12ne64/ostest/defconfig
+++ b/nuttx/configs/demo9s12ne64/ostest/defconfig
@@ -142,7 +142,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=256
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/ea3131/nsh/defconfig b/nuttx/configs/ea3131/nsh/defconfig
index 735af431b..8c7b351af 100644
--- a/nuttx/configs/ea3131/nsh/defconfig
+++ b/nuttx/configs/ea3131/nsh/defconfig
@@ -141,7 +141,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/ea3131/ostest/defconfig b/nuttx/configs/ea3131/ostest/defconfig
index 2f73ad5c9..19838ceab 100644
--- a/nuttx/configs/ea3131/ostest/defconfig
+++ b/nuttx/configs/ea3131/ostest/defconfig
@@ -141,7 +141,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/ea3131/pgnsh/defconfig b/nuttx/configs/ea3131/pgnsh/defconfig
index 32f89c500..1cc2bec7e 100644
--- a/nuttx/configs/ea3131/pgnsh/defconfig
+++ b/nuttx/configs/ea3131/pgnsh/defconfig
@@ -156,7 +156,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# OS setup related to on-demand paging:
diff --git a/nuttx/configs/ea3131/usbserial/defconfig b/nuttx/configs/ea3131/usbserial/defconfig
index 3d33a1b67..a82f69877 100644
--- a/nuttx/configs/ea3131/usbserial/defconfig
+++ b/nuttx/configs/ea3131/usbserial/defconfig
@@ -143,7 +143,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/ea3131/usbstorage/defconfig b/nuttx/configs/ea3131/usbstorage/defconfig
index 8d9933f55..a957fb3ab 100644
--- a/nuttx/configs/ea3131/usbstorage/defconfig
+++ b/nuttx/configs/ea3131/usbstorage/defconfig
@@ -144,7 +144,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/ea3152/ostest/defconfig b/nuttx/configs/ea3152/ostest/defconfig
index d85fd5821..6d0bb63f0 100644
--- a/nuttx/configs/ea3152/ostest/defconfig
+++ b/nuttx/configs/ea3152/ostest/defconfig
@@ -142,7 +142,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/fire-stm32v2/nsh/defconfig b/nuttx/configs/fire-stm32v2/nsh/defconfig
index c42bb1569..266098496 100644
--- a/nuttx/configs/fire-stm32v2/nsh/defconfig
+++ b/nuttx/configs/fire-stm32v2/nsh/defconfig
@@ -266,7 +266,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
# CONFIG_SCHED_LPWORK is not set
CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_ATEXIT is not set
diff --git a/nuttx/configs/hymini-stm32v/buttons/defconfig b/nuttx/configs/hymini-stm32v/buttons/defconfig
index bbd6c2319..e90ded32a 100644
--- a/nuttx/configs/hymini-stm32v/buttons/defconfig
+++ b/nuttx/configs/hymini-stm32v/buttons/defconfig
@@ -194,7 +194,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/hymini-stm32v/nsh/defconfig b/nuttx/configs/hymini-stm32v/nsh/defconfig
index ca589278a..eeb3b09ff 100755
--- a/nuttx/configs/hymini-stm32v/nsh/defconfig
+++ b/nuttx/configs/hymini-stm32v/nsh/defconfig
@@ -192,7 +192,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/hymini-stm32v/nsh2/defconfig b/nuttx/configs/hymini-stm32v/nsh2/defconfig
index 5a8c0bea2..ecf4c3a3d 100644
--- a/nuttx/configs/hymini-stm32v/nsh2/defconfig
+++ b/nuttx/configs/hymini-stm32v/nsh2/defconfig
@@ -202,7 +202,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/hymini-stm32v/nx/defconfig b/nuttx/configs/hymini-stm32v/nx/defconfig
index 28b08582c..c6e049142 100644
--- a/nuttx/configs/hymini-stm32v/nx/defconfig
+++ b/nuttx/configs/hymini-stm32v/nx/defconfig
@@ -193,7 +193,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/hymini-stm32v/nxlines/defconfig b/nuttx/configs/hymini-stm32v/nxlines/defconfig
index 880efb7d8..fb968c483 100644
--- a/nuttx/configs/hymini-stm32v/nxlines/defconfig
+++ b/nuttx/configs/hymini-stm32v/nxlines/defconfig
@@ -197,7 +197,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/hymini-stm32v/usbserial/defconfig b/nuttx/configs/hymini-stm32v/usbserial/defconfig
index 732c1e8b6..0c7317a00 100755
--- a/nuttx/configs/hymini-stm32v/usbserial/defconfig
+++ b/nuttx/configs/hymini-stm32v/usbserial/defconfig
@@ -195,7 +195,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/hymini-stm32v/usbstorage/defconfig b/nuttx/configs/hymini-stm32v/usbstorage/defconfig
index 7e49de0e8..16f43a1ce 100755
--- a/nuttx/configs/hymini-stm32v/usbstorage/defconfig
+++ b/nuttx/configs/hymini-stm32v/usbstorage/defconfig
@@ -195,7 +195,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/kwikstik-k40/ostest/defconfig b/nuttx/configs/kwikstik-k40/ostest/defconfig
index 759cff20b..5f0291ced 100755
--- a/nuttx/configs/kwikstik-k40/ostest/defconfig
+++ b/nuttx/configs/kwikstik-k40/ostest/defconfig
@@ -204,7 +204,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/lincoln60/nsh/defconfig b/nuttx/configs/lincoln60/nsh/defconfig
index e5009f8d6..908b01e3a 100644
--- a/nuttx/configs/lincoln60/nsh/defconfig
+++ b/nuttx/configs/lincoln60/nsh/defconfig
@@ -181,7 +181,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/lincoln60/ostest/defconfig b/nuttx/configs/lincoln60/ostest/defconfig
index 986f9bf43..ea42f5763 100644
--- a/nuttx/configs/lincoln60/ostest/defconfig
+++ b/nuttx/configs/lincoln60/ostest/defconfig
@@ -187,7 +187,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/lpc4330-xplorer/nsh/defconfig b/nuttx/configs/lpc4330-xplorer/nsh/defconfig
index 0afcbae89..78b9e3f71 100644
--- a/nuttx/configs/lpc4330-xplorer/nsh/defconfig
+++ b/nuttx/configs/lpc4330-xplorer/nsh/defconfig
@@ -227,7 +227,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/lpc4330-xplorer/ostest/defconfig b/nuttx/configs/lpc4330-xplorer/ostest/defconfig
index 76d3f11e9..342fe04a0 100644
--- a/nuttx/configs/lpc4330-xplorer/ostest/defconfig
+++ b/nuttx/configs/lpc4330-xplorer/ostest/defconfig
@@ -224,7 +224,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/lpcxpresso-lpc1768/dhcpd/defconfig b/nuttx/configs/lpcxpresso-lpc1768/dhcpd/defconfig
index f56dfca1b..2e0d2eea6 100755
--- a/nuttx/configs/lpcxpresso-lpc1768/dhcpd/defconfig
+++ b/nuttx/configs/lpcxpresso-lpc1768/dhcpd/defconfig
@@ -186,7 +186,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/lpcxpresso-lpc1768/nsh/defconfig b/nuttx/configs/lpcxpresso-lpc1768/nsh/defconfig
index ef70b5508..23f375a47 100755
--- a/nuttx/configs/lpcxpresso-lpc1768/nsh/defconfig
+++ b/nuttx/configs/lpcxpresso-lpc1768/nsh/defconfig
@@ -189,7 +189,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/lpcxpresso-lpc1768/nx/defconfig b/nuttx/configs/lpcxpresso-lpc1768/nx/defconfig
index a0d3cd283..3f8474103 100755
--- a/nuttx/configs/lpcxpresso-lpc1768/nx/defconfig
+++ b/nuttx/configs/lpcxpresso-lpc1768/nx/defconfig
@@ -191,7 +191,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/lpcxpresso-lpc1768/ostest/defconfig b/nuttx/configs/lpcxpresso-lpc1768/ostest/defconfig
index 660bd6c8b..10b63eb2d 100755
--- a/nuttx/configs/lpcxpresso-lpc1768/ostest/defconfig
+++ b/nuttx/configs/lpcxpresso-lpc1768/ostest/defconfig
@@ -184,7 +184,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/lpcxpresso-lpc1768/thttpd/defconfig b/nuttx/configs/lpcxpresso-lpc1768/thttpd/defconfig
index 755869156..b6ea25948 100755
--- a/nuttx/configs/lpcxpresso-lpc1768/thttpd/defconfig
+++ b/nuttx/configs/lpcxpresso-lpc1768/thttpd/defconfig
@@ -186,7 +186,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/lpcxpresso-lpc1768/usbstorage/defconfig b/nuttx/configs/lpcxpresso-lpc1768/usbstorage/defconfig
index 004d92cb3..9e4bcb15d 100755
--- a/nuttx/configs/lpcxpresso-lpc1768/usbstorage/defconfig
+++ b/nuttx/configs/lpcxpresso-lpc1768/usbstorage/defconfig
@@ -187,7 +187,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/mbed/hidkbd/defconfig b/nuttx/configs/mbed/hidkbd/defconfig
index ba0af97ca..b4bf00872 100644
--- a/nuttx/configs/mbed/hidkbd/defconfig
+++ b/nuttx/configs/mbed/hidkbd/defconfig
@@ -186,7 +186,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/mbed/nsh/defconfig b/nuttx/configs/mbed/nsh/defconfig
index a1168dd19..2156af80e 100755
--- a/nuttx/configs/mbed/nsh/defconfig
+++ b/nuttx/configs/mbed/nsh/defconfig
@@ -181,7 +181,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/micropendous3/hello/defconfig b/nuttx/configs/micropendous3/hello/defconfig
index ea8faf8f5..ebc755abc 100644
--- a/nuttx/configs/micropendous3/hello/defconfig
+++ b/nuttx/configs/micropendous3/hello/defconfig
@@ -137,7 +137,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/mirtoo/nsh/defconfig b/nuttx/configs/mirtoo/nsh/defconfig
index f2e2b8991..94a6b8b17 100644
--- a/nuttx/configs/mirtoo/nsh/defconfig
+++ b/nuttx/configs/mirtoo/nsh/defconfig
@@ -200,7 +200,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/mirtoo/nxffs/defconfig b/nuttx/configs/mirtoo/nxffs/defconfig
index 29de6f1e7..d633e56d9 100644
--- a/nuttx/configs/mirtoo/nxffs/defconfig
+++ b/nuttx/configs/mirtoo/nxffs/defconfig
@@ -200,7 +200,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/mirtoo/ostest/defconfig b/nuttx/configs/mirtoo/ostest/defconfig
index dfe7a25c5..471dab444 100644
--- a/nuttx/configs/mirtoo/ostest/defconfig
+++ b/nuttx/configs/mirtoo/ostest/defconfig
@@ -190,7 +190,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/ne64badge/ostest/defconfig b/nuttx/configs/ne64badge/ostest/defconfig
index 78e10f87c..e6e0df700 100755
--- a/nuttx/configs/ne64badge/ostest/defconfig
+++ b/nuttx/configs/ne64badge/ostest/defconfig
@@ -148,7 +148,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=256
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/nucleus2g/nsh/defconfig b/nuttx/configs/nucleus2g/nsh/defconfig
index cc747e0c8..2c440bc7f 100755
--- a/nuttx/configs/nucleus2g/nsh/defconfig
+++ b/nuttx/configs/nucleus2g/nsh/defconfig
@@ -182,7 +182,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/nucleus2g/ostest/defconfig b/nuttx/configs/nucleus2g/ostest/defconfig
index 3d777de9c..c32b1e715 100755
--- a/nuttx/configs/nucleus2g/ostest/defconfig
+++ b/nuttx/configs/nucleus2g/ostest/defconfig
@@ -181,7 +181,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/nucleus2g/usbserial/defconfig b/nuttx/configs/nucleus2g/usbserial/defconfig
index e5762e8bc..abe9ac020 100755
--- a/nuttx/configs/nucleus2g/usbserial/defconfig
+++ b/nuttx/configs/nucleus2g/usbserial/defconfig
@@ -182,7 +182,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/nucleus2g/usbstorage/defconfig b/nuttx/configs/nucleus2g/usbstorage/defconfig
index 88c54bccc..adab8f4f0 100755
--- a/nuttx/configs/nucleus2g/usbstorage/defconfig
+++ b/nuttx/configs/nucleus2g/usbstorage/defconfig
@@ -183,7 +183,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/olimex-lpc1766stk/ftpc/defconfig b/nuttx/configs/olimex-lpc1766stk/ftpc/defconfig
index 36c5eefc4..8ff0d95aa 100755
--- a/nuttx/configs/olimex-lpc1766stk/ftpc/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/ftpc/defconfig
@@ -192,7 +192,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
#
diff --git a/nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig b/nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig
index 35a7bfc3d..634601187 100755
--- a/nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/hidkbd/defconfig
@@ -262,7 +262,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
# CONFIG_SCHED_LPWORK is not set
# CONFIG_SCHED_WAITPID is not set
# CONFIG_SCHED_ATEXIT is not set
diff --git a/nuttx/configs/olimex-lpc1766stk/nettest/defconfig b/nuttx/configs/olimex-lpc1766stk/nettest/defconfig
index f89d265b0..4ab823b8c 100755
--- a/nuttx/configs/olimex-lpc1766stk/nettest/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/nettest/defconfig
@@ -192,7 +192,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/olimex-lpc1766stk/nsh/defconfig b/nuttx/configs/olimex-lpc1766stk/nsh/defconfig
index 0d82b458b..096f08a8a 100755
--- a/nuttx/configs/olimex-lpc1766stk/nsh/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/nsh/defconfig
@@ -194,7 +194,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/olimex-lpc1766stk/nx/defconfig b/nuttx/configs/olimex-lpc1766stk/nx/defconfig
index 55c480fe3..28ad229d6 100755
--- a/nuttx/configs/olimex-lpc1766stk/nx/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/nx/defconfig
@@ -197,7 +197,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/olimex-lpc1766stk/ostest/defconfig b/nuttx/configs/olimex-lpc1766stk/ostest/defconfig
index 32e2cacc5..02732e74a 100755
--- a/nuttx/configs/olimex-lpc1766stk/ostest/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/ostest/defconfig
@@ -187,7 +187,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/olimex-lpc1766stk/slip-httpd/defconfig b/nuttx/configs/olimex-lpc1766stk/slip-httpd/defconfig
index ff2674c79..9becdee04 100755
--- a/nuttx/configs/olimex-lpc1766stk/slip-httpd/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/slip-httpd/defconfig
@@ -190,7 +190,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/olimex-lpc1766stk/thttpd/defconfig b/nuttx/configs/olimex-lpc1766stk/thttpd/defconfig
index 936dba359..fe42a861f 100755
--- a/nuttx/configs/olimex-lpc1766stk/thttpd/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/thttpd/defconfig
@@ -188,7 +188,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/olimex-lpc1766stk/usbserial/defconfig b/nuttx/configs/olimex-lpc1766stk/usbserial/defconfig
index 603a1562a..995cbad59 100755
--- a/nuttx/configs/olimex-lpc1766stk/usbserial/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/usbserial/defconfig
@@ -188,7 +188,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/olimex-lpc1766stk/usbstorage/defconfig b/nuttx/configs/olimex-lpc1766stk/usbstorage/defconfig
index 2c29d2ffd..e11c2c404 100755
--- a/nuttx/configs/olimex-lpc1766stk/usbstorage/defconfig
+++ b/nuttx/configs/olimex-lpc1766stk/usbstorage/defconfig
@@ -189,7 +189,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/olimex-stm32-p107/nsh/defconfig b/nuttx/configs/olimex-stm32-p107/nsh/defconfig
index 7aaae2514..0a831ce9f 100644
--- a/nuttx/configs/olimex-stm32-p107/nsh/defconfig
+++ b/nuttx/configs/olimex-stm32-p107/nsh/defconfig
@@ -234,7 +234,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/olimex-stm32-p107/ostest/defconfig b/nuttx/configs/olimex-stm32-p107/ostest/defconfig
index d4bba38fb..272832381 100644
--- a/nuttx/configs/olimex-stm32-p107/ostest/defconfig
+++ b/nuttx/configs/olimex-stm32-p107/ostest/defconfig
@@ -242,7 +242,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/olimex-strp711/nettest/defconfig b/nuttx/configs/olimex-strp711/nettest/defconfig
index 4d73540b8..a8767c7be 100755
--- a/nuttx/configs/olimex-strp711/nettest/defconfig
+++ b/nuttx/configs/olimex-strp711/nettest/defconfig
@@ -160,7 +160,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/pcblogic-pic32mx/nsh/defconfig b/nuttx/configs/pcblogic-pic32mx/nsh/defconfig
index b4bd30ae8..7bce554ac 100644
--- a/nuttx/configs/pcblogic-pic32mx/nsh/defconfig
+++ b/nuttx/configs/pcblogic-pic32mx/nsh/defconfig
@@ -189,7 +189,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/pcblogic-pic32mx/ostest/defconfig b/nuttx/configs/pcblogic-pic32mx/ostest/defconfig
index 08bdccddd..730b8134a 100644
--- a/nuttx/configs/pcblogic-pic32mx/ostest/defconfig
+++ b/nuttx/configs/pcblogic-pic32mx/ostest/defconfig
@@ -187,7 +187,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/pic32-starterkit/nsh/defconfig b/nuttx/configs/pic32-starterkit/nsh/defconfig
index f2cd27560..32220d89b 100644
--- a/nuttx/configs/pic32-starterkit/nsh/defconfig
+++ b/nuttx/configs/pic32-starterkit/nsh/defconfig
@@ -253,7 +253,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/pic32-starterkit/nsh2/defconfig b/nuttx/configs/pic32-starterkit/nsh2/defconfig
index 6f227f638..a7a1ff18a 100644
--- a/nuttx/configs/pic32-starterkit/nsh2/defconfig
+++ b/nuttx/configs/pic32-starterkit/nsh2/defconfig
@@ -252,7 +252,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/pic32-starterkit/ostest/defconfig b/nuttx/configs/pic32-starterkit/ostest/defconfig
index 922cb8901..3a55de491 100644
--- a/nuttx/configs/pic32-starterkit/ostest/defconfig
+++ b/nuttx/configs/pic32-starterkit/ostest/defconfig
@@ -250,7 +250,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/pic32mx7mmb/nsh/defconfig b/nuttx/configs/pic32mx7mmb/nsh/defconfig
index aa7fc23df..d39f8bc40 100644
--- a/nuttx/configs/pic32mx7mmb/nsh/defconfig
+++ b/nuttx/configs/pic32mx7mmb/nsh/defconfig
@@ -259,7 +259,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/pic32mx7mmb/ostest/defconfig b/nuttx/configs/pic32mx7mmb/ostest/defconfig
index 1d656380d..b3cecf98d 100644
--- a/nuttx/configs/pic32mx7mmb/ostest/defconfig
+++ b/nuttx/configs/pic32mx7mmb/ostest/defconfig
@@ -250,7 +250,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/sam3u-ek/knsh/defconfig b/nuttx/configs/sam3u-ek/knsh/defconfig
index e61180407..30f60f0e3 100755
--- a/nuttx/configs/sam3u-ek/knsh/defconfig
+++ b/nuttx/configs/sam3u-ek/knsh/defconfig
@@ -186,7 +186,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# These NSH commands are (temporarily) disable because more support is needed
diff --git a/nuttx/configs/sam3u-ek/nsh/defconfig b/nuttx/configs/sam3u-ek/nsh/defconfig
index 288df5957..971598464 100755
--- a/nuttx/configs/sam3u-ek/nsh/defconfig
+++ b/nuttx/configs/sam3u-ek/nsh/defconfig
@@ -171,7 +171,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/sam3u-ek/nx/defconfig b/nuttx/configs/sam3u-ek/nx/defconfig
index 7b56b9d41..dd55d9c93 100755
--- a/nuttx/configs/sam3u-ek/nx/defconfig
+++ b/nuttx/configs/sam3u-ek/nx/defconfig
@@ -172,7 +172,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/sam3u-ek/ostest/defconfig b/nuttx/configs/sam3u-ek/ostest/defconfig
index b2e9a5184..bf15cb1a5 100755
--- a/nuttx/configs/sam3u-ek/ostest/defconfig
+++ b/nuttx/configs/sam3u-ek/ostest/defconfig
@@ -172,7 +172,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/sam3u-ek/touchscreen/defconfig b/nuttx/configs/sam3u-ek/touchscreen/defconfig
index e89db8c4b..414eadb6e 100755
--- a/nuttx/configs/sam3u-ek/touchscreen/defconfig
+++ b/nuttx/configs/sam3u-ek/touchscreen/defconfig
@@ -180,7 +180,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/shenzhou/nsh/defconfig b/nuttx/configs/shenzhou/nsh/defconfig
index c54d714d0..383522b6f 100644
--- a/nuttx/configs/shenzhou/nsh/defconfig
+++ b/nuttx/configs/shenzhou/nsh/defconfig
@@ -273,7 +273,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
# CONFIG_SCHED_LPWORK is not set
CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_ATEXIT is not set
diff --git a/nuttx/configs/shenzhou/nxwm/defconfig b/nuttx/configs/shenzhou/nxwm/defconfig
index 975327747..b9bf72aeb 100644
--- a/nuttx/configs/shenzhou/nxwm/defconfig
+++ b/nuttx/configs/shenzhou/nxwm/defconfig
@@ -309,7 +309,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
# CONFIG_SCHED_LPWORK is not set
# CONFIG_SCHED_WAITPID is not set
# CONFIG_SCHED_ATEXIT is not set
diff --git a/nuttx/configs/shenzhou/thttpd/defconfig b/nuttx/configs/shenzhou/thttpd/defconfig
index 958ab02ed..d7af34821 100644
--- a/nuttx/configs/shenzhou/thttpd/defconfig
+++ b/nuttx/configs/shenzhou/thttpd/defconfig
@@ -260,7 +260,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
# CONFIG_SCHED_LPWORK is not set
CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_ATEXIT is not set
diff --git a/nuttx/configs/sim/nsh/defconfig b/nuttx/configs/sim/nsh/defconfig
index a60edd4ac..2d627a66d 100644
--- a/nuttx/configs/sim/nsh/defconfig
+++ b/nuttx/configs/sim/nsh/defconfig
@@ -72,7 +72,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
CONFIG_SCHED_ONEXIT=n
diff --git a/nuttx/configs/sim/nsh2/defconfig b/nuttx/configs/sim/nsh2/defconfig
index e5dcce322..c9e5b343f 100644
--- a/nuttx/configs/sim/nsh2/defconfig
+++ b/nuttx/configs/sim/nsh2/defconfig
@@ -91,7 +91,7 @@ CONFIG_PRIORITY_INHERITANCE=n
CONFIG_SEM_PREALLOCHOLDERS=0
CONFIG_SEM_NNESTPRIO=0
CONFIG_FDCLONE_DISABLE=n
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_FDCLONE_STDIO=n
CONFIG_SDCLONE_DISABLE=y
CONFIG_SCHED_WORKQUEUE=n
diff --git a/nuttx/configs/sim/ostest/defconfig b/nuttx/configs/sim/ostest/defconfig
index 43d78e6a2..5cea9a6d4 100644
--- a/nuttx/configs/sim/ostest/defconfig
+++ b/nuttx/configs/sim/ostest/defconfig
@@ -57,7 +57,7 @@ CONFIG_DEBUG_VERBOSE=y
#
# CONFIG_DEBUG_ANALOG is not set
# CONFIG_DEBUG_DMA is not set
-# CONFIG_DEBUG_SYMBOLS is not set
+CONFIG_DEBUG_SYMBOLS=y
#
# System Type
@@ -131,6 +131,7 @@ CONFIG_MSEC_PER_TICK=10
CONFIG_RR_INTERVAL=0
# CONFIG_SCHED_INSTRUMENTATION is not set
CONFIG_TASK_NAME_SIZE=32
+CONFIG_SCHED_HAVE_PARENT=y
# CONFIG_JULIAN_TIME is not set
CONFIG_START_YEAR=2007
CONFIG_START_MONTH=2
@@ -156,6 +157,15 @@ CONFIG_DISABLE_OS_API=y
# CONFIG_DISABLE_ENVIRON is not set
CONFIG_DISABLE_POLL=y
+#
+# Signal Numbers
+#
+CONFIG_SIG_SIGUSR1=1
+CONFIG_SIG_SIGUSR2=2
+CONFIG_SIG_SIGALARM=3
+CONFIG_SIG_SIGCHLD=4
+CONFIG_SIG_SIGCONDTIMEDOUT=16
+
#
# Sizes of configurable things (0 disables)
#
@@ -352,6 +362,7 @@ CONFIG_EXAMPLES_OSTEST_RR_RUNS=10
# CONFIG_EXAMPLES_PASHELLO is not set
# CONFIG_EXAMPLES_PIPE is not set
# CONFIG_EXAMPLES_POLL is not set
+# CONFIG_EXAMPLES_POSIXSPAWN is not set
# CONFIG_EXAMPLES_QENCODER is not set
# CONFIG_EXAMPLES_RGMP is not set
# CONFIG_EXAMPLES_ROMFS is not set
diff --git a/nuttx/configs/stm3210e-eval/RIDE/defconfig b/nuttx/configs/stm3210e-eval/RIDE/defconfig
index e71540c24..6d84e7c36 100755
--- a/nuttx/configs/stm3210e-eval/RIDE/defconfig
+++ b/nuttx/configs/stm3210e-eval/RIDE/defconfig
@@ -200,7 +200,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/stm3210e-eval/buttons/defconfig b/nuttx/configs/stm3210e-eval/buttons/defconfig
index 0d6882b5d..37e19171f 100644
--- a/nuttx/configs/stm3210e-eval/buttons/defconfig
+++ b/nuttx/configs/stm3210e-eval/buttons/defconfig
@@ -210,7 +210,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/stm3210e-eval/composite/defconfig b/nuttx/configs/stm3210e-eval/composite/defconfig
index 2db58aee5..7fee33794 100755
--- a/nuttx/configs/stm3210e-eval/composite/defconfig
+++ b/nuttx/configs/stm3210e-eval/composite/defconfig
@@ -210,7 +210,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/stm3210e-eval/nsh/defconfig b/nuttx/configs/stm3210e-eval/nsh/defconfig
index 52fdd777f..b5e52e494 100755
--- a/nuttx/configs/stm3210e-eval/nsh/defconfig
+++ b/nuttx/configs/stm3210e-eval/nsh/defconfig
@@ -208,7 +208,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/stm3210e-eval/nsh2/defconfig b/nuttx/configs/stm3210e-eval/nsh2/defconfig
index 18e42d539..30a0bb327 100644
--- a/nuttx/configs/stm3210e-eval/nsh2/defconfig
+++ b/nuttx/configs/stm3210e-eval/nsh2/defconfig
@@ -255,7 +255,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3210e-eval/nx/defconfig b/nuttx/configs/stm3210e-eval/nx/defconfig
index 68a3ad9b5..0ad42dfbe 100644
--- a/nuttx/configs/stm3210e-eval/nx/defconfig
+++ b/nuttx/configs/stm3210e-eval/nx/defconfig
@@ -209,7 +209,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/stm3210e-eval/nxconsole/defconfig b/nuttx/configs/stm3210e-eval/nxconsole/defconfig
index 9cb8689c6..7dd5878bf 100644
--- a/nuttx/configs/stm3210e-eval/nxconsole/defconfig
+++ b/nuttx/configs/stm3210e-eval/nxconsole/defconfig
@@ -209,7 +209,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/stm3210e-eval/nxlines/defconfig b/nuttx/configs/stm3210e-eval/nxlines/defconfig
index ab42612f3..068a17acb 100644
--- a/nuttx/configs/stm3210e-eval/nxlines/defconfig
+++ b/nuttx/configs/stm3210e-eval/nxlines/defconfig
@@ -209,7 +209,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/stm3210e-eval/nxtext/defconfig b/nuttx/configs/stm3210e-eval/nxtext/defconfig
index c00e9b1e8..b6f88a3ca 100644
--- a/nuttx/configs/stm3210e-eval/nxtext/defconfig
+++ b/nuttx/configs/stm3210e-eval/nxtext/defconfig
@@ -209,7 +209,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/stm3210e-eval/ostest/defconfig b/nuttx/configs/stm3210e-eval/ostest/defconfig
index 8ed1795a6..0553b1a98 100755
--- a/nuttx/configs/stm3210e-eval/ostest/defconfig
+++ b/nuttx/configs/stm3210e-eval/ostest/defconfig
@@ -220,7 +220,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/stm3210e-eval/pm/defconfig b/nuttx/configs/stm3210e-eval/pm/defconfig
index 7babce8f6..61bd995c8 100644
--- a/nuttx/configs/stm3210e-eval/pm/defconfig
+++ b/nuttx/configs/stm3210e-eval/pm/defconfig
@@ -265,7 +265,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3210e-eval/usbserial/defconfig b/nuttx/configs/stm3210e-eval/usbserial/defconfig
index b41b41f50..94059c07c 100755
--- a/nuttx/configs/stm3210e-eval/usbserial/defconfig
+++ b/nuttx/configs/stm3210e-eval/usbserial/defconfig
@@ -210,7 +210,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/stm3210e-eval/usbstorage/defconfig b/nuttx/configs/stm3210e-eval/usbstorage/defconfig
index 9f927d7e3..5c1ed5fb2 100755
--- a/nuttx/configs/stm3210e-eval/usbstorage/defconfig
+++ b/nuttx/configs/stm3210e-eval/usbstorage/defconfig
@@ -210,7 +210,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/stm3220g-eval/dhcpd/defconfig b/nuttx/configs/stm3220g-eval/dhcpd/defconfig
index 04f243d71..29baf9af0 100644
--- a/nuttx/configs/stm3220g-eval/dhcpd/defconfig
+++ b/nuttx/configs/stm3220g-eval/dhcpd/defconfig
@@ -262,7 +262,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3220g-eval/nettest/defconfig b/nuttx/configs/stm3220g-eval/nettest/defconfig
index 201df86b0..08e04ad0e 100644
--- a/nuttx/configs/stm3220g-eval/nettest/defconfig
+++ b/nuttx/configs/stm3220g-eval/nettest/defconfig
@@ -262,7 +262,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3220g-eval/nsh/defconfig b/nuttx/configs/stm3220g-eval/nsh/defconfig
index 8baf52f7e..bd9d02860 100644
--- a/nuttx/configs/stm3220g-eval/nsh/defconfig
+++ b/nuttx/configs/stm3220g-eval/nsh/defconfig
@@ -297,7 +297,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3220g-eval/nsh2/defconfig b/nuttx/configs/stm3220g-eval/nsh2/defconfig
index c273ce60f..b5fe843bc 100644
--- a/nuttx/configs/stm3220g-eval/nsh2/defconfig
+++ b/nuttx/configs/stm3220g-eval/nsh2/defconfig
@@ -296,7 +296,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3220g-eval/nxwm/defconfig b/nuttx/configs/stm3220g-eval/nxwm/defconfig
index ab061f07a..145792ddb 100644
--- a/nuttx/configs/stm3220g-eval/nxwm/defconfig
+++ b/nuttx/configs/stm3220g-eval/nxwm/defconfig
@@ -316,7 +316,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
# CONFIG_SCHED_LPWORK is not set
CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_ATEXIT is not set
diff --git a/nuttx/configs/stm3220g-eval/ostest/defconfig b/nuttx/configs/stm3220g-eval/ostest/defconfig
index 2393d0a69..f63f96c9a 100644
--- a/nuttx/configs/stm3220g-eval/ostest/defconfig
+++ b/nuttx/configs/stm3220g-eval/ostest/defconfig
@@ -261,7 +261,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3220g-eval/telnetd/defconfig b/nuttx/configs/stm3220g-eval/telnetd/defconfig
index 1401dc6e7..f529198f1 100644
--- a/nuttx/configs/stm3220g-eval/telnetd/defconfig
+++ b/nuttx/configs/stm3220g-eval/telnetd/defconfig
@@ -262,7 +262,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3240g-eval/dhcpd/defconfig b/nuttx/configs/stm3240g-eval/dhcpd/defconfig
index 80293f66a..5199cf85c 100644
--- a/nuttx/configs/stm3240g-eval/dhcpd/defconfig
+++ b/nuttx/configs/stm3240g-eval/dhcpd/defconfig
@@ -268,7 +268,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3240g-eval/nettest/defconfig b/nuttx/configs/stm3240g-eval/nettest/defconfig
index 81a53bd68..c5e0da795 100644
--- a/nuttx/configs/stm3240g-eval/nettest/defconfig
+++ b/nuttx/configs/stm3240g-eval/nettest/defconfig
@@ -268,7 +268,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3240g-eval/nsh/defconfig b/nuttx/configs/stm3240g-eval/nsh/defconfig
index 54eb1d56f..6c19ed531 100644
--- a/nuttx/configs/stm3240g-eval/nsh/defconfig
+++ b/nuttx/configs/stm3240g-eval/nsh/defconfig
@@ -301,7 +301,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
CONFIG_DEV_RANDOM=y
diff --git a/nuttx/configs/stm3240g-eval/nsh2/defconfig b/nuttx/configs/stm3240g-eval/nsh2/defconfig
index ba6445615..08690ade3 100644
--- a/nuttx/configs/stm3240g-eval/nsh2/defconfig
+++ b/nuttx/configs/stm3240g-eval/nsh2/defconfig
@@ -302,7 +302,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3240g-eval/nxconsole/defconfig b/nuttx/configs/stm3240g-eval/nxconsole/defconfig
index f8a1fb7d5..202fa4378 100644
--- a/nuttx/configs/stm3240g-eval/nxconsole/defconfig
+++ b/nuttx/configs/stm3240g-eval/nxconsole/defconfig
@@ -301,7 +301,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3240g-eval/nxwm/defconfig b/nuttx/configs/stm3240g-eval/nxwm/defconfig
index 5dfdb28fc..a220af2d1 100644
--- a/nuttx/configs/stm3240g-eval/nxwm/defconfig
+++ b/nuttx/configs/stm3240g-eval/nxwm/defconfig
@@ -302,7 +302,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
CONFIG_SCHED_ONEXIT=y
diff --git a/nuttx/configs/stm3240g-eval/ostest/defconfig b/nuttx/configs/stm3240g-eval/ostest/defconfig
index 38b51e84b..fcc54aa4b 100644
--- a/nuttx/configs/stm3240g-eval/ostest/defconfig
+++ b/nuttx/configs/stm3240g-eval/ostest/defconfig
@@ -266,7 +266,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3240g-eval/telnetd/defconfig b/nuttx/configs/stm3240g-eval/telnetd/defconfig
index 471845c14..5aef41c27 100644
--- a/nuttx/configs/stm3240g-eval/telnetd/defconfig
+++ b/nuttx/configs/stm3240g-eval/telnetd/defconfig
@@ -268,7 +268,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm3240g-eval/webserver/defconfig b/nuttx/configs/stm3240g-eval/webserver/defconfig
index e9cbbf93d..6d09968e9 100644
--- a/nuttx/configs/stm3240g-eval/webserver/defconfig
+++ b/nuttx/configs/stm3240g-eval/webserver/defconfig
@@ -302,7 +302,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=2048
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm32f100rc_generic/nsh/defconfig b/nuttx/configs/stm32f100rc_generic/nsh/defconfig
index 65ac9a73d..12193e7ed 100644
--- a/nuttx/configs/stm32f100rc_generic/nsh/defconfig
+++ b/nuttx/configs/stm32f100rc_generic/nsh/defconfig
@@ -249,7 +249,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
# CONFIG_SCHED_LPWORK is not set
CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_ATEXIT is not set
diff --git a/nuttx/configs/stm32f4discovery/README.txt b/nuttx/configs/stm32f4discovery/README.txt
index c1d484279..39fb41d78 100644
--- a/nuttx/configs/stm32f4discovery/README.txt
+++ b/nuttx/configs/stm32f4discovery/README.txt
@@ -1447,6 +1447,32 @@ Where is one of the following:
STANDBY mode. This used of the RTC alarm could conflict with other uses of
the RTC alarm in your application.
+
+ posix_spawn:
+ ------------
+ This configuration directory, performs a simple test os the posix_spawn
+ interface using apps/examples/posix_spawn.
+
+ NOTES:
+
+ 1. This configuration uses the mconf-based configuration tool. To
+ change this configuration using that tool, you should:
+
+ a. Build and install the kconfig-mconf tool. See nuttx/README.txt
+ and misc/tools/
+
+ b. Execute 'make menuconfig' in nuttx/ in order to start the
+ reconfiguration process.
+
+ 2. Default toolchain:
+
+ CONFIG_HOST_WINDOWS=y : Builds under windows
+ CONFIG_WINDOWS_CYGWIN=y : Using Cygwin and
+ CONFIG_STM32_CODESOURCERYW=y : The native Windows CodeSourcery toolchain
+
+ 3. By default, this project assumes that you are *NOT* using the DFU
+ bootloader.
+
winbuild:
--------
diff --git a/nuttx/configs/stm32f4discovery/nsh/defconfig b/nuttx/configs/stm32f4discovery/nsh/defconfig
index 8967fd01c..98034e22e 100644
--- a/nuttx/configs/stm32f4discovery/nsh/defconfig
+++ b/nuttx/configs/stm32f4discovery/nsh/defconfig
@@ -282,7 +282,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm32f4discovery/pm/defconfig b/nuttx/configs/stm32f4discovery/pm/defconfig
index 105eb4d37..3e24168cd 100644
--- a/nuttx/configs/stm32f4discovery/pm/defconfig
+++ b/nuttx/configs/stm32f4discovery/pm/defconfig
@@ -283,7 +283,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/stm32f4discovery/posix_spawn/defconfig b/nuttx/configs/stm32f4discovery/posix_spawn/defconfig
index b908393d8..9e30ada8a 100644
--- a/nuttx/configs/stm32f4discovery/posix_spawn/defconfig
+++ b/nuttx/configs/stm32f4discovery/posix_spawn/defconfig
@@ -441,7 +441,7 @@ CONFIG_EOL_IS_EITHER_CRLF=y
CONFIG_LIBC_EXECFUNCS=y
CONFIG_EXECFUNCS_SYMTAB="exports"
CONFIG_EXECFUNCS_NSYMBOLS=10
-CONFIG_POSIX_SPAWN_STACKSIZE=768
+CONFIG_POSIX_SPAWN_STACKSIZE=1024
# CONFIG_LIBC_STRERROR is not set
# CONFIG_LIBC_PERROR_STDOUT is not set
CONFIG_ARCH_LOWPUTC=y
diff --git a/nuttx/configs/sure-pic32mx/nsh/defconfig b/nuttx/configs/sure-pic32mx/nsh/defconfig
index 050f30247..60c4dc53d 100644
--- a/nuttx/configs/sure-pic32mx/nsh/defconfig
+++ b/nuttx/configs/sure-pic32mx/nsh/defconfig
@@ -202,7 +202,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/sure-pic32mx/ostest/defconfig b/nuttx/configs/sure-pic32mx/ostest/defconfig
index eb386e232..1bca11c47 100644
--- a/nuttx/configs/sure-pic32mx/ostest/defconfig
+++ b/nuttx/configs/sure-pic32mx/ostest/defconfig
@@ -188,7 +188,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/sure-pic32mx/usbnsh/defconfig b/nuttx/configs/sure-pic32mx/usbnsh/defconfig
index 2b28b94c7..978e16541 100644
--- a/nuttx/configs/sure-pic32mx/usbnsh/defconfig
+++ b/nuttx/configs/sure-pic32mx/usbnsh/defconfig
@@ -199,7 +199,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/teensy/hello/defconfig b/nuttx/configs/teensy/hello/defconfig
index 93376ac57..8fafe1a10 100644
--- a/nuttx/configs/teensy/hello/defconfig
+++ b/nuttx/configs/teensy/hello/defconfig
@@ -137,7 +137,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for nxflat
diff --git a/nuttx/configs/teensy/nsh/defconfig b/nuttx/configs/teensy/nsh/defconfig
index ffcd94c1d..faeb0b103 100755
--- a/nuttx/configs/teensy/nsh/defconfig
+++ b/nuttx/configs/teensy/nsh/defconfig
@@ -137,7 +137,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/teensy/usbstorage/defconfig b/nuttx/configs/teensy/usbstorage/defconfig
index dba45073f..1f0186897 100755
--- a/nuttx/configs/teensy/usbstorage/defconfig
+++ b/nuttx/configs/teensy/usbstorage/defconfig
@@ -138,7 +138,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# Settings for NXFLAT
diff --git a/nuttx/configs/twr-k60n512/nsh/defconfig b/nuttx/configs/twr-k60n512/nsh/defconfig
index aeb0c5359..7a4bb3b3a 100644
--- a/nuttx/configs/twr-k60n512/nsh/defconfig
+++ b/nuttx/configs/twr-k60n512/nsh/defconfig
@@ -204,7 +204,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/twr-k60n512/ostest/defconfig b/nuttx/configs/twr-k60n512/ostest/defconfig
index 9cf37c763..355e5773b 100644
--- a/nuttx/configs/twr-k60n512/ostest/defconfig
+++ b/nuttx/configs/twr-k60n512/ostest/defconfig
@@ -203,7 +203,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
#
# The following can be used to disable categories of
diff --git a/nuttx/configs/ubw32/nsh/defconfig b/nuttx/configs/ubw32/nsh/defconfig
index 320b7e266..ad18c12b6 100644
--- a/nuttx/configs/ubw32/nsh/defconfig
+++ b/nuttx/configs/ubw32/nsh/defconfig
@@ -189,7 +189,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/ubw32/ostest/defconfig b/nuttx/configs/ubw32/ostest/defconfig
index 71f286700..60322d4f6 100644
--- a/nuttx/configs/ubw32/ostest/defconfig
+++ b/nuttx/configs/ubw32/ostest/defconfig
@@ -188,7 +188,7 @@ CONFIG_SCHED_WORKQUEUE=n
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=n
CONFIG_SCHED_ATEXIT=n
diff --git a/nuttx/configs/vsn/nsh/defconfig b/nuttx/configs/vsn/nsh/defconfig
index fa5570596..2b7d8a20c 100755
--- a/nuttx/configs/vsn/nsh/defconfig
+++ b/nuttx/configs/vsn/nsh/defconfig
@@ -247,7 +247,7 @@ CONFIG_SCHED_WORKQUEUE=y
CONFIG_SCHED_WORKPRIORITY=192
CONFIG_SCHED_WORKPERIOD=50000
CONFIG_SCHED_WORKSTACKSIZE=1024
-CONFIG_SIG_SIGWORK=4
+CONFIG_SIG_SIGWORK=17
CONFIG_SCHED_WAITPID=y
#
# The following can be used to disable categories of
diff --git a/nuttx/include/nuttx/sched.h b/nuttx/include/nuttx/sched.h
index 940bf1f1b..6c67e1500 100644
--- a/nuttx/include/nuttx/sched.h
+++ b/nuttx/include/nuttx/sched.h
@@ -202,6 +202,9 @@ struct _TCB
/* Task Management Fields *****************************************************/
pid_t pid; /* This is the ID of the thread */
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ pid_t parent; /* This is the ID of the parent thread */
+#endif
start_t start; /* Thread start function */
entry_t entry; /* Entry Point into the thread */
diff --git a/nuttx/include/nuttx/wqueue.h b/nuttx/include/nuttx/wqueue.h
index c509bf197..d56901d89 100644
--- a/nuttx/include/nuttx/wqueue.h
+++ b/nuttx/include/nuttx/wqueue.h
@@ -68,7 +68,7 @@
* CONFIG_SCHED_WORKSTACKSIZE - The stack size allocated for the worker
* thread. Default: CONFIG_IDLETHREAD_STACKSIZE.
* CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up
- * the worker thread. Default: 4
+ * the worker thread. Default: 17
*
* CONFIG_SCHED_LPWORK. If CONFIG_SCHED_WORKQUEUE is defined, then a single
* work queue is created by default. If CONFIG_SCHED_LPWORK is also defined
diff --git a/nuttx/include/signal.h b/nuttx/include/signal.h
index 02b222343..30726105b 100644
--- a/nuttx/include/signal.h
+++ b/nuttx/include/signal.h
@@ -66,44 +66,56 @@
/* A few of the real time signals are used within the OS. They have
* default values that can be overridden from the configuration file. The
- * rest are all user signals:
+ * rest are all user signals.
+ *
+ * These are semi-standard signal definitions:
*/
#ifndef CONFIG_SIG_SIGUSR1
-#define SIGUSR1 0 /* User signal 1 */
+# define SIGUSR1 1 /* User signal 1 */
#else
-#define SIGUSR1 CONFIG_SIG_SIGUSR1
+# define SIGUSR1 CONFIG_SIG_SIGUSR1
#endif
#ifndef CONFIG_SIG_SIGUSR2
-#define SIGUSR2 1 /* User signal 2 */
+# define SIGUSR2 2 /* User signal 2 */
#else
-#define SIGUSR2 CONFIG_SIG_SIGUSR2
+# define SIGUSR2 CONFIG_SIG_SIGUSR2
#endif
#ifndef CONFIG_SIG_SIGALARM
-#define SIGALRM 2 /* Default signal used with POSIX timers (used only */
+# define SIGALRM 3 /* Default signal used with POSIX timers (used only */
/* no other signal is provided) */
#else
-#define SIGALRM CONFIG_SIG_SIGALARM
+# define SIGALRM CONFIG_SIG_SIGALARM
#endif
-#ifndef CONFIG_DISABLE_PTHREAD
-#ifndef CONFIG_SIG_SIGCONDTIMEDOUT
-#define SIGCONDTIMEDOUT 3 /* Used in the implementation of pthread_cond_timedwait */
-#else
-#define SIGCONDTIMEDOUT CONFIG_SIG_SIGCONDTIMEDOUT
+#ifdef CONFIG_SCHED_HAVE_PARENT
+# ifndef CONFIG_SIG_SIGCHLD
+# define SIGCHLD 4 /* Used by child threads to signal parent thread */
+# else
+# define SIGCHLD CONFIG_SIG_SIGCHLD
+# endif
#endif
+
+/* The following are non-standard signal definitions */
+
+#ifndef CONFIG_DISABLE_PTHREAD
+# ifndef CONFIG_SIG_SIGCONDTIMEDOUT
+# define SIGCONDTIMEDOUT 16 /* Used in the implementation of pthread_cond_timedwait */
+# else
+# define SIGCONDTIMEDOUT CONFIG_SIG_SIGCONDTIMEDOUT
+# endif
#endif
/* SIGWORK is used to wake up various internal, NuttX worker thread */
#if defined(CONFIG_SCHED_WORKQUEUE) || defined(CONFIG_PAGING)
-#ifndef CONFIG_SIG_SIGWORK
-#define SIGWORK 4 /* Used to wake up the work queue */
-#else
-#define SIGWORK CONFIG_SIG_SIGWORK
-#endif
+# ifndef CONFIG_SIG_SIGWORK
+# define SIGWORK 17 /* Used to wake up the work queue */
+# else
+# define SIGWORK CONFIG_SIG_SIGWORK
+# endif
#endif
/* sigprocmask() "how" definitions. Only one of the following can be specified: */
@@ -122,12 +134,18 @@
/* These are the possible values of the signfo si_code field */
-#define SI_USER 0 /* Signal sent from kill, raise, or abort */
-#define SI_QUEUE 1 /* Signal sent from sigqueue */
-#define SI_TIMER 2 /* Signal is result of timer expiration */
-#define SI_ASYNCIO 3 /* Signal is the result of asynch IO completion */
-#define SI_MESGQ 4 /* Signal generated by arrival of a message on an */
- /* empty message queue */
+#define SI_USER 0 /* Signal sent from kill, raise, or abort */
+#define SI_QUEUE 1 /* Signal sent from sigqueue */
+#define SI_TIMER 2 /* Signal is result of timer expiration */
+#define SI_ASYNCIO 3 /* Signal is the result of asynch IO completion */
+#define SI_MESGQ 4 /* Signal generated by arrival of a message on an */
+ /* empty message queue */
+#define CLD_EXITED 5 /* Child has exited (SIGCHLD only) */
+#define CLD_KILLED 6 /* Child was killed (SIGCHLD only) */
+#define CLD_DUMPED 7 /* Child terminated abnormally (SIGCHLD only) */
+#define CLD_TRAPPED 8 /* Traced child has trapped (SIGCHLD only) */
+#define CLD_STOPPED 9 /* Child has stopped (SIGCHLD only) */
+#define CLD_CONTINUED 10 /* Stopped child had continued (SIGCHLD only) */
/* Values for the sigev_notify field of struct sigevent */
@@ -175,6 +193,10 @@ struct siginfo
uint8_t si_signo; /* Identifies signal */
uint8_t si_code; /* Source: SI_USER, SI_QUEUE, SI_TIMER, SI_ASYNCIO, or SI_MESGQ */
union sigval si_value; /* Data passed with signal */
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ pid_t si_pid; /* Sending task ID */
+ int si_status; /* Exit value or signal (SIGCHLD only). */
+#endif
};
typedef struct siginfo siginfo_t;
diff --git a/nuttx/libc/Kconfig b/nuttx/libc/Kconfig
index 2f091f1c7..72a6a5346 100644
--- a/nuttx/libc/Kconfig
+++ b/nuttx/libc/Kconfig
@@ -123,11 +123,12 @@ config EXECFUNCS_NSYMBOLS
config POSIX_SPAWN_STACKSIZE
int "posix_spawn Stack Size"
- default 768
+ default 1024
---help---
If posix_spawn[p] uses I/O redirection options, then it will require
an intermediary/proxy task to muck with the file descriptors. This
- configuration item specifies the stack size used for the proxy.
+ configuration item specifies the stack size used for the proxy. Default:
+ 1024 bytes.
endif
diff --git a/nuttx/sched/Kconfig b/nuttx/sched/Kconfig
index bfaec3b5d..69621a1fa 100644
--- a/nuttx/sched/Kconfig
+++ b/nuttx/sched/Kconfig
@@ -38,6 +38,16 @@ config TASK_NAME_SIZE
Useful if scheduler instrumentation is selected. Set to zero to
disable.
+config SCHED_HAVE_PARENT
+ bool "Remember Parent"
+ default n
+ ---help---
+ Remember the ID of the parent thread when a new child thread is
+ created. This support enables a few minor features (such as
+ SIGCHLD) and slightly increases the size of the Task Control Block
+ (TCB) of every task to hold the ID of the parent thread. Default:
+ disabled.
+
config JULIAN_TIME
bool "Enables Julian time conversions"
default n
@@ -127,6 +137,7 @@ config SDCLONE_DISABLE
config SCHED_WORKQUEUE
bool "Enable worker thread"
default n
+ depends on !DISABLE_SIGNALS
---help---
Create a dedicated "worker" thread to handle delayed processing from interrupt
handlers. This feature is required for some drivers but, if there are no
@@ -158,14 +169,6 @@ config SCHED_WORKSTACKSIZE
---help---
The stack size allocated for the worker thread. Default: 2K.
-config SIG_SIGWORK
- int "Worker thread wakeup signal"
- default 4
- depends on SCHED_WORKQUEUE
- ---help---
- The signal number that will be used to wake-up the worker thread.
- Default: 4
-
config SCHED_LPWORK
bool "Enable a lower priority worker thread"
default n
@@ -310,6 +313,56 @@ config DISABLE_POLL
depends on DISABLE_OS_API
default n
+if !DISABLE_SIGNALS
+comment "Signal Numbers"
+
+config SIG_SIGUSR1
+ int "SIGUSR1"
+ default 1
+ ---help---
+ Value of standard user signal 1 (SIGUSR1). Default: 1
+
+config SIG_SIGUSR2
+ int "SIGUSR2"
+ default 2
+ ---help---
+ Value of standard user signal 2 (SIGUSR2). Default: 2
+
+config SIG_SIGALARM
+ int "SIGALRM"
+ default 3
+ ---help---
+ Default the signal number used with POSIX timers (SIGALRM).
+ Default: 3
+
+config SIG_SIGCHLD
+ int "SIGCHLD"
+ default 4
+ depends on SCHED_HAVE_PARENT
+ ---help---
+ The SIGCHLD signal is sent to the parent of a child process when it
+ exits, is interrupted (stopped), or resumes after being interrupted.
+ Default: 4
+
+config SIG_SIGCONDTIMEDOUT
+ int "SIGCONDTIMEDOUT"
+ default 16
+ depends on !DISABLE_PTHREAD
+ ---help---
+ This non-standard signal number is used the implementation of
+ pthread_cond_timedwait(). Default 16.
+
+config SIG_SIGWORK
+ int "SIGWORK"
+ default 17
+ depends on SCHED_WORKQUEUE
+ ---help---
+ SIGWORK is a non-standard signal used to wake up the internal NuttX
+ worker thread. This setting specifies the signal number that will be
+ used for SIGWORK. Default: 17
+
+endif
+
comment "Sizes of configurable things (0 disables)"
config MAX_TASKS
diff --git a/nuttx/sched/sched_unlock.c b/nuttx/sched/sched_unlock.c
index 9a52e8358..5eafcfc9e 100644
--- a/nuttx/sched/sched_unlock.c
+++ b/nuttx/sched/sched_unlock.c
@@ -126,5 +126,6 @@ int sched_unlock(void)
irqrestore(flags);
}
+
return OK;
}
diff --git a/nuttx/sched/sig_kill.c b/nuttx/sched/sig_kill.c
index 17921015f..b3d74d8a1 100644
--- a/nuttx/sched/sig_kill.c
+++ b/nuttx/sched/sig_kill.c
@@ -84,6 +84,9 @@
int kill(pid_t pid, int signo)
{
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ FAR _TCB *rtcb = (FAR _TCB *)g_readytorun.head;
+#endif
FAR _TCB *stcb;
siginfo_t info;
int ret = ERROR;
@@ -124,6 +127,10 @@ int kill(pid_t pid, int signo)
info.si_signo = signo;
info.si_code = SI_USER;
info.si_value.sival_ptr = NULL;
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ info.si_pid = rtcb->pid;
+ info.si_status = OK;
+#endif
/* Send the signal */
diff --git a/nuttx/sched/sig_mqnotempty.c b/nuttx/sched/sig_mqnotempty.c
index 9a1fd7243..f7ae6fd0d 100644
--- a/nuttx/sched/sig_mqnotempty.c
+++ b/nuttx/sched/sig_mqnotempty.c
@@ -88,6 +88,9 @@ int sig_mqnotempty (int pid, int signo, union sigval value)
int sig_mqnotempty (int pid, int signo, void *sival_ptr)
#endif
{
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ FAR _TCB *rtcb = (FAR _TCB *)g_readytorun.head;
+#endif
FAR _TCB *stcb;
siginfo_t info;
int ret = ERROR;
@@ -113,6 +116,10 @@ int sig_mqnotempty (int pid, int signo, void *sival_ptr)
#else
info.si_value.sival_ptr = sival_ptr;
#endif
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ info.si_pid = rtcb->pid;
+ info.si_status = OK;
+#endif
/* Verify that we can perform the signalling operation */
diff --git a/nuttx/sched/sig_queue.c b/nuttx/sched/sig_queue.c
index dee1c798a..db404238e 100644
--- a/nuttx/sched/sig_queue.c
+++ b/nuttx/sched/sig_queue.c
@@ -111,6 +111,9 @@ int sigqueue (int pid, int signo, union sigval value)
int sigqueue(int pid, int signo, void *sival_ptr)
#endif
{
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ FAR _TCB *rtcb = (FAR _TCB *)g_readytorun.head;
+#endif
FAR _TCB *stcb;
siginfo_t info;
int ret = ERROR;
@@ -142,13 +145,17 @@ int sigqueue(int pid, int signo, void *sival_ptr)
/* Create the siginfo structure */
- info.si_signo = signo;
- info.si_code = SI_QUEUE;
+ info.si_signo = signo;
+ info.si_code = SI_QUEUE;
#ifdef CONFIG_CAN_PASS_STRUCTS
- info.si_value = value;
+ info.si_value = value;
#else
info.si_value.sival_ptr = sival_ptr;
#endif
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ info.si_pid = rtcb->pid;
+ info.si_status = OK;
+#endif
/* Send the signal */
diff --git a/nuttx/sched/sig_timedwait.c b/nuttx/sched/sig_timedwait.c
index d7610cd49..b07b8f2a1 100644
--- a/nuttx/sched/sig_timedwait.c
+++ b/nuttx/sched/sig_timedwait.c
@@ -120,6 +120,10 @@ static void sig_timeout(int argc, uint32_t itcb)
u.wtcb->sigunbinfo.si_signo = SIG_WAIT_TIMEOUT;
u.wtcb->sigunbinfo.si_code = SI_TIMER;
u.wtcb->sigunbinfo.si_value.sival_int = 0;
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ u.wtcb->sigunbinfo.si_pid = 0; /* Not applicable */
+ u.wtcb->sigunbinfo.si_status = OK;
+#endif
up_unblock_task(u.wtcb);
}
}
diff --git a/nuttx/sched/task_deletecurrent.c b/nuttx/sched/task_deletecurrent.c
index 77025f5e0..7ecfb26cc 100644
--- a/nuttx/sched/task_deletecurrent.c
+++ b/nuttx/sched/task_deletecurrent.c
@@ -90,6 +90,9 @@
* Return Value:
* OK on success; or ERROR on failure
*
+ * Assumeptions:
+ * Interrupts are disabled.
+ *
****************************************************************************/
int task_deletecurrent(void)
@@ -108,7 +111,7 @@ int task_deletecurrent(void)
(void)sched_removereadytorun(dtcb);
rtcb = (FAR _TCB*)g_readytorun.head;
- /* We are not in a bad state -- the head of the ready to run task list
+ /* We are now in a bad state -- the head of the ready to run task list
* does not correspond to the thread that is running. Disabling pre-
* emption on this TCB and marking the new ready-to-run task as not
* running (see, for example, get_errno_ptr()).
@@ -132,9 +135,16 @@ int task_deletecurrent(void)
(void)sched_mergepending();
}
- /* Now calling sched_unlock() should have no effect */
+ /* We can't use sched_unlock() to decrement the lock count because the
+ * sched_mergepending() call above might have changed the task at the
+ * head of the ready-to-run list. Furthermore, we should not need to
+ * perform the unlock action anyway because we know that the pending
+ * task list is empty. So all we really need to do is to decrement
+ * the lockcount on rctb.
+ */
- sched_unlock();
+ DEBUGASSERT(rtcb->lockcount > 0);
+ rtcb->lockcount--;
return OK;
}
diff --git a/nuttx/sched/task_exithook.c b/nuttx/sched/task_exithook.c
index 3bde8fb7a..9ce2e5899 100644
--- a/nuttx/sched/task_exithook.c
+++ b/nuttx/sched/task_exithook.c
@@ -41,6 +41,7 @@
#include
#include
+#include
#include
#include
@@ -187,6 +188,56 @@ static inline void task_onexit(FAR _TCB *tcb, int status)
# define task_onexit(tcb,status)
#endif
+/****************************************************************************
+ * Name: task_sigchild
+ *
+ * Description:
+ * Send the SIGCHILD signal to the parent thread
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_HAVE_PARENT
+static inline void task_sigchild(FAR _TCB *tcb, int status)
+{
+ FAR _TCB *ptcb;
+ siginfo_t info;
+
+ /* Keep things stationary through the following */
+
+ sched_lock();
+
+ /* Get the TCB of the receiving task */
+
+ ptcb = sched_gettcb(tcb->parent);
+ if (!ptcb)
+ {
+ /* The parent no longer exists... bail */
+
+ sched_unlock();
+ return;
+ }
+
+ /* Create the siginfo structure. We don't actually know the cause. That
+ * is a bug. Let's just say that the child task just exit-ted for now.
+ */
+
+ info.si_signo = SIGCHLD;
+ info.si_code = CLD_EXITED;
+ info.si_value.sival_ptr = NULL;
+ info.si_pid = tcb->pid;
+ info.si_status = status;
+
+ /* Send the signal. We need to use this internal interface so that we can
+ * provide the correct si_code value with the signal.
+ */
+
+ (void)sig_received(ptcb, &info);
+ sched_unlock();
+}
+#else
+# define task_sigchild(tcb,status)
+#endif
+
/****************************************************************************
* Name: task_exitwakeup
*
@@ -259,6 +310,10 @@ void task_exithook(FAR _TCB *tcb, int status)
task_atexit(tcb);
+ /* Send SIGCHLD to the parent of the exiting task */
+
+ task_sigchild(tcb, status);
+
/* Call any registered on_exit function(s) */
task_onexit(tcb, status);
diff --git a/nuttx/sched/task_setup.c b/nuttx/sched/task_setup.c
index 8721b39ec..c5dd8ca3a 100644
--- a/nuttx/sched/task_setup.c
+++ b/nuttx/sched/task_setup.c
@@ -146,6 +146,34 @@ static int task_assignpid(FAR _TCB *tcb)
return ERROR;
}
+/****************************************************************************
+ * Name: task_saveparent
+ *
+ * Description:
+ * Save the task ID of the parent task in the child task's TCB.
+ *
+ * Parameters:
+ * tcb - The TCB of the new, child task.
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * The parent of the new task is the task at the head of the ready-to-run
+ * list.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_HAVE_PARENT
+static inline void task_saveparent(FAR _TCB *tcb)
+{
+ FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+ tcb->parent = rtcb->pid;
+}
+#else
+# define task_saveparent(tcb)
+#endif
+
/****************************************************************************
* Name: task_dupdspace
*
@@ -161,6 +189,8 @@ static int task_assignpid(FAR _TCB *tcb)
* None
*
* Assumptions:
+ * The parent of the new task is the task at the head of the ready-to-run
+ * list.
*
****************************************************************************/
@@ -231,6 +261,10 @@ int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, main_t main)
tcb->start = start;
tcb->entry.main = main;
+ /* Save the task ID of the parent task in the TCB */
+
+ task_saveparent(tcb);
+
/* exec(), pthread_create(), task_create(), and vfork() all
* inherit the signal mask of the parent thread.
*/
@@ -243,7 +277,7 @@ int task_schedsetup(FAR _TCB *tcb, int priority, start_t start, main_t main)
* until it is activated.
*/
- tcb->task_state = TSTATE_TASK_INVALID;
+ tcb->task_state = TSTATE_TASK_INVALID;
/* Clone the parent tasks D-Space (if it was running PIC). This
* must be done before calling up_initial_state() so that the
diff --git a/nuttx/sched/timer_settime.c b/nuttx/sched/timer_settime.c
index 1814ba898..f09842ad4 100644
--- a/nuttx/sched/timer_settime.c
+++ b/nuttx/sched/timer_settime.c
@@ -113,6 +113,10 @@ static void inline timer_sigqueue(FAR struct posix_timer_s *timer)
#else
info.si_value.sival_ptr = timer->pt_value.sival_ptr;
#endif
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ info.si_pid = 0; /* Not applicable */
+ info.si_status = OK;
+#endif
/* Send the signal */
--
cgit v1.2.3
From ffda55b34a9a8a4a84f4cbc1da3836b944baec46 Mon Sep 17 00:00:00 2001
From: patacongo
Date: Sun, 13 Jan 2013 00:35:47 +0000
Subject: Cosmetic cleanup from SIGCHLD changes
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5514 42af7a65-404d-4744-a932-0658087f49c3
---
apps/examples/ostest/sighand.c | 7 ++++++-
nuttx/ChangeLog | 2 +-
nuttx/sched/task_deletecurrent.c | 6 ++++--
3 files changed, 11 insertions(+), 4 deletions(-)
(limited to 'nuttx/sched')
diff --git a/apps/examples/ostest/sighand.c b/apps/examples/ostest/sighand.c
index 63d9590d9..32b182c21 100644
--- a/apps/examples/ostest/sighand.c
+++ b/apps/examples/ostest/sighand.c
@@ -57,7 +57,12 @@ static bool threadexited = false;
#ifdef CONFIG_SCHED_HAVE_PARENT
static void death_of_child(int signo, siginfo_t *info, void *ucontext)
{
- /* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
+ /* Use of printf in a signal handler is NOT safe! It can cause deadlocks!
+ * Also, signals are not queued by NuttX. As a consequence, some
+ * notifications will get lost (or the info data can be overwrittedn)!
+ * Because POSIX does not require signals to be queued, I do not think
+ * that this is a bug (the overwriting is a bug, however).
+ */
if (info)
{
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 921b7014b..7deb9fa94 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -3918,7 +3918,7 @@
the scenario: (1) sched_lock() is called increments the lockcount
on the current TCB (i.e., the one at the head of the ready to run
list), (2) sched_mergepending is called which may change the task
- at the head of the readytorun list, then (2) sched_lock() is called
+ at the head of the readytorun list, then (2) sched_unlock() is called
which decrements the lockcount on the wrong TCB. The failure case
that I saw was that pre-emption got disabled in the IDLE thread,
locking up the whole system.
diff --git a/nuttx/sched/task_deletecurrent.c b/nuttx/sched/task_deletecurrent.c
index 7ecfb26cc..e1e06acf6 100644
--- a/nuttx/sched/task_deletecurrent.c
+++ b/nuttx/sched/task_deletecurrent.c
@@ -115,9 +115,12 @@ int task_deletecurrent(void)
* does not correspond to the thread that is running. Disabling pre-
* emption on this TCB and marking the new ready-to-run task as not
* running (see, for example, get_errno_ptr()).
+ *
+ * We disable pre-emption here by directly incrementing the lockcount
+ * (vs. calling sched_lock()).
*/
- sched_lock();
+ rtcb->lockcount++;
rtcb->task_state = TSTATE_TASK_READYTORUN;
/* Move the TCB to the specified blocked task list and delete it */
@@ -143,7 +146,6 @@ int task_deletecurrent(void)
* the lockcount on rctb.
*/
- DEBUGASSERT(rtcb->lockcount > 0);
rtcb->lockcount--;
return OK;
}
--
cgit v1.2.3
From b3f3dd123c181fe851f0a9756bed7acd4ba4ef7d Mon Sep 17 00:00:00 2001
From: patacongo
Date: Sun, 13 Jan 2013 18:53:00 +0000
Subject: Use SIGCHLD with waitpid(); implemented wait() and waitid()
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5515 42af7a65-404d-4744-a932-0658087f49c3
---
apps/ChangeLog.txt | 3 +-
apps/examples/ostest/Makefile | 4 +
apps/examples/ostest/ostest.h | 42 +++--
apps/examples/ostest/ostest_main.c | 8 +
apps/examples/ostest/waitpid.c | 269 +++++++++++++++++++++++++++++
nuttx/ChangeLog | 7 +
nuttx/Documentation/NuttX.html | 8 +-
nuttx/Documentation/NuttxPortingGuide.html | 10 +-
nuttx/Documentation/NuttxUserGuide.html | 181 +++++++++++++++++--
nuttx/TODO | 13 +-
nuttx/configs/README.txt | 16 +-
nuttx/configs/sim/ostest/defconfig | 2 +-
nuttx/include/nuttx/sched.h | 5 +-
nuttx/include/sys/types.h | 4 +-
nuttx/include/sys/wait.h | 10 +-
nuttx/sched/Kconfig | 14 +-
nuttx/sched/Makefile | 5 +-
nuttx/sched/os_internal.h | 6 +-
nuttx/sched/sched_wait.c | 90 ++++++++++
nuttx/sched/sched_waitid.c | 256 +++++++++++++++++++++++++++
nuttx/sched/sched_waitpid.c | 192 ++++++++++++++++++--
nuttx/sched/task_exithook.c | 24 ++-
nuttx/sched/task_setup.c | 3 +
23 files changed, 1078 insertions(+), 94 deletions(-)
create mode 100644 apps/examples/ostest/waitpid.c
create mode 100644 nuttx/sched/sched_wait.c
create mode 100644 nuttx/sched/sched_waitid.c
(limited to 'nuttx/sched')
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index 65d4d6134..70381a79d 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -464,4 +464,5 @@
* apps/exampes/posix_spawn: Added a test of poxis_spawn().
* apps/examples/ostest: Extend signal handler test to catch
death-of-child signals (SIGCHLD).
-
+ * apps/examples/ostest/waitpid.c: Add a test for waitpid(), waitid(),
+ and wait().
diff --git a/apps/examples/ostest/Makefile b/apps/examples/ostest/Makefile
index b7ba9a9a8..5a8ff7293 100644
--- a/apps/examples/ostest/Makefile
+++ b/apps/examples/ostest/Makefile
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_ARCH_FPU),y)
CSRCS += fpu.c
endif
+ifeq ($(CONFIG_SCHED_WAITPID),y)
+CSRCS += waitpid.c
+endif
+
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
CSRCS += cancel.c cond.c mutex.c sem.c barrier.c
ifneq ($(CONFIG_RR_INTERVAL),0)
diff --git a/apps/examples/ostest/ostest.h b/apps/examples/ostest/ostest.h
index bc46a3860..5217f0a0c 100644
--- a/apps/examples/ostest/ostest.h
+++ b/apps/examples/ostest/ostest.h
@@ -105,68 +105,74 @@
/* dev_null.c ***************************************************************/
-extern int dev_null(void);
+int dev_null(void);
/* fpu.c ********************************************************************/
-extern void fpu_test(void);
+void fpu_test(void);
+
+/* waitpid.c ****************************************************************/
+
+#ifdef CONFIG_SCHED_WAITPID
+int waitpid_test(void);
+#endif
/* mutex.c ******************************************************************/
-extern void mutex_test(void);
+void mutex_test(void);
/* rmutex.c ******************************************************************/
-extern void recursive_mutex_test(void);
+void recursive_mutex_test(void);
/* sem.c ********************************************************************/
-extern void sem_test(void);
+void sem_test(void);
/* cond.c *******************************************************************/
-extern void cond_test(void);
+void cond_test(void);
/* mqueue.c *****************************************************************/
-extern void mqueue_test(void);
+void mqueue_test(void);
/* timedmqueue.c ************************************************************/
-extern void timedmqueue_test(void);
+void timedmqueue_test(void);
/* cancel.c *****************************************************************/
-extern void cancel_test(void);
+void cancel_test(void);
/* timedwait.c **************************************************************/
-extern void timedwait_test(void);
+void timedwait_test(void);
/* sighand.c ****************************************************************/
-extern void sighand_test(void);
+void sighand_test(void);
/* posixtimers.c ************************************************************/
-extern void timer_test(void);
+void timer_test(void);
/* roundrobin.c *************************************************************/
-extern void rr_test(void);
+void rr_test(void);
/* barrier.c ****************************************************************/
-extern void barrier_test(void);
+void barrier_test(void);
/* prioinherit.c ************************************************************/
-extern void priority_inheritance(void);
+void priority_inheritance(void);
/* vfork.c ******************************************************************/
#ifdef CONFIG_ARCH_HAVE_VFORK
-extern int vfork_test(void);
+int vfork_test(void);
#endif
/* APIs exported (conditionally) by the OS specifically for testing of
@@ -174,8 +180,8 @@ extern int vfork_test(void);
*/
#if defined(CONFIG_DEBUG) && defined(CONFIG_PRIORITY_INHERITANCE) && defined(CONFIG_SEM_PHDEBUG)
-extern void sem_enumholders(FAR sem_t *sem);
-extern int sem_nfreeholders(void);
+void sem_enumholders(FAR sem_t *sem);
+int sem_nfreeholders(void);
#else
# define sem_enumholders(sem)
# define sem_nfreeholders()
diff --git a/apps/examples/ostest/ostest_main.c b/apps/examples/ostest/ostest_main.c
index ca44353c3..aab1ff045 100644
--- a/apps/examples/ostest/ostest_main.c
+++ b/apps/examples/ostest/ostest_main.c
@@ -301,6 +301,14 @@ static int user_main(int argc, char *argv[])
check_test_memory_usage();
#endif
+#ifdef CONFIG_SCHED_WAITPID
+ /* Check waitpid() and friends */
+
+ printf("\nuser_main: waitpid test\n");
+ waitpid_test();
+ check_test_memory_usage();
+#endif
+
#ifndef CONFIG_DISABLE_PTHREAD
/* Verify pthreads and pthread mutex */
diff --git a/apps/examples/ostest/waitpid.c b/apps/examples/ostest/waitpid.c
new file mode 100644
index 000000000..e53b49213
--- /dev/null
+++ b/apps/examples/ostest/waitpid.c
@@ -0,0 +1,269 @@
+/****************************************************************************
+ * examples/ostest/waitpid.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "ostest.h"
+
+#ifdef CONFIG_SCHED_WAITPID
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define RETURN_STATUS 14
+#define NCHILDREN 3
+#define PRIORITY 100
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static int g_waitpids[NCHILDREN];
+
+/****************************************************************************
+ * Priviate Functions
+ ****************************************************************************/
+
+static int waitpid_main(int argc, char *argv[])
+{
+ pid_t me = getpid();
+
+ printf("waitpid_main: PID %d Started\n", me);
+ sleep(3);
+ printf("waitpid_main: PID %d exitting with result=%d\n", me, RETURN_STATUS);
+ return RETURN_STATUS;
+}
+
+static void waitpid_start_children(void)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < NCHILDREN; i++)
+ {
+ ret = TASK_CREATE("waitpid", PRIORITY, STACKSIZE, waitpid_main, NULL);
+ if (ret < 0)
+ {
+ printf("waitpid_start_child: ERROR Failed to start user_main\n");
+ }
+ else
+ {
+ printf("waitpid_start_child: Started waitpid_main at PID=%d\n", ret);
+ }
+
+ g_waitpids[i] = ret;
+ }
+}
+
+static void waitpid_last(void)
+{
+ int stat_loc;
+ int ret;
+
+ printf("waitpid_last: Waiting for PID=%d with waitpid()\n",
+ g_waitpids[NCHILDREN-1]);
+
+ ret = (int)waitpid(g_waitpids[NCHILDREN-1], &stat_loc, 0);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_last: ERROR: PID %d waitpid failed: %d\n",
+ g_waitpids[NCHILDREN-1], errcode);
+ }
+ else if (stat_loc != RETURN_STATUS)
+ {
+ printf("waitpid_last: ERROR: PID %d return status is %d, expected %d\n",
+ g_waitpids[NCHILDREN-1], stat_loc, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_last: PID %d waitpid succeeded with stat_loc=%d\n",
+ g_waitpids[NCHILDREN-1], stat_loc);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int waitpid_test(void)
+{
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ siginfo_t info;
+#endif
+ int stat_loc;
+ int ret;
+
+ /* Start the children and wait for first one to complete */
+
+ printf("\nTest waitpid()\n");
+ waitpid_start_children();
+
+ printf("waitpid_test: Waiting for PID=%d with waitpid()\n", g_waitpids[0]);
+ ret = (int)waitpid(g_waitpids[0], &stat_loc, 0);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_test: ERROR: PID %d waitpid failed: %d\n",
+ g_waitpids[0], errcode);
+ }
+ else if (ret != g_waitpids[0])
+ {
+ printf("waitpid_test: ERROR: PID %d wait returned PID %d\n",
+ g_waitpids[0], ret);
+ }
+ else if (stat_loc != RETURN_STATUS)
+ {
+ printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
+ g_waitpids[0], stat_loc, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_test: PID %d waitpid succeeded with stat_loc=%d\n",
+ g_waitpids[0], stat_loc);
+ }
+
+ /* Wait a big to make sure that the other threads complete */
+
+ waitpid_last();
+ sleep(1);
+
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ /* Start the children and wait for first one to complete */
+
+ printf("\nTest waitid(P_PID)\n");
+ waitpid_start_children();
+
+ printf("waitpid_test: Waiting for PID=%d with waitid()\n", g_waitpids[0]);
+ ret = waitid(P_PID, (id_t)g_waitpids[0], &info, WEXITED);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_test: ERROR: PID %d waitid failed: %d\n",
+ g_waitpids[0], errcode);
+ }
+ else if (info.si_pid != g_waitpids[0])
+ {
+ printf("waitpid_test: ERROR: PID %d waitid returned PID %d\n",
+ g_waitpids[0], info.si_pid);
+ }
+ else if (info.si_status != RETURN_STATUS)
+ {
+ printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
+ info.si_pid, info.si_status, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_test: waitid PID %d succeeded with si_status=%d\n",
+ info.si_pid, info.si_status);
+ }
+
+ /* Wait a big to make sure that the other threads complete */
+
+ waitpid_last();
+ sleep(1);
+
+ /* Start the children and wait for any one to complete */
+
+ printf("\nTest waitid(P_ALL)\n");
+ waitpid_start_children();
+
+ printf("waitpid_test: Waiting for any child with waitid()\n");
+ ret = waitid(P_ALL, 0, &info, WEXITED);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_test: ERROR: waitid failed: %d\n", errcode);
+ }
+ else if (info.si_status != RETURN_STATUS)
+ {
+ printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
+ info.si_pid, info.si_status, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_test: PID %d waitid succeeded with si_status=%d\n",
+ info.si_pid, info.si_status);
+ }
+
+ /* Wait a big to make sure that the other threads complete */
+
+ waitpid_last();
+ sleep(1);
+
+ /* Start the children and wait for first one to complete */
+
+ printf("\nTest wait()\n");
+ waitpid_start_children();
+
+ printf("waitpid_test: Waiting for any child with wait()\n");
+ ret = (int)wait(&stat_loc);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_test: ERROR: wait failed: %d\n", errcode);
+ }
+ else if (stat_loc != RETURN_STATUS)
+ {
+ printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
+ ret, stat_loc, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_test: PID %d wait succeeded with stat_loc=%d\n",
+ ret, stat_loc);
+ }
+
+ /* Wait a big to make sure that the other threads complete */
+
+ waitpid_last();
+ sleep(1);
+#endif
+
+ return 0;
+}
+
+#endif /* CONFIG_SCHED_WAITPID */
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 7deb9fa94..e8d4f7309 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -3922,3 +3922,10 @@
which decrements the lockcount on the wrong TCB. The failure case
that I saw was that pre-emption got disabled in the IDLE thread,
locking up the whole system.
+ * sched/sched_waitpid.c: Use SIGCHLD instead of a semaphore. This
+ is a much more spec-compliant implemenation. However, there are
+ some issues with overruning signals because NuttX does not support
+ queueing of signals (POSIX does not require it). I think it may
+ need to.
+ * sched/sched_waitid.c and sched_wait.c: Add support for waitid()
+ and wait(). See issues with waitpid() above.
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index f6e9a41ba..22651de79 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -286,7 +286,7 @@
Easily extensible to new processor architectures, SoC architecture, or board architectures.
- A Porting Guide is available.
+ A Porting Guide is available.
@@ -536,7 +536,7 @@
|
- Power management sub-system.
+ Power management sub-system.
|
@@ -1009,7 +1009,7 @@
This configuration file contains a long list of settings that control
what is built into NuttX and what is not.
There are hundreds of such settings
- (see the NuttX Porting Guide
+ (see the NuttX Porting Guide
for a partial list that excludes platform specific settings).
These many, many configuration options allow NuttX to be highly tuned to
meet size requirements.
@@ -3837,7 +3837,7 @@ pascal-3.0 2011-05-15 Gregory Nutt <gnutt@nuttx.org>
![](favicon.ico) |
- Porting Guide |
+ Porting Guide |
![](favicon.ico) |
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index 0b67eddb7..fec7106b0 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -12,7 +12,7 @@
NuttX RTOS Porting Guide
- Last Updated: January 12, 2013
+ Last Updated: January 13, 2013
@@ -4482,7 +4482,8 @@ build
CONFIG_SCHED_HAVE_PARENT
: Remember the ID of the parent thread when a new child thread is created.
- This support enables a few minor features (such as SIGCHLD
) and slightly increases the size of the Task Control Block (TCB) of every task to hold the ID of the parent thread.
+ This support enables some additional features (such as SIGCHLD
) and modifies the behavior of other interfaces.
+ For example, it makes waitpid()
more standards complete by restricting the waited-for tasks to the children of the caller.
Default: disabled.
@@ -4601,10 +4602,11 @@ build
CONFIG_SCHED_LPWORKPERIOD
: How often the lower priority worker thread checks for work in units of microseconds. Default: 50*1000 (50 MS).
- CONFIG_SCHED_LPWORKSTACKSIZE - The stack size allocated for the lower priority worker thread. Default: CONFIG_IDLETHREAD_STACKSIZE.
+ CONFIG_SCHED_LPWORKSTACKSIZE
: The stack size allocated for the lower priority worker thread. Default: CONFIG_IDLETHREAD_STACKSIZE.
- CONFIG_SCHED_WAITPID
: Enables the waitpid()
API
+ CONFIG_SCHED_WAITPID
: Enables the waitpid()
interface in a default, non-standard mode (non-standard in the sense that the waited for PID need not be child of the caller).
+ If SCHED_HAVE_PARENT
is also defined, then this setting will modify the behavior or waitpid()
(making more spec compliant) and will enable the waitid()
and waitp()
interfaces as well.
CONFIG_SCHED_ATEXIT
: Enables the atexit() API
diff --git a/nuttx/Documentation/NuttxUserGuide.html b/nuttx/Documentation/NuttxUserGuide.html
index c6eabd29a..3cfb63f11 100644
--- a/nuttx/Documentation/NuttxUserGuide.html
+++ b/nuttx/Documentation/NuttxUserGuide.html
@@ -13,7 +13,7 @@
NuttX Operating SystemUser's Manual
by
Gregory Nutt
-
Last Updated: January 11, 2013
+ Last Updated: January 13, 2013
@@ -1776,8 +1776,10 @@ priority of the calling task is returned.
Task synchronization interfaces
@@ -1886,10 +1888,12 @@ on this thread of execution.
Description:
- The following discussion is a general description of the waitpid(
) interface.
- However, as of this writing, the implementation of waitpid()
is fragmentary (but usable).
- It simply supports waiting for any task to complete execution.
- NuttX does not support any concept of parent/child processes or of process groups nor signals related to child processes (SIGCHLD
).
+ The following discussion is a general description of the waitpid()
interface.
+ However, as of this writing, the implementation of waitpid()
is incomplete (but usable).
+ If CONFIG_SCHED_HAVE_PARENT
is defined, waitpid()
will be a little more compliant to specifications.
+ Without CONFIG_SCHED_HAVE_PARENT
, waitpid()
simply supports waiting for any task to complete execution.
+ With CONFIG_SCHED_HAVE_PARENT
, waitpid()
will use SIGCHLD
and can, therefore, wait for any child of the parent to complete.
+ The implementation is incomplete in either case, however: NuttX does not support any concept of process groups.
Nor does NuttX retain the status of exited tasks so if waitpid()
is called after a task has exited, then no status will be available.
The options argument is currently ignored.
@@ -2038,7 +2042,158 @@ on this thread of execution.
Comparable to the POSIX interface of the same name, but the implementation is incomplete (as detailed above).
-
+
+
+Function Prototype:
+
+ #include <sys/wait.h>
+ #ifdef CONFIG_SCHED_HAVE_PARENT
+ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options);
+ #endif
+
+
+ Description:
+
+
+ The following discussion is a general description of the waitid()
interface.
+ However, as of this writing, the implementation of waitid()
is incomplete (but usable).
+ If CONFIG_SCHED_HAVE_PARENT
is defined, waitid()
will be a little more compliant to specifications.
+ waitpid()
simply supports waiting a specific child task (P_PID
or for any child task P_ALL
to complete execution.
+ SIGCHLD
is used.
+ The implementation is incomplete in either case, however: NuttX does not support any concept of process groups.
+ Nor does NuttX retain the status of exited tasks so if waitpid()
is called after a task has exited, then no status will be available.
+ The options argument is currently ignored.
+
+
+ The waitid()
function suspends the calling thread until one child of the process containing the calling thread changes state.
+ It records the current state of a child in the structure pointed to by info
.
+ If a child process changed state prior to the call to waitid()
, waitid()
returns immediately.
+ If more than one thread is suspended in wait()
or waitpid()
waiting termination of the same process, exactly one thread will return the process status at the time of the target process termination
+
+
+ The idtype
and id
arguments are used to specify which children waitid()
will wait for.
+
+
+
+ -
+ If
idtype
is P_PID, waitid()
will wait for the child with a process ID equal to (pid_t)id
.
+
+ -
+ If
idtype
is P_PGID, waitid()
will wait for any child with a process group ID equal to (pid_t)id
.
+
+ -
+ If
idtype
is P_ALL, waitid()
will wait for any children and id
is ignored.
+
+
+ The options
argument is used to specify which state changes waitid()
will will wait for.
+ It is formed by OR-ing together one or more of the following flags:
+
+
+ -
+
WEXITED
:
+ Wait for processes that have exited.
+
+ -
+
WSTOPPED
:
+ Status will be returned for any child that has stopped upon receipt of a signal.
+
+ -
+
WCONTINUES
:
+ Status will be returned for any child that was stopped and has been continued.
+
+ -
+
WNOHANG
:
+ Return immediately if there are no children to wait for.
+
+ -
+
WNOWAIT
:
+ Keep the process whose status is returned in info
in a waitable state.
+ This will not affect the state of the process;
+ the process may be waited for again after this call completes.
+
+
+ The info
argument must point to a siginfo_t
structure.
+ If waitid()
returns because a child process was found that satisfied the conditions indicated by the arguments idtype
and options, then the structure pointed to by info
will be filled in by the system with the status of the process.
+ The si_signo
member will always be equal to SIGCHLD
.
+
+
+ Input Parameters:
+ See the description above.
+
+
+ Returned Value:
+ If waitid()
returns due to the change of state of one of its children, 0 is returned.
+ Otherwise, -1 is returned and errno
is set to indicate the error.
+
+
+ The waitid()
function will fail if:
+
+
+ -
+
ECHILD
:
+
+ The calling process has no existing unwaited-for child processes.
+ -
+
EINTR
:
+
+ The waitid()
function was interrupted by a signal.
+ -
+
EINVAL
:
+ An invalid value was specified for options
, or idtype
and id
specify an invalid set of processes.
+
+
+
+ Assumptions/Limitations:
+
+ POSIX Compatibility:
+ Comparable to the POSIX interface of the same name, but the implementation is incomplete (as detailed in the description above).
+
+
+
+
+Function Prototype:
+
+ #include <sys/wait.h>
+ #ifdef CONFIG_SCHED_HAVE_PARENT
+ pid_t wait(FAR int *stat_loc);
+ #endif
+
+
+ Description:
+
+
+ The following discussion is a general description of the wait()
interface.
+ However, as of this writing, the implementation of wait()
is incomplete (but usable).
+ wait()
is based on waitpaid()
.
+ See the description of waitpaid()
for further information.
+
+
+ The wait()
function will suspend execution of the calling thread until status information for one of its terminated child processes is available, or until delivery of a signal whose action is either to execute a signal-catching function or to terminate the process.
+ If more than one thread is suspended in wait()
awaiting termination of the same process, exactly one thread will return the process status at the time of the target process termination.
+ If status information is available prior to the call towait()
, return will be immediate.
+
+
+ The waitpid()
function will behave identically to wait()
, if its pid
argument is (pid_t)-1 and the options argument is 0.
+ Otherwise, its behavior will be modified by the values of the pid
and options
arguments.
+
+
+ Input Parameters:
+
+
+ stat_loc
. The location to return the exit status
+
+
+ Returned Value:
+ See the values returned by waitpaid()
.
+
+
+ Assumptions/Limitations:
+
+ POSIX Compatibility:
+ Comparable to the POSIX interface of the same name, but the implementation is incomplete (as detailed in the description waitpaid()
).
+
+
+
Function Prototype:
@@ -2077,7 +2232,7 @@ on this thread of execution.
atexit()
functions are not inherited when a new task is created.
-
+
Function Prototype:
@@ -9023,9 +9178,9 @@ notify a task when a message is available on a queue.
pipe
poll
poll.h
+ posix_spawn
- posix_spawn
posix_spawn_file_actions_addclose
posix_spawn_file_actions_adddup2
posix_spawn_file_actions_addopen
@@ -9107,10 +9262,10 @@ notify a task when a message is available on a queue.
recv
recvfrom
rename
- |
-
rmdir
rewinddir
+ |
+
ROM disk driver
ROMFS
sched_getparam
@@ -9183,6 +9338,8 @@ notify a task when a message is available on a queue.
vfprintf
vprintf
vsprintf
+ wait
+ waitid
waitpid
Watchdog Timer Interfaces
wd_cancel
diff --git a/nuttx/TODO b/nuttx/TODO
index 92b7ab4f5..88324c06b 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -6,7 +6,7 @@ standards, things that could be improved, and ideas for enhancements.
nuttx/
- (11) Task/Scheduler (sched/)
+ (10) Task/Scheduler (sched/)
(1) Memory Managment (mm/)
(2) Signals (sched/, arch/)
(2) pthreads (sched/)
@@ -58,17 +58,6 @@ o Task/Scheduler (sched/)
Status: Closed. No, this behavior will not be implemented.
Priority: Medium, required for good emulation of process/pthread model.
- Title: WAIT.H
- Description: Implement sys/wait.h and functions. Consider implementing wait,
- waitpid, waitid. At present, a parent has no information about
- child tasks.
-
- Update: A simple but usable version of waitpid() has been included.
- This version is not compliant with all specifications and can be
- enabled with CONFIG_SCHED_WAITPID.
- Status: Open, however no further work is planned.
- Priority: Low
-
Title: MISSING ERRNO SETTINGS
Description: Several APIs do not set errno. Need to review all APIs.
Update: These are being fixed as they are encountered. There is
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index 2724cf5a3..4800f02ee 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -335,10 +335,11 @@ defconfig -- This is a configuration file similar to the Linux
task name to save in the TCB. Useful if scheduler
instrumentation is selected. Set to zero to disable.
CONFIG_SCHED_HAVE_PARENT - Remember the ID of the parent thread
- when a new child thread is created. This support enables a
- few minor features (such as SIGCHLD) and slightly increases
- the size of the Task Control Block (TCB) of every task to hold
- the ID of the parent thread. Default: disabled.
+ when a new child thread is created. This support enables some
+ additional features (such as SIGCHLD) and modifies the behavior
+ of other interfaces. For example, it makes waitpid() more
+ standards complete by restricting the waited-for tasks to the
+ children of the caller. Default: disabled.
CONFIG_START_YEAR, CONFIG_START_MONTH, CONFIG_START_DAY -
Used to initialize the internal time logic.
CONFIG_GREGORIAN_TIME - Enables Gregorian time conversions.
@@ -417,7 +418,12 @@ defconfig -- This is a configuration file similar to the Linux
checks for work in units of microseconds. Default: 50*1000 (50 MS).
CONFIG_SCHED_LPWORKSTACKSIZE - The stack size allocated for the lower
priority worker thread. Default: CONFIG_IDLETHREAD_STACKSIZE.
- CONFIG_SCHED_WAITPID - Enables the waitpid() API
+ CONFIG_SCHED_WAITPID - Enables the waitpid() interface in a default,
+ non-standard mode (non-standard in the sense that the waited for
+ PID need not be child of the caller). If SCHED_HAVE_PARENT is
+ also defined, then this setting will modify the behavior or
+ waitpid() (making more spec compliant) and will enable the
+ waitid() and wait() interfaces as well.
CONFIG_SCHED_ATEXIT - Enables the atexit() API
CONFIG_SCHED_ATEXIT_MAX - By default if CONFIG_SCHED_ATEXIT is
selected, only a single atexit() function is supported. That number
diff --git a/nuttx/configs/sim/ostest/defconfig b/nuttx/configs/sim/ostest/defconfig
index 5cea9a6d4..c8d5c501d 100644
--- a/nuttx/configs/sim/ostest/defconfig
+++ b/nuttx/configs/sim/ostest/defconfig
@@ -143,7 +143,7 @@ CONFIG_MUTEX_TYPES=y
# CONFIG_FDCLONE_STDIO is not set
CONFIG_SDCLONE_DISABLE=y
# CONFIG_SCHED_WORKQUEUE is not set
-# CONFIG_SCHED_WAITPID is not set
+CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_ATEXIT is not set
# CONFIG_SCHED_ONEXIT is not set
CONFIG_USER_ENTRYPOINT="ostest_main"
diff --git a/nuttx/include/nuttx/sched.h b/nuttx/include/nuttx/sched.h
index 6c67e1500..b2ec1cee4 100644
--- a/nuttx/include/nuttx/sched.h
+++ b/nuttx/include/nuttx/sched.h
@@ -1,7 +1,7 @@
/********************************************************************************
* include/nuttx/sched.h
*
- * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -204,6 +204,7 @@ struct _TCB
pid_t pid; /* This is the ID of the thread */
#ifdef CONFIG_SCHED_HAVE_PARENT
pid_t parent; /* This is the ID of the parent thread */
+ uint16_t nchildren; /* This is the number active children */
#endif
start_t start; /* Thread start function */
entry_t entry; /* Entry Point into the thread */
@@ -226,7 +227,7 @@ struct _TCB
# endif
#endif
-#ifdef CONFIG_SCHED_WAITPID
+#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
sem_t exitsem; /* Support for waitpid */
int *stat_loc; /* Location to return exit status */
#endif
diff --git a/nuttx/include/sys/types.h b/nuttx/include/sys/types.h
index 2ae69d4a7..95feee72e 100644
--- a/nuttx/include/sys/types.h
+++ b/nuttx/include/sys/types.h
@@ -154,7 +154,9 @@ typedef uint16_t dev_t;
typedef uint16_t ino_t;
-/* pid_t is used for process IDs and process group IDs */
+/* pid_t is used for process IDs and process group IDs. It must be signed because
+ * negative PID values are used to represent invalid PIDs.
+ */
typedef int pid_t;
diff --git a/nuttx/include/sys/wait.h b/nuttx/include/sys/wait.h
index 6af1e971e..2476adef9 100644
--- a/nuttx/include/sys/wait.h
+++ b/nuttx/include/sys/wait.h
@@ -1,7 +1,7 @@
/****************************************************************************
* include/sys/wait.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,7 @@
#define WTERMSIG(s) (false) /* Return signal number that caused process to terminate */
/* The following symbolic constants are possible values for the options
- * argument to waitpi(1) (1) and/or waitid() (2),
+ * argument to waitpid() (1) and/or waitid() (2),
*/
#define WCONTINUED (1 << 0) /* Status for child that has been continued (1)(2) */
@@ -104,9 +104,9 @@ extern "C" {
#define EXTERN extern
#endif
-EXTERN pid_t wait(int *stat_loc);
-EXTERN int waitid(idtype_t idtype, id_t id, siginfo_t *siginfo, int options);
-EXTERN pid_t waitpid(pid_t pid, int *stat_loc, int options);
+EXTERN pid_t wait(FAR int *stat_loc);
+EXTERN int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options);
+EXTERN pid_t waitpid(pid_t pid, FAR int *stat_loc, int options);
#undef EXTERN
#if defined(__cplusplus)
diff --git a/nuttx/sched/Kconfig b/nuttx/sched/Kconfig
index 69621a1fa..6d53a03aa 100644
--- a/nuttx/sched/Kconfig
+++ b/nuttx/sched/Kconfig
@@ -43,9 +43,10 @@ config SCHED_HAVE_PARENT
default n
---help---
Remember the ID of the parent thread when a new child thread is
- created. This support enables a few minor features (such as
- SIGCHLD) and slightly increases the size of the Task Control Block
- (TCB) of every task to hold the ID of the parent thread. Default:
+ created. This support enables some additional features (such as
+ SIGCHLD) and modifies the behavior of other interfaces. For
+ example, it makes waitpid() more standards complete by restricting
+ the waited-for tasks to the children of the caller. Default:
disabled.
config JULIAN_TIME
@@ -206,7 +207,12 @@ config SCHED_WAITPID
bool "Enable waitpid() API"
default n
---help---
- Enables the waitpid() API
+ Enables the waitpid() interface in a default, non-standard mode
+ (non-standard in the sense that the waited for PID need not be child
+ of the caller). If SCHED_HAVE_PARENT is also defined, then this
+ setting will modify the behavior or waitpid() (making more spec
+ compliant) and will enable the waitid() and wait() interfaces as
+ well.
config SCHED_ATEXIT
bool "Enable atexit() API"
diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile
index 23d1e9938..3d6b58bac 100644
--- a/nuttx/sched/Makefile
+++ b/nuttx/sched/Makefile
@@ -1,7 +1,7 @@
############################################################################
# sched/Makefile
#
-# Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+# Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt
#
# Redistribution and use in source and binary forms, with or without
@@ -69,6 +69,9 @@ endif
ifeq ($(CONFIG_SCHED_WAITPID),y)
SCHED_SRCS += sched_waitpid.c
+ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
+SCHED_SRCS += sched_waitid.c sched_wait.c
+endif
endif
ENV_SRCS = env_getenvironptr.c env_dup.c env_share.c env_release.c \
diff --git a/nuttx/sched/os_internal.h b/nuttx/sched/os_internal.h
index 13b8083cf..32d9fb4ac 100644
--- a/nuttx/sched/os_internal.h
+++ b/nuttx/sched/os_internal.h
@@ -83,10 +83,10 @@ enum os_crash_codes_e
OSERR_BADREPRIORITIZESTATE /* Attempt to reprioritize in bad state or priority */
};
-/* Special task IDS */
+/* Special task IDS. Any negative PID is invalid. */
-#define NULL_TASK_PROCESS_ID 0
-#define INVALID_PROCESS_ID 0
+#define NULL_TASK_PROCESS_ID (pid_t)0
+#define INVALID_PROCESS_ID (pid_t)-1
/* Although task IDs can take the (positive, non-zero)
* range of pid_t, the number of tasks that will be supported
diff --git a/nuttx/sched/sched_wait.c b/nuttx/sched/sched_wait.c
new file mode 100644
index 000000000..813d4f842
--- /dev/null
+++ b/nuttx/sched/sched_wait.c
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * sched/sched_wait.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Included Files
+ *****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include "os_internal.h"
+
+#if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)
+
+/*****************************************************************************
+ * Private Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Public Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Name: wait
+ *
+ * Description:
+ * The wait() function will suspend execution of the calling thread until
+ * status information for one of its terminated child processes is
+ * available, or until delivery of a signal whose action is either to
+ * execute a signal-catching function or to terminate the process. If more
+ * than one thread is suspended in wait() or waitpid() awaiting termination
+ * of the same process, exactly one thread will return the process status
+ * at the time of the target process termination. If status information is
+ * available prior to the call to wait(), return will be immediate.
+ *
+ * The waitpid() function will behave identically to wait(), if the pid
+ * argument is (pid_t)-1 and the options argument is 0. Otherwise, its
+ * behaviour will be modified by the values of the pid and options arguments.
+ *
+ * Input Parameters:
+ * stat_loc - The location to return the exit status
+ *
+ * Returned Value:
+ * See waitpid();
+ *
+ *****************************************************************************/
+
+pid_t wait(FAR int *stat_loc)
+{
+ return waitpid((pid_t)-1, stat_loc, 0);
+}
+
+#endif /* CONFIG_SCHED_WAITPID && CONFIG_SCHED_HAVE_PARENT*/
diff --git a/nuttx/sched/sched_waitid.c b/nuttx/sched/sched_waitid.c
new file mode 100644
index 000000000..eabc69afe
--- /dev/null
+++ b/nuttx/sched/sched_waitid.c
@@ -0,0 +1,256 @@
+/*****************************************************************************
+ * sched/sched_waitid.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Included Files
+ *****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include "os_internal.h"
+
+#if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)
+
+/*****************************************************************************
+ * Private Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Public Functions
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Name: waitid
+ *
+ * Description:
+ * The waitid() function suspends the calling thread until one child of
+ * the process containing the calling thread changes state. It records the
+ * current state of a child in the structure pointed to by 'info'. If a
+ * child process changed state prior to the call to waitid(), waitid()
+ * returns immediately. If more than one thread is suspended in wait() or
+ * waitpid() waiting termination of the same process, exactly one thread
+ * will return the process status at the time of the target process
+ * termination
+ *
+ * The idtype and id arguments are used to specify which children waitid()
+ * will wait for.
+ *
+ * If idtype is P_PID, waitid() will wait for the child with a process
+ * ID equal to (pid_t)id.
+ *
+ * If idtype is P_PGID, waitid() will wait for any child with a process
+ * group ID equal to (pid_t)id.
+ *
+ * If idtype is P_ALL, waitid() will wait for any children and id is
+ * ignored.
+ *
+ * The options argument is used to specify which state changes waitid()
+ * will will wait for. It is formed by OR-ing together one or more of the
+ * following flags:
+ *
+ * WEXITED - Wait for processes that have exited.
+ * WSTOPPED - Status will be returned for any child that has stopped
+ * upon receipt of a signal.
+ * WCONTINUED - Status will be returned for any child that was stopped
+ * and has been continued.
+ * WNOHANG - Return immediately if there are no children to wait for.
+ * WNOWAIT - Keep the process whose status is returned in 'info' in a
+ * waitable state. This will not affect the state of the process; the
+ * process may be waited for again after this call completes.
+ *
+ * The 'info' argument must point to a siginfo_t structure. If waitid()
+ * returns because a child process was found that satisfied the conditions
+ * indicated by the arguments idtype and options, then the structure pointed
+ * to by 'info' will be filled in by the system with the status of the
+ * process. The si_signo member will always be equal to SIGCHLD.
+ *
+ * Input Parameters:
+ * See description.
+ *
+ * Returned Value:
+ * If waitid() returns due to the change of state of one of its children,
+ * 0 is returned. Otherwise, -1 is returned and errno is set to indicate
+ * the error.
+ *
+ * The waitid() function will fail if:
+ *
+ * ECHILD - The calling process has no existing unwaited-for child
+ * processes.
+ * EINTR - The waitid() function was interrupted by a signal.
+ * EINVAL - An invalid value was specified for options, or idtype and id
+ * specify an invalid set of processes.
+ *
+ *****************************************************************************/
+
+int waitid(idtype_t idtype, id_t id, siginfo_t *info, int options)
+{
+ FAR _TCB *rtcb = (FAR _TCB *)g_readytorun.head;
+ sigset_t sigset;
+ int err;
+ int ret;
+
+ /* MISSING LOGIC: If WNOHANG is provided in the options, then this function
+ * should returned immediately. However, there is no mechanism available now
+ * know if the thread has child: The children remember their parents (if
+ * CONFIG_SCHED_HAVE_PARENT) but the parents do not remember their children.
+ */
+
+ /* None of the options are supported except for WEXITED (which must be
+ * provided. Currently SIGCHILD always reports CLD_EXITED so we cannot
+ * distinguish any other events.
+ */
+
+#ifdef CONFIG_DEBUG
+ if (options != WEXITED)
+ {
+ set_errno(ENOSYS);
+ return ERROR;
+ }
+#endif
+
+ /* Create a signal set that contains only SIGCHLD */
+
+ (void)sigemptyset(&sigset);
+ (void)sigaddset(&sigset, SIGCHLD);
+
+ /* Disable pre-emption so that nothing changes while the loop executes */
+
+ sched_lock();
+
+ /* Verify that this task actually has children and that the the requeste
+ * TCB is actually a child of this task.
+ */
+
+ if (rtcb->nchildren == 0)
+ {
+ err = ECHILD;
+ goto errout_with_errno;
+ }
+ else if (idtype == P_PID)
+ {
+ /* Get the TCB corresponding to this PID and make sure it is our child. */
+
+ FAR _TCB *ctcb = sched_gettcb((pid_t)id);
+ if (!ctcb || ctcb->parent != rtcb->pid)
+ {
+ err = ECHILD;
+ goto errout_with_errno;
+ }
+ }
+
+ /* Loop until the child that we are waiting for dies */
+
+ for (;;)
+ {
+ /* Check if the task has already died. Signals are not queued in
+ * NuttX. So a possibility is that the child has died and we
+ * missed the death of child signal (we got some other signal
+ * instead).
+ */
+
+ if (rtcb->nchildren == 0 ||
+ (idtype == P_PID && (ret = kill((pid_t)id, 0)) < 0))
+ {
+ /* We know that the child task was running okay we stared,
+ * so we must have lost the signal. What can we do?
+ * Let's claim we were interrupted by a signal.
+ */
+
+ err = EINTR;
+ goto errout_with_errno;
+ }
+
+ /* Wait for any death-of-child signal */
+
+ ret = sigwaitinfo(&sigset, info);
+ if (ret < 0)
+ {
+ goto errout;
+ }
+
+ /* Make there this was SIGCHLD */
+
+ if (info->si_signo == SIGCHLD)
+ {
+ /* Yes.. Are we waiting for the death of a specific child? */
+
+ if (idtype == P_PID)
+ {
+ /* Was this the death of the thread we were waiting for? */
+
+ if (info->si_pid == (pid_t)id)
+ {
+ /* Yes... return success */
+
+ break;
+ }
+ }
+
+ /* Are we waiting for any child to change state? */
+
+ else if (idtype == P_ALL)
+ {
+ /* Return success */
+
+ break;
+ }
+
+ /* Other ID types are not supported */
+
+ else /* if (idtype == P_PGID) */
+ {
+ set_errno(ENOSYS);
+ goto errout;
+ }
+ }
+ }
+
+ sched_unlock();
+ return OK;
+
+errout_with_errno:
+ set_errno(err);
+errout:
+ sched_unlock();
+ return ERROR;
+}
+
+#endif /* CONFIG_SCHED_WAITPID && CONFIG_SCHED_HAVE_PARENT*/
diff --git a/nuttx/sched/sched_waitpid.c b/nuttx/sched/sched_waitpid.c
index 692ef6410..dc715b2e9 100644
--- a/nuttx/sched/sched_waitpid.c
+++ b/nuttx/sched/sched_waitpid.c
@@ -1,7 +1,7 @@
/*****************************************************************************
* sched/sched_waitpid.c
*
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -41,13 +41,14 @@
#include
#include
+#include
#include
#include
#include "os_internal.h"
-#ifdef CONFIG_SCHED_WAITPID /* Experimental */
+#ifdef CONFIG_SCHED_WAITPID
/*****************************************************************************
* Private Functions
@@ -58,7 +59,7 @@
*****************************************************************************/
/*****************************************************************************
- * Name: sched_waitpid
+ * Name: waitpid
*
* Description:
*
@@ -172,10 +173,16 @@
*
*****************************************************************************/
-/***************************************************************************/
-/* NOTE: This is a partially functional, experimental version of waitpid() */
-/***************************************************************************/
+/***************************************************************************
+ * NOTE: This is a partially functional, experimental version of waitpid()
+ *
+ * If there is no SIGCHLD signal supported (CONFIG_SCHED_HAVE_PARENT not
+ * defined), then waitpid() is still available, but does not obey the
+ * restriction that the pid be a child of the caller.
+ *
+ ***************************************************************************/
+#ifndef CONFIG_SCHED_HAVE_PARENT
pid_t waitpid(pid_t pid, int *stat_loc, int options)
{
_TCB *tcb;
@@ -183,9 +190,24 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
int err;
int ret;
+ DEBUGASSERT(stat_loc);
+
+ /* None of the options are supported */
+
+#ifdef CONFIG_DEBUG
+ if (options != 0)
+ {
+ set_errno(ENOSYS);
+ return ERROR;
+ }
+#endif
+
/* Disable pre-emption so that nothing changes in the following tests */
sched_lock();
+
+ /* Get the TCB corresponding to this PID */
+
tcb = sched_gettcb(pid);
if (!tcb)
{
@@ -193,16 +215,6 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
goto errout_with_errno;
}
- /* None of the options are supported */
-
-#ifdef CONFIG_DEBUG
- if (options != 0)
- {
- err = ENOSYS;
- goto errout_with_errno;
- }
-#endif
-
/* "If more than one thread is suspended in waitpid() awaiting termination of
* the same process, exactly one thread will return the process status at the
* time of the target process termination." Hmmm.. what do we return to the
@@ -245,4 +257,152 @@ errout:
return ERROR;
}
+/***************************************************************************
+ *
+ * If CONFIG_SCHED_HAVE_PARENT is defined, then waitpid will use the SIGHCLD
+ * signal. It can also handle the pid == (pid_t)-1 arguement. This is
+ * slightly more spec-compliant.
+ *
+ * But then I have to be concerned about the fact that NuttX does not queue
+ * signals. This means that a flurry of signals can cause signals to be
+ * lost (or to have the data in the struct siginfo to be overwritten by
+ * the next signal).
+ *
+ ***************************************************************************/
+
+#else
+pid_t waitpid(pid_t pid, int *stat_loc, int options)
+{
+ FAR _TCB *rtcb = (FAR _TCB *)g_readytorun.head;
+ FAR struct siginfo info;
+ sigset_t sigset;
+ int err;
+ int ret;
+
+ DEBUGASSERT(stat_loc);
+
+ /* None of the options are supported */
+
+#ifdef CONFIG_DEBUG
+ if (options != 0)
+ {
+ set_errno(ENOSYS);
+ return ERROR;
+ }
+#endif
+
+ /* Create a signal set that contains only SIGCHLD */
+
+ (void)sigemptyset(&sigset);
+ (void)sigaddset(&sigset, SIGCHLD);
+
+ /* Disable pre-emption so that nothing changes while the loop executes */
+
+ sched_lock();
+
+ /* Verify that this task actually has children and that the the requeste
+ * TCB is actually a child of this task.
+ */
+
+ if (rtcb->nchildren == 0)
+ {
+ err = ECHILD;
+ goto errout_with_errno;
+ }
+ else if (pid != (pid_t)-1)
+ {
+ /* Get the TCB corresponding to this PID and make sure it is our child. */
+
+ FAR _TCB *ctcb = sched_gettcb(pid);
+ if (!ctcb || ctcb->parent != rtcb->pid)
+ {
+ err = ECHILD;
+ goto errout_with_errno;
+ }
+ }
+
+ /* Loop until the child that we are waiting for dies */
+
+ for (;;)
+ {
+ /* Check if the task has already died. Signals are not queued in
+ * NuttX. So a possibility is that the child has died and we
+ * missed the death of child signal (we got some other signal
+ * instead).
+ */
+
+ if (pid == (pid_t)-1)
+ {
+ /* We are waiting for any child, check if there are still
+ * chilren.
+ */
+
+ if (rtcb->nchildren == 0)
+ {
+ /* There were one or more children when we started so they
+ * must have exit'ed. There are just no bread crumbs left
+ * behind to tell us the PID(s) of the existed children.
+ * Reporting ECHLD is about all we can do in this case.
+ */
+
+ err = ECHILD;
+ goto errout_with_errno;
+ }
+ }
+ else
+ {
+ /* We are waiting for a specific PID. We can use kill() with
+ * signal number 0 to determine if that task is still alive.
+ */
+
+ ret = kill(pid, 0);
+ if (ret < 0)
+ {
+ /* It is no longer running. We know that the child task was
+ * running okay when we started, so we must have lost the
+ * signal. In this case, we know that the task exit'ed, but
+ * we do not know its exit status. It would be better to
+ * reported ECHILD that bogus status.
+ */
+
+ err = ECHILD;
+ goto errout_with_errno;
+ }
+ }
+
+ /* Wait for any death-of-child signal */
+
+ ret = sigwaitinfo(&sigset, &info);
+ if (ret < 0)
+ {
+ goto errout_with_lock;
+ }
+
+ /* Was this the death of the thread we were waiting for? In the of
+ * pid == (pid_t)-1, we are waiting for any child thread.
+ */
+
+ if (info.si_signo == SIGCHLD &&
+ (pid == (pid_t)-1 || info.si_pid == pid))
+ {
+ /* Yes... return the status and PID (in the event it was -1) */
+
+ *stat_loc = info.si_status;
+ pid = info.si_pid;
+ break;
+ }
+ }
+
+ sched_unlock();
+ return (int)pid;
+
+errout_with_errno:
+ set_errno(err);
+
+errout_with_lock:
+ sched_unlock();
+ return ERROR;
+}
+#endif /* CONFIG_SCHED_HAVE_PARENT */
+
#endif /* CONFIG_SCHED_WAITPID */
diff --git a/nuttx/sched/task_exithook.c b/nuttx/sched/task_exithook.c
index 9ce2e5899..1106f2885 100644
--- a/nuttx/sched/task_exithook.c
+++ b/nuttx/sched/task_exithook.c
@@ -217,6 +217,20 @@ static inline void task_sigchild(FAR _TCB *tcb, int status)
return;
}
+ /* Decrement the number of children from this parent */
+
+ DEBUGASSERT(ptcb->nchildren > 0);
+ ptcb->nchildren--;
+
+ /* Set the parent to an impossible PID. We do this because under certain
+ * conditions, task_exithook() can be called multiple times. If this
+ * function is called again, sched_gettcb() will fail on the invalid
+ * parent PID above, nchildren will be decremented once and all will be
+ * well.
+ */
+
+ tcb->parent = INVALID_PROCESS_ID;
+
/* Create the siginfo structure. We don't actually know the cause. That
* is a bug. Let's just say that the child task just exit-ted for now.
*/
@@ -246,7 +260,7 @@ static inline void task_sigchild(FAR _TCB *tcb, int status)
*
****************************************************************************/
-#ifdef CONFIG_SCHED_WAITPID
+#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
static inline void task_exitwakeup(FAR _TCB *tcb, int status)
{
/* Wakeup any tasks waiting for this task to exit */
@@ -310,14 +324,14 @@ void task_exithook(FAR _TCB *tcb, int status)
task_atexit(tcb);
- /* Send SIGCHLD to the parent of the exiting task */
-
- task_sigchild(tcb, status);
-
/* Call any registered on_exit function(s) */
task_onexit(tcb, status);
+ /* Send SIGCHLD to the parent of the exit-ing task */
+
+ task_sigchild(tcb, status);
+
/* Wakeup any tasks waiting for this task to exit */
task_exitwakeup(tcb, status);
diff --git a/nuttx/sched/task_setup.c b/nuttx/sched/task_setup.c
index c5dd8ca3a..92897f0ae 100644
--- a/nuttx/sched/task_setup.c
+++ b/nuttx/sched/task_setup.c
@@ -168,7 +168,10 @@ static int task_assignpid(FAR _TCB *tcb)
static inline void task_saveparent(FAR _TCB *tcb)
{
FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
+
+ DEBUGASSERT(rtcb->nchildren < UINT16_MAX);
tcb->parent = rtcb->pid;
+ rtcb->nchildren++;
}
#else
# define task_saveparent(tcb)
--
cgit v1.2.3
From cc3614dfe8f67033dca8c7c1f40c3367a0d3ca06 Mon Sep 17 00:00:00 2001
From: patacongo
Date: Mon, 14 Jan 2013 19:22:32 +0000
Subject: Finish dup logic for open files; fix bug in sigtimedwait(), would
return wrong signo value if the signal was already pending
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5517 42af7a65-404d-4744-a932-0658087f49c3
---
apps/builtin/Kconfig | 15 +++++
apps/builtin/binfs.c | 37 ++++++++++-
nuttx/ChangeLog | 9 +++
nuttx/TODO | 24 +-------
nuttx/fs/fat/fs_fat32.c | 126 +++++++++++++++++++++++++++++++++++++-
nuttx/fs/fat/fs_fat32.h | 1 -
nuttx/fs/fat/fs_fat32util.c | 10 +--
nuttx/fs/nfs/nfs_node.h | 3 +-
nuttx/fs/nfs/nfs_util.c | 9 +--
nuttx/fs/nfs/nfs_vfsops.c | 106 ++++++++++++++++++++++++++++----
nuttx/fs/nfs/rpc_clnt.c | 28 ++++-----
nuttx/fs/nxffs/nxffs.h | 41 +++++++------
nuttx/fs/nxffs/nxffs_initialize.c | 4 +-
nuttx/fs/nxffs/nxffs_open.c | 62 ++++++++++++++++++-
nuttx/fs/romfs/fs_romfs.c | 2 +-
nuttx/include/nuttx/fs/fs.h | 2 +-
nuttx/sched/mq_initialize.c | 4 +-
nuttx/sched/sig_timedwait.c | 2 +-
nuttx/sched/task_vfork.c | 2 +-
19 files changed, 384 insertions(+), 103 deletions(-)
(limited to 'nuttx/sched')
diff --git a/apps/builtin/Kconfig b/apps/builtin/Kconfig
index 8310e6df9..5b262734d 100644
--- a/apps/builtin/Kconfig
+++ b/apps/builtin/Kconfig
@@ -12,4 +12,19 @@ config BUILTIN
to support built-in applications in the NuttShell (NSH).
if BUILTIN
+
+ config APPS_BINDIR
+ bool "BINFS File System"
+ default n
+ ---help---
+ The BINFS file system is current just a toy. The BINFS may, for example,
+ be mount at /bin. Then all of the built-in applications will appear as
+ executable file in /bin if you list them from NSH like:
+
+ nsh> ls -l /bin
+
+ At present, the BINFS supports nothing more than that. It is planned,
+ however, to support execution of the builtin applications from BINFS as
+ well (via a binfmt/ loader). However, that is down the road.
+
endif
diff --git a/apps/builtin/binfs.c b/apps/builtin/binfs.c
index 4159c9663..365021c7f 100644
--- a/apps/builtin/binfs.c
+++ b/apps/builtin/binfs.c
@@ -85,6 +85,8 @@ static int binfs_close(FAR struct file *filep);
static ssize_t binfs_read(FAR struct file *filep, char *buffer, size_t buflen);
static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+static int binfs_dup(FAR const struct file *oldp, FAR struct file *newp);
+
static int binfs_opendir(struct inode *mountpt, const char *relpath,
struct fs_dirent_s *dir);
static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir);
@@ -120,7 +122,7 @@ const struct mountpt_operations binfs_operations =
binfs_ioctl, /* ioctl */
NULL, /* sync */
- NULL, /* dup */
+ binfs_dup, /* dup */
binfs_opendir, /* opendir */
NULL, /* closedir */
@@ -296,6 +298,39 @@ static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
return -ENOTTY;
}
+/****************************************************************************
+ * Name: binfs_dup
+ *
+ * Description:
+ * Duplicate open file data in the new file structure.
+ *
+ ****************************************************************************/
+
+static int binfs_dup(FAR const struct file *oldp, FAR struct file *newp)
+{
+ struct binfs_state_s *bm;
+ int ret = -ENOSYS;
+
+ fvdbg("Dup %p->%p\n", oldp, newp);
+
+ /* Sanity checks */
+
+ DEBUGASSERT(oldp->f_priv == NULL && oldp->f_inode != NULL);
+
+ /* mountpoint private data from the inode reference from the file
+ * structure
+ */
+
+ bm = (struct binfs_state_s*)oldp->f_inode->i_private;
+ DEBUGASSERT(bm != NULL);
+
+ /* Opening of elements within the pseudo-file system is not yet supported
+ * and, hence, neither is dup'ing the opened file.
+ */
+
+ return ret;
+}
+
/****************************************************************************
* Name: binfs_opendir
*
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index cb0244e20..4ba0fe985 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -3940,3 +3940,12 @@
implemented).
* fs/romfs: Remove the rf_open flag. It looks good, but actually
does nothing.
+ * fs/fat: Remove the ff_open flag. Same story as for the ROMFS
+ rf_open flag.
+ * fs/fat/fs_fat32.c, fs/nxffs/nxffs_initialize, and
+ fs/nfs/nfs_vfsops.c: Completed implementation of the dup() methods.
+ There is still no good test available.
+ * sched/sig_timedwait.c: sigtimedwait() would return a bad signal
+ number if the signal was already pending when the function was
+ called.
+ called.
diff --git a/nuttx/TODO b/nuttx/TODO
index 28a9ce68b..0d02e10e6 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -1,4 +1,4 @@
-NuttX TODO List (Last updated January 13, 2013)
+NuttX TODO List (Last updated January 14, 2013)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with
@@ -15,7 +15,7 @@ nuttx/
(17) Network (net/, drivers/net)
(4) USB (drivers/usbdev, drivers/usbhost)
(12) Libraries (libc/, )
- (10) File system/Generic drivers (fs/, drivers/)
+ (9) File system/Generic drivers (fs/, drivers/)
(5) Graphics subystem (graphics/)
(1) Pascal add-on (pcode/)
(1) Documentation (Documentation/)
@@ -879,26 +879,6 @@ o File system / Generic drivers (fs/, drivers/)
Status: Open
Priority: Medium
- Title: dup AND dup2 WILL NOT WORK ON FILES IN A MOUNTED VOLUME
- Description: The current implementation of dup() and dup2() will only
- work with open device drivers and sockets. It will not
- work with open files in a file system. Support for dup'ing
- open files on a mounted volume has not been implemented yet.
-
- There is a stubbed out, partial implemenation in fs/fs_files.c.
- In would perform the dup2() operation by re-opening the file
- and setting the file pointer. The logic, however, would require
- that we remember the (relative) path to the file in the mounted
- volume for each open file.
-
- An option might to add a dup() method to the file system
- mountpoint interface.
-
- A limitation that results from this is that you cannot
- redirect I/O to an from and file.
- Status: Open
- Priority: High
-
o Graphics subystem (graphics/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/fs/fat/fs_fat32.c b/nuttx/fs/fat/fs_fat32.c
index 788e6bebc..7164a9f8f 100644
--- a/nuttx/fs/fat/fs_fat32.c
+++ b/nuttx/fs/fat/fs_fat32.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/fat/fs_fat32.c
*
- * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* References:
@@ -86,7 +86,9 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
size_t buflen);
static off_t fat_seek(FAR struct file *filep, off_t offset, int whence);
static int fat_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+
static int fat_sync(FAR struct file *filep);
+static int fat_dup(FAR const struct file *oldp, FAR struct file *newp);
static int fat_opendir(struct inode *mountpt, const char *relpath,
struct fs_dirent_s *dir);
@@ -129,7 +131,7 @@ const struct mountpt_operations fat_operations =
fat_ioctl, /* ioctl */
fat_sync, /* sync */
- NULL, /* dup */
+ fat_dup, /* dup */
fat_opendir, /* opendir */
NULL, /* closedir */
@@ -313,7 +315,6 @@ static int fat_open(FAR struct file *filep, const char *relpath,
/* Initialize the file private data (only need to initialize non-zero elements) */
- ff->ff_open = true;
ff->ff_oflags = oflags;
/* Save information that can be used later to recover the directory entry */
@@ -898,6 +899,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
DEBUGASSERT(fs != NULL);
/* Map the offset according to the whence option */
+
switch (whence)
{
case SEEK_SET: /* The offset is set to offset bytes. */
@@ -971,6 +973,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
ret = cluster;
goto errout_with_semaphore;
}
+
ff->ff_startcluster = cluster;
}
@@ -1232,6 +1235,123 @@ errout_with_semaphore:
return ret;
}
+/****************************************************************************
+ * Name: fat_dup
+ *
+ * Description: Duplicate open file data in the new file structure.
+ *
+ ****************************************************************************/
+
+static int fat_dup(FAR const struct file *oldp, FAR struct file *newp)
+{
+ FAR struct fat_mountpt_s *fs;
+ FAR struct fat_file_s *oldff;
+ FAR struct fat_file_s *newff;
+ int ret;
+
+ fvdbg("Dup %p->%p\n", oldp, newp);
+
+ /* Sanity checks */
+
+ DEBUGASSERT(oldp->f_priv != NULL &&
+ newp->f_priv == NULL &&
+ newp->f_inode != NULL);
+
+ /* Recover our private data from the struct file instance */
+
+ fs = (struct fat_mountpt_s *)oldp->f_inode->i_private;
+ DEBUGASSERT(fs != NULL);
+
+ /* Check if the mount is still healthy */
+
+ fat_semtake(fs);
+ ret = fat_checkmount(fs);
+ if (ret != OK)
+ {
+ goto errout_with_semaphore;
+ }
+
+ /* Recover the old private data from the old struct file instance */
+
+ oldff = oldp->f_priv;
+
+ /* Create a new instance of the file private date to describe the
+ * dup'ed file.
+ */
+
+ newff = (struct fat_file_s *)kmalloc(sizeof(struct fat_file_s));
+ if (!newff)
+ {
+ ret = -ENOMEM;
+ goto errout_with_semaphore;
+ }
+
+ /* Create a file buffer to support partial sector accesses */
+
+ newff->ff_buffer = (uint8_t*)fat_io_alloc(fs->fs_hwsectorsize);
+ if (!newff->ff_buffer)
+ {
+ ret = -ENOMEM;
+ goto errout_with_struct;
+ }
+
+ /* Copy the rest of the open open file state from the old file structure.
+ * There are some assumptions and potential issues here:
+ *
+ * 1) We assume that the higher level logic has copied the elements of
+ * the file structure, in particular, the file position.
+ * 2) There is a problem with ff_size if there are multiple opened
+ * file structures, each believing they know the size of the file.
+ * If one instance modifies the file length, then the new size of
+ * the opened file will be unknown to the other. That is a lurking
+ * bug!
+ *
+ * One good solution to this might be to add a refernce count to the
+ * file structure. Then, instead of dup'ing the whole structure
+ * as is done here, just increment the reference count on the
+ * structure. The would have to be integrated with open logic as
+ * well, however, so that the same file structure is re-used if the
+ * file is re-opened.
+ */
+
+ newff->ff_bflags = 0;
+ newff->ff_oflags = oldff->ff_oflags;
+ newff->ff_sectorsincluster = oldff->ff_sectorsincluster;
+ newff->ff_dirindex = oldff->ff_dirindex;
+ newff->ff_currentcluster = oldff->ff_currentcluster;
+ newff->ff_dirsector = oldff->ff_dirsector;
+ newff->ff_size = oldff->ff_size;
+ newff->ff_currentsector = 0;
+ newff->ff_cachesector = 0;
+
+ /* Attach the private date to the struct file instance */
+
+ newp->f_priv = newff;
+
+ /* Then insert the new instance into the mountpoint structure.
+ * It needs to be there (1) to handle error conditions that effect
+ * all files, and (2) to inform the umount logic that we are busy
+ * (but a simple reference count could have done that).
+ */
+
+ newff->ff_next = fs->fs_head;
+ fs->fs_head = newff->ff_next;
+
+ fat_semgive(fs);
+ return OK;
+
+ /* Error exits -- goto's are nasty things, but they sure can make error
+ * handling a lot simpler.
+ */
+
+errout_with_struct:
+ kfree(newff);
+
+errout_with_semaphore:
+ fat_semgive(fs);
+ return ret;
+}
+
/****************************************************************************
* Name: fat_opendir
*
diff --git a/nuttx/fs/fat/fs_fat32.h b/nuttx/fs/fat/fs_fat32.h
index 71a21333b..81f3f4675 100644
--- a/nuttx/fs/fat/fs_fat32.h
+++ b/nuttx/fs/fat/fs_fat32.h
@@ -752,7 +752,6 @@ struct fat_mountpt_s
struct fat_file_s
{
struct fat_file_s *ff_next; /* Retained in a singly linked list */
- bool ff_open; /* true: The file is (still) open */
uint8_t ff_bflags; /* The file buffer flags */
uint8_t ff_oflags; /* Flags provided when file was opened */
uint8_t ff_sectorsincluster; /* Sectors remaining in cluster */
diff --git a/nuttx/fs/fat/fs_fat32util.c b/nuttx/fs/fat/fs_fat32util.c
index 7231456d7..9aa1d3992 100644
--- a/nuttx/fs/fat/fs_fat32util.c
+++ b/nuttx/fs/fat/fs_fat32util.c
@@ -692,8 +692,6 @@ int fat_checkmount(struct fat_mountpt_s *fs)
if (fs && fs->fs_mounted)
{
- struct fat_file_s *file;
-
/* We still think the mount is healthy. Check an see if this is
* still the case
*/
@@ -715,14 +713,8 @@ int fat_checkmount(struct fat_mountpt_s *fs)
/* If we get here, the mount is NOT healthy */
fs->fs_mounted = false;
-
- /* Make sure that this is flagged in every opened file */
-
- for (file = fs->fs_head; file; file = file->ff_next)
- {
- file->ff_open = false;
- }
}
+
return -ENODEV;
}
diff --git a/nuttx/fs/nfs/nfs_node.h b/nuttx/fs/nfs/nfs_node.h
index 4ae9e162c..408bd1993 100644
--- a/nuttx/fs/nfs/nfs_node.h
+++ b/nuttx/fs/nfs/nfs_node.h
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nfs/nfs_node.h
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas
* Gregory Nutt
@@ -70,6 +70,7 @@
struct nfsnode
{
struct nfsnode *n_next; /* Retained in a singly linked list. */
+ uint8_t n_crefs; /* Reference count (for nfs_dup) */
uint8_t n_type; /* File type */
uint8_t n_fhsize; /* Size in bytes of the file handle */
uint8_t n_flags; /* Node flags */
diff --git a/nuttx/fs/nfs/nfs_util.c b/nuttx/fs/nfs/nfs_util.c
index 73fda72a7..e7d28b3d7 100644
--- a/nuttx/fs/nfs/nfs_util.c
+++ b/nuttx/fs/nfs/nfs_util.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nfs/nfs_util.c
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -213,7 +213,6 @@ int nfs_request(struct nfsmount *nmp, int procnum,
{
struct rpcclnt *clnt = nmp->nm_rpcclnt;
struct nfs_reply_header replyh;
- int trylater_delay;
int error;
tryagain:
@@ -250,12 +249,6 @@ tryagain:
if (error == EAGAIN)
{
error = 0;
- trylater_delay *= NFS_TIMEOUTMUL;
- if (trylater_delay > NFS_MAXTIMEO)
- {
- trylater_delay = NFS_MAXTIMEO;
- }
-
goto tryagain;
}
diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c
index efb026c7f..01e999ac8 100644
--- a/nuttx/fs/nfs/nfs_vfsops.c
+++ b/nuttx/fs/nfs/nfs_vfsops.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nfs/nfs_vfsops.c
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas
* Gregory Nutt
@@ -133,6 +133,7 @@ static int nfs_close(FAR struct file *filep);
static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen);
static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
size_t buflen);
+static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp);
static int nfs_opendir(struct inode *mountpt, const char *relpath,
struct fs_dirent_s *dir);
static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir);
@@ -168,7 +169,7 @@ const struct mountpt_operations nfs_operations =
NULL, /* ioctl */
NULL, /* sync */
- NULL, /* dup */
+ nfs_dup, /* dup */
nfs_opendir, /* opendir */
NULL, /* closedir */
@@ -359,7 +360,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
/* Save the attributes in the file data structure */
- tmp = *ptr++; /* handle_follows */
+ tmp = *ptr; /* handle_follows */
if (!tmp)
{
fdbg("WARNING: no file attributes\n");
@@ -369,7 +370,6 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
/* Initialize the file attributes */
nfs_attrupdate(np, (FAR struct nfs_fattr *)ptr);
- ptr += uint32_increment(sizeof(struct nfs_fattr));
}
/* Any following dir_wcc data is ignored for now */
@@ -412,7 +412,7 @@ static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np)
reqlen += (int)np->n_fhsize;
ptr += uint32_increment(np->n_fhsize);
- /* Copy the variable-length attribtes */
+ /* Copy the variable-length attributes */
*ptr++ = nfs_false; /* Don't change mode */
*ptr++ = nfs_false; /* Don't change uid */
@@ -423,7 +423,7 @@ static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np)
*ptr++ = HTONL(NFSV3SATTRTIME_TOSERVER); /* Use the server's time */
*ptr++ = HTONL(NFSV3SATTRTIME_TOSERVER); /* Use the server's time */
*ptr++ = nfs_false; /* No guard value */
- reqlen += 9*sizeof(uint32_t)
+ reqlen += 9 * sizeof(uint32_t);
/* Perform the SETATTR RPC */
@@ -553,9 +553,9 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
static int nfs_open(FAR struct file *filep, FAR const char *relpath,
int oflags, mode_t mode)
{
- struct nfsmount *nmp;
- struct nfsnode *np = NULL;
- int error;
+ struct nfsmount *nmp;
+ struct nfsnode *np;
+ int error;
/* Sanity checks */
@@ -634,6 +634,8 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
* non-zero elements)
*/
+ np->n_crefs = 1;
+
/* Attach the private data to the struct file instance */
filep->f_priv = np;
@@ -656,6 +658,7 @@ errout_with_semaphore:
{
kfree(np);
}
+
nfs_semgive(nmp);
return -error;
}
@@ -693,8 +696,22 @@ static int nfs_close(FAR struct file *filep)
nfs_semtake(nmp);
- /* Find our file structure in the list of file structures containted in the
- * mount structure.
+ /* Decrement the reference count. If the reference count would not
+ * decrement to zero, then that is all we have to do.
+ */
+
+ if (np->n_crefs > 1)
+ {
+ np->n_crefs--;
+ nfs_semgive(nmp);
+ return OK;
+ }
+
+ /* There are no more references to the file structure. Now we need to
+ * free up all resources associated with the open file.
+ *
+ * First, find our file structure in the list of file structures
+ * containted in the mount structure.
*/
for (prev = NULL, curr = nmp->nm_head; curr; prev = curr, curr = curr->n_next)
@@ -759,8 +776,8 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
/* Recover our private data from the struct file instance */
- nmp = (struct nfsmount*) filep->f_inode->i_private;
- np = (struct nfsnode*) filep->f_priv;
+ nmp = (struct nfsmount*)filep->f_inode->i_private;
+ np = (struct nfsnode*)filep->f_priv;
DEBUGASSERT(nmp != NULL);
@@ -1093,6 +1110,66 @@ errout_with_semaphore:
return -error;
}
+/****************************************************************************
+ * Name: binfs_dup
+ *
+ * Description:
+ * Duplicate open file data in the new file structure.
+ *
+ ****************************************************************************/
+
+static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp)
+{
+ struct nfsmount *nmp;
+ FAR struct nfsnode *np;
+ int error;
+
+ fvdbg("Dup %p->%p\n", oldp, newp);
+
+ /* Sanity checks */
+
+ DEBUGASSERT(oldp->f_priv != NULL && oldp->f_inode != NULL);
+
+ /* Recover our private data from the struct file instance */
+
+ nmp = (struct nfsmount*)oldp->f_inode->i_private;
+ np = (struct nfsnode*)oldp->f_priv;
+
+ DEBUGASSERT(nmp != NULL);
+
+ /* Check if the mount is still healthy */
+
+ nfs_semtake(nmp);
+ error = nfs_checkmount(nmp);
+ if (error != OK)
+ {
+ fdbg("ERROR: nfs_checkmount failed: %d\n", error);
+ nfs_semgive(nmp);
+ return -error;
+ }
+
+ /* Increment the reference count on the NFS node structure */
+
+ DEBUGASSERT(np->n_crefs < 0xff);
+ np->n_crefs++;
+
+ /* And save this as the file data for the new node */
+
+ newp->f_priv = np;
+
+ /* Then insert the new instance at the head of the list in the mountpoint
+ * tructure. It needs to be there (1) to handle error conditions that effect
+ * all files, and (2) to inform the umount logic that we are busy. We
+ * cannot unmount the file system if this list is not empty!
+ */
+
+ np->n_next = nmp->nm_head;
+ nmp->nm_head = np;
+
+ nfs_semgive(nmp);
+ return OK;
+}
+
/****************************************************************************
* Name: nfs_opendir
*
@@ -1756,12 +1833,15 @@ bad:
{
kfree(nmp->nm_so);
}
+
if (nmp->nm_rpcclnt)
{
kfree(nmp->nm_rpcclnt);
}
+
kfree(nmp);
}
+
return error;
}
diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c
index 0e2a394ba..9c2ada4f2 100644
--- a/nuttx/fs/nfs/rpc_clnt.c
+++ b/nuttx/fs/nfs/rpc_clnt.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nfs/rpc_clnt.c
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas
* Gregory Nutt
@@ -224,8 +224,6 @@ static int rpcclnt_receive(FAR struct rpcclnt *rpc, FAR struct sockaddr *aname,
static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
FAR void *reply, size_t resplen)
{
- FAR struct rpc_reply_header *replyheader;
- uint32_t rxid;
int error;
/* Get the next RPC reply from the socket */
@@ -235,22 +233,22 @@ static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
{
fdbg("ERROR: rpcclnt_receive returned: %d\n", error);
- /* If we failed because of a timeout, then try sending the CALL
- * message again.
- */
+ /* If we failed because of a timeout, then try sending the CALL
+ * message again.
+ */
- if (error == EAGAIN || error == ETIMEDOUT)
- {
- rpc->rc_timeout = true;
- }
- }
+ if (error == EAGAIN || error == ETIMEDOUT)
+ {
+ rpc->rc_timeout = true;
+ }
+ }
/* Get the xid and check that it is an RPC replysvr */
else
{
- replyheader = (FAR struct rpc_reply_header *)reply;
- rxid = replyheader->rp_xid;
+ FAR struct rpc_reply_header *replyheader =
+ (FAR struct rpc_reply_header *)reply;
if (replyheader->rp_direction != rpc_reply)
{
@@ -260,7 +258,7 @@ static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
}
}
- return OK;
+ return error;
}
/****************************************************************************
@@ -275,7 +273,6 @@ static uint32_t rpcclnt_newxid(void)
{
static uint32_t rpcclnt_xid = 0;
static uint32_t rpcclnt_xid_touched = 0;
- int xidp = 0;
srand(time(NULL));
if ((rpcclnt_xid == 0) && (rpcclnt_xid_touched == 0))
@@ -285,6 +282,7 @@ static uint32_t rpcclnt_newxid(void)
}
else
{
+ int xidp = 0;
do
{
xidp = rand();
diff --git a/nuttx/fs/nxffs/nxffs.h b/nuttx/fs/nxffs/nxffs.h
index 616dc7197..083e00fa7 100644
--- a/nuttx/fs/nxffs/nxffs.h
+++ b/nuttx/fs/nxffs/nxffs.h
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nxffs/nxffs.h
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* References: Linux/Documentation/filesystems/romfs.txt
@@ -1044,6 +1044,7 @@ extern int nxffs_pack(FAR struct nxffs_volume_s *volume);
* - nxffs_read() is defined in nxffs_read.c
* - nxffs_write() is defined in nxffs_write.c
* - nxffs_ioctl() is defined in nxffs_ioctl.c
+ * - nxffs_dup() is defined in nxffs_open.c
* - nxffs_opendir(), nxffs_readdir(), and nxffs_rewindir() are defined in
* nxffs_dirent.c
* - nxffs_bind() and nxffs_unbind() are defined in nxffs_initialize.c
@@ -1058,25 +1059,25 @@ struct fs_dirent_s;
struct statfs;
struct stat;
-extern int nxffs_open(FAR struct file *filep, FAR const char *relpath,
- int oflags, mode_t mode);
-extern int nxffs_close(FAR struct file *filep);
-extern ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer,
- size_t buflen);
-extern ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer,
- size_t buflen);
-extern int nxffs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-extern int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
- FAR struct fs_dirent_s *dir);
-extern int nxffs_readdir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
-extern int nxffs_rewinddir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
-extern int nxffs_bind(FAR struct inode *blkdriver, FAR const void *data,
- FAR void **handle);
-extern int nxffs_unbind(FAR void *handle, FAR struct inode **blkdriver);
-extern int nxffs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf);
-extern int nxffs_stat(FAR struct inode *mountpt, FAR const char *relpath,
- FAR struct stat *buf);
-extern int nxffs_unlink(FAR struct inode *mountpt, FAR const char *relpath);
+int nxffs_open(FAR struct file *filep, FAR const char *relpath, int oflags,
+ mode_t mode);
+int nxffs_close(FAR struct file *filep);
+ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
+ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer,
+ size_t buflen);
+int nxffs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+int nxffs_dup(FAR const struct file *oldp, FAR struct file *newp);
+int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
+ FAR struct fs_dirent_s *dir);
+int nxffs_readdir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
+int nxffs_rewinddir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
+int nxffs_bind(FAR struct inode *blkdriver, FAR const void *data,
+ FAR void **handle);
+int nxffs_unbind(FAR void *handle, FAR struct inode **blkdriver);
+int nxffs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf);
+int nxffs_stat(FAR struct inode *mountpt, FAR const char *relpath,
+ FAR struct stat *buf);
+int nxffs_unlink(FAR struct inode *mountpt, FAR const char *relpath);
#endif /* __FS_NXFFS_NXFFS_H */
diff --git a/nuttx/fs/nxffs/nxffs_initialize.c b/nuttx/fs/nxffs/nxffs_initialize.c
index 0aa424869..4e7428c73 100644
--- a/nuttx/fs/nxffs/nxffs_initialize.c
+++ b/nuttx/fs/nxffs/nxffs_initialize.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nxffs/nxffs_initialize.c
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* References: Linux/Documentation/filesystems/romfs.txt
@@ -84,7 +84,7 @@ const struct mountpt_operations nxffs_operations =
nxffs_ioctl, /* ioctl */
NULL, /* sync -- No buffered data */
- NULL, /* dup -- not implemented */
+ nxffs_dup, /* dup */
nxffs_opendir, /* opendir */
NULL, /* closedir */
diff --git a/nuttx/fs/nxffs/nxffs_open.c b/nuttx/fs/nxffs/nxffs_open.c
index eb7817c57..b1e99267f 100644
--- a/nuttx/fs/nxffs/nxffs_open.c
+++ b/nuttx/fs/nxffs/nxffs_open.c
@@ -1,7 +1,7 @@
/****************************************************************************
* fs/nxffs/nxffs_open.c
*
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* References: Linux/Documentation/filesystems/romfs.txt
@@ -1023,7 +1023,7 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath,
#endif
/* Limitation: A file must be opened for reading or writing, but not both.
- * There is no general for extending the size of of a file. Extending the
+ * There is no general way of extending the size of a file. Extending the
* file size of possible if the file to be extended is the last in the
* sequence on FLASH, but since that case is not the general case, no file
* extension is supported.
@@ -1058,6 +1058,64 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath,
return ret;
}
+/****************************************************************************
+ * Name: binfs_dup
+ *
+ * Description:
+ * Duplicate open file data in the new file structure.
+ *
+ ****************************************************************************/
+
+int nxffs_dup(FAR const struct file *oldp, FAR struct file *newp)
+{
+#ifdef CONFIG_DEBUG
+ FAR struct nxffs_volume_s *volume;
+#endif
+ FAR struct nxffs_ofile_s *ofile;
+
+ fvdbg("Dup %p->%p\n", oldp, newp);
+
+ /* Sanity checks */
+
+#ifdef CONFIG_DEBUG
+ DEBUGASSERT(oldp->f_priv == NULL && oldp->f_inode != NULL);
+
+ /* Get the mountpoint private data from the NuttX inode reference in the
+ * file structure
+ */
+
+ volume = (FAR struct nxffs_volume_s*)oldp->f_inode->i_private;
+ DEBUGASSERT(volume != NULL);
+#endif
+
+ /* Recover the open file state from the struct file instance */
+
+ ofile = (FAR struct nxffs_ofile_s *)oldp->f_priv;
+
+ /* I do not think we need exclusive access to the volume to do this.
+ * The volume exclsem protects the open file list and, hence, would
+ * assure that the ofile is stable. However, it is assumed that the
+ * caller holds a value file descriptor associated with this ofile,
+ * so it should be stable throughout the life of this function.
+ */
+
+ /* Limitations: I do not think we have to be concerned about the
+ * usual NXFFS file limitations here: dup'ing cannot resulting
+ * in mixed reading and writing to the same file, or multiple
+ * writer to different file.
+ *
+ * I notice that nxffs_wropen will prohibit multiple opens for
+ * writing. But I do not thing that dup'ing a file already opened
+ * for writing suffers from any of these issues.
+ */
+
+ /* Just increment the reference count on the ofile */
+
+ ofile->crefs++;
+ newp->f_priv = (FAR void *)ofile;
+ return OK;
+}
+
/****************************************************************************
* Name: nxffs_close
*
diff --git a/nuttx/fs/romfs/fs_romfs.c b/nuttx/fs/romfs/fs_romfs.c
index de87c7fec..2814aa49d 100644
--- a/nuttx/fs/romfs/fs_romfs.c
+++ b/nuttx/fs/romfs/fs_romfs.c
@@ -636,7 +636,7 @@ static int romfs_dup(FAR const struct file *oldp, FAR struct file *newp)
* dup'ed file.
*/
- newrf = (FAR struct romfs_file_s *)malloc(sizeof(struct romfs_file_s));
+ newrf = (FAR struct romfs_file_s *)kmalloc(sizeof(struct romfs_file_s));
if (!newrf)
{
fdbg("Failed to allocate private data\n", ret);
diff --git a/nuttx/include/nuttx/fs/fs.h b/nuttx/include/nuttx/fs/fs.h
index 3138a8412..327bf37ca 100644
--- a/nuttx/include/nuttx/fs/fs.h
+++ b/nuttx/include/nuttx/fs/fs.h
@@ -1,7 +1,7 @@
/****************************************************************************
* include/nuttx/fs/fs.h
*
- * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
diff --git a/nuttx/sched/mq_initialize.c b/nuttx/sched/mq_initialize.c
index 5b03a1120..dd7c7ed0f 100644
--- a/nuttx/sched/mq_initialize.c
+++ b/nuttx/sched/mq_initialize.c
@@ -217,11 +217,11 @@ void mq_initialize(void)
void mq_desblockalloc(void)
{
- struct mq_des_block_s *mqdesblock;
+ FAR struct mq_des_block_s *mqdesblock;
/* Allocate a block of message descriptors */
- mqdesblock = (struct mq_des_block_s *)kmalloc(sizeof(struct mq_des_block_s));
+ mqdesblock = (FAR struct mq_des_block_s *)kmalloc(sizeof(struct mq_des_block_s));
if (mqdesblock)
{
int i;
diff --git a/nuttx/sched/sig_timedwait.c b/nuttx/sched/sig_timedwait.c
index b07b8f2a1..f8c619b21 100644
--- a/nuttx/sched/sig_timedwait.c
+++ b/nuttx/sched/sig_timedwait.c
@@ -228,7 +228,7 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info,
/* The return value is the number of the signal that awakened us */
- ret = info->si_signo;
+ ret = sigpend->info.si_signo;
}
/* We will have to wait for a signal to be posted to this task. */
diff --git a/nuttx/sched/task_vfork.c b/nuttx/sched/task_vfork.c
index 0ea09b048..4b42c7b36 100644
--- a/nuttx/sched/task_vfork.c
+++ b/nuttx/sched/task_vfork.c
@@ -291,7 +291,7 @@ pid_t task_vforkstart(FAR _TCB *child)
* still running.
*/
- while ((ret = kill(pid, 0)) == OK)
+ while (kill(pid, 0) == OK)
{
/* Yes.. then we can yield to it -- assuming that it has not lowered
* its priority. sleep(0) might be a safer thing to do since it does
--
cgit v1.2.3
From 90a72e97d3f18a5e230578c63113da119622a73a Mon Sep 17 00:00:00 2001
From: patacongo
Date: Tue, 15 Jan 2013 15:40:18 +0000
Subject: Implement vfork() for the MIPS32 architecture
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5520 42af7a65-404d-4744-a932-0658087f49c3
---
nuttx/ChangeLog | 3 +
nuttx/Documentation/NuttX.html | 4 +-
nuttx/TODO | 21 ++-
nuttx/arch/arm/src/arm/vfork.S | 3 +
nuttx/arch/arm/src/armv7-m/vfork.S | 3 +
nuttx/arch/arm/src/common/up_vfork.c | 2 +-
nuttx/arch/arm/src/common/up_vfork.h | 8 +-
nuttx/arch/mips/Kconfig | 1 +
nuttx/arch/mips/src/mips32/Kconfig | 8 ++
nuttx/arch/mips/src/mips32/up_vfork.c | 254 ++++++++++++++++++++++++++++++++++
nuttx/arch/mips/src/mips32/up_vfork.h | 132 ++++++++++++++++++
nuttx/arch/mips/src/mips32/vfork.S | 154 +++++++++++++++++++++
nuttx/arch/mips/src/pic32mx/Make.defs | 4 +-
nuttx/configs/ubw32/ostest/defconfig | 9 +-
nuttx/sched/task_vfork.c | 8 +-
15 files changed, 599 insertions(+), 15 deletions(-)
create mode 100644 nuttx/arch/mips/src/mips32/up_vfork.c
create mode 100644 nuttx/arch/mips/src/mips32/up_vfork.h
create mode 100644 nuttx/arch/mips/src/mips32/vfork.S
(limited to 'nuttx/sched')
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 41ac95db0..2d2cd8259 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -3952,4 +3952,7 @@
scripts sub-directory
* configs/ubw32/ostest: Configuration configured to use the
kconfig-frontends tools.
+ * arch/mips/src/mips32/up_vfork.c, up_vfork.h, and vfork.S:
+ Implement vfork() for MIPS32 (no floating point support)
+ * configs/ubw32/ostest: Enable the vfork() test.
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 22651de79..c5f1ebc9c 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -381,7 +381,7 @@
|
- Well documented in the NuttX User Guide.
+ Well documented in the NuttX User Guide.
@@ -3833,7 +3833,7 @@ pascal-3.0 2011-05-15 Gregory Nutt <gnutt@nuttx.org>
|
![](favicon.ico) |
- User Guide |
+ User Guide |
![](favicon.ico) |
diff --git a/nuttx/TODO b/nuttx/TODO
index 0d02e10e6..58ca4cc8e 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -6,7 +6,7 @@ standards, things that could be improved, and ideas for enhancements.
nuttx/
- (10) Task/Scheduler (sched/)
+ (11) Task/Scheduler (sched/)
(1) Memory Managment (mm/)
(3) Signals (sched/, arch/)
(2) pthreads (sched/)
@@ -195,6 +195,25 @@ o Task/Scheduler (sched/)
Status: Open
Priority: Low
+ Title: IMPROVED TASK CONTROL BLOCK STRUCTURE
+ All task resources that are shared amongst threads have
+ their own "break-away", reference-counted structure. The
+ Task Control Block (TCB) of each thread holds a reference
+ to each breakaway structure (see include/nuttx/sched.h).
+ It would be more efficent to have one reference counted
+ structure that holds all of the shared resources.
+
+ These are the current shared structures:
+ - Environment varaibles (struct environ_s)
+ - PIC data space and address environments (struct dspace_s)
+ - File descriptors (struct filelist)
+ - FILE streams (struct streamlist)
+ - Sockets (struct socketlist)
+ Status: Open
+ Priority: Low. This is an enhancement. It would slight reduce
+ memory usage but would also increase coupling. These
+ resources are nicely modular now.
+
o Memory Managment (mm/)
^^^^^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/arch/arm/src/arm/vfork.S b/nuttx/arch/arm/src/arm/vfork.S
index 226d9f7de..7c3c8b727 100644
--- a/nuttx/arch/arm/src/arm/vfork.S
+++ b/nuttx/arch/arm/src/arm/vfork.S
@@ -105,6 +105,7 @@ vfork:
mov r0, sp /* Save the value of the stack on entry */
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
+ /* CPU registers */
/* Save the volatile registers */
str r4, [sp, #VFORK_R4_OFFSET]
@@ -121,6 +122,8 @@ vfork:
str r0, [sp, #VFORK_SP_OFFSET]
str lr, [sp, #VFORK_LR_OFFSET]
+ /* Floating point registers (not yet) */
+
/* Then, call up_vfork(), passing it a pointer to the stack structure */
mov r0, sp
diff --git a/nuttx/arch/arm/src/armv7-m/vfork.S b/nuttx/arch/arm/src/armv7-m/vfork.S
index 386fca33c..f36ff23aa 100644
--- a/nuttx/arch/arm/src/armv7-m/vfork.S
+++ b/nuttx/arch/arm/src/armv7-m/vfork.S
@@ -108,6 +108,7 @@ vfork:
mov r0, sp /* Save the value of the stack on entry */
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
+ /* CPU registers */
/* Save the volatile registers */
str r4, [sp, #VFORK_R4_OFFSET]
@@ -124,6 +125,8 @@ vfork:
str r0, [sp, #VFORK_SP_OFFSET]
str lr, [sp, #VFORK_LR_OFFSET]
+ /* Floating point registers (not yet) */
+
/* Then, call up_vfork(), passing it a pointer to the stack structure */
mov r0, sp
diff --git a/nuttx/arch/arm/src/common/up_vfork.c b/nuttx/arch/arm/src/common/up_vfork.c
index 5349378bc..3b653e317 100644
--- a/nuttx/arch/arm/src/common/up_vfork.c
+++ b/nuttx/arch/arm/src/common/up_vfork.c
@@ -208,7 +208,7 @@ pid_t up_vfork(const struct vfork_s *context)
svdbg("New stack base:%08x SP:%08x FP:%08x\n",
child->adj_stack_ptr, newsp, newfp);
- /* Update the stack pointer, frame pointer, and voltile registers. When
+ /* Update the stack pointer, frame pointer, and volatile registers. When
* the child TCB was initialized, all of the values were set to zero.
* up_initial_state() altered a few values, but the return value in R0
* should be cleared to zero, providing the indication to the newly started
diff --git a/nuttx/arch/arm/src/common/up_vfork.h b/nuttx/arch/arm/src/common/up_vfork.h
index a4505474a..97edf9aaa 100644
--- a/nuttx/arch/arm/src/common/up_vfork.h
+++ b/nuttx/arch/arm/src/common/up_vfork.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * arch/arm/src/common/arm-vfork.h
+ * arch/arm/src/common/up_vfork.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -53,6 +53,7 @@
#define VFORK_R8_OFFSET (4*4) /* Volatile register r8 */
#define VFORK_R9_OFFSET (5*4) /* Volatile register r9 */
#define VFORK_R10_OFFSET (6*4) /* Volatile register r10 */
+
#define VFORK_FP_OFFSET (7*4) /* Frame pointer */
#define VFORK_SP_OFFSET (8*4) /* Stack pointer*/
#define VFORK_LR_OFFSET (9*4) /* Return address*/
@@ -66,6 +67,8 @@
#ifndef __ASSEMBLY__
struct vfork_s
{
+ /* CPU registers */
+
uint32_t r4; /* Volatile register r4 */
uint32_t r5; /* Volatile register r5 */
uint32_t r6; /* Volatile register r6 */
@@ -73,9 +76,12 @@ struct vfork_s
uint32_t r8; /* Volatile register r8 */
uint32_t r9; /* Volatile register r9 */
uint32_t r10; /* Volatile register r10 */
+
uint32_t fp; /* Frame pointer */
uint32_t sp; /* Stack pointer*/
uint32_t lr; /* Return address*/
+
+ /* Floating point registers (not yet) */
};
#endif
diff --git a/nuttx/arch/mips/Kconfig b/nuttx/arch/mips/Kconfig
index 1b10e26ae..86482ef7a 100644
--- a/nuttx/arch/mips/Kconfig
+++ b/nuttx/arch/mips/Kconfig
@@ -22,6 +22,7 @@ endchoice
config ARCH_MIPS32
bool
default n
+ select ARCH_HAVE_VFORK
config ARCH_FAMILY
string
diff --git a/nuttx/arch/mips/src/mips32/Kconfig b/nuttx/arch/mips/src/mips32/Kconfig
index b8b5d9b92..c7a4499c2 100644
--- a/nuttx/arch/mips/src/mips32/Kconfig
+++ b/nuttx/arch/mips/src/mips32/Kconfig
@@ -47,4 +47,12 @@ config MIPS32_TOOLCHAIN_PINGUINOL
endchoice
+config MIPS32_FRAMEPOINTER
+ bool "ABI Uses Frame Pointer"
+ default n
+ depends on ARCH_HAVE_VFORK
+ ---help---
+ Register r30 may be a frame pointer in some ABIs. Or may just be
+ saved register s8. It makes a difference for vfork handling.
+
endif
diff --git a/nuttx/arch/mips/src/mips32/up_vfork.c b/nuttx/arch/mips/src/mips32/up_vfork.c
new file mode 100644
index 000000000..6b7e27f31
--- /dev/null
+++ b/nuttx/arch/mips/src/mips32/up_vfork.c
@@ -0,0 +1,254 @@
+/****************************************************************************
+ * arch/mips/src/mips32/up_vfork.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "up_vfork.h"
+#include "os_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_STACK_ALIGNMENT
+# define CONFIG_STACK_ALIGNMENT 4
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_vfork
+ *
+ * Description:
+ * The vfork() function has the same effect as fork(), except that the
+ * behavior is undefined if the process created by vfork() either modifies
+ * any data other than a variable of type pid_t used to store the return
+ * value from vfork(), or returns from the function in which vfork() was
+ * called, or calls any other function before successfully calling _exit()
+ * or one of the exec family of functions.
+ *
+ * The overall sequence is:
+ *
+ * 1) User code calls vfork(). vfork() collects context information and
+ * transfers control up up_vfork().
+ * 2) up_vfork()and calls task_vforksetup().
+ * 3) task_vforksetup() allocates and configures the child task's TCB. This
+ * consists of:
+ * - Allocation of the child task's TCB.
+ * - Initialization of file descriptors and streams
+ * - Configuration of environment variables
+ * - Setup the intput parameters for the task.
+ * - Initialization of the TCB (including call to up_initial_state()
+ * 4) up_vfork() provides any additional operating context. up_vfork must:
+ * - Allocate and initialize the stack
+ * - Initialize special values in any CPU registers that were not
+ * already configured by up_initial_state()
+ * 5) up_vfork() then calls task_vforkstart()
+ * 6) task_vforkstart() then executes the child thread.
+ *
+ * task_vforkabort() may be called if an error occurs between steps 3 and 6.
+ *
+ * Input Paremeters:
+ * context - Caller context information saved by vfork()
+ *
+ * Return:
+ * Upon successful completion, vfork() returns 0 to the child process and
+ * returns the process ID of the child process to the parent process.
+ * Otherwise, -1 is returned to the parent, no child process is created,
+ * and errno is set to indicate the error.
+ *
+ ****************************************************************************/
+
+pid_t up_vfork(const struct vfork_s *context)
+{
+ _TCB *parent = (FAR _TCB *)g_readytorun.head;
+ _TCB *child;
+ size_t stacksize;
+ uint32_t newsp;
+#if CONFIG_MIPS32_FRAMEPOINTER
+ uint32_t newfp;
+#endif
+ uint32_t stackutil;
+ int ret;
+
+ svdbg("s0:%08x s1:%08x s2:%08x s3:%08x s4:%08x\n",
+ context->s0, context->s1, context->s2, context->s3, context->s4);
+#if CONFIG_MIPS32_FRAMEPOINTER
+ svdbg("s5:%08x s6:%08x s7:%08x\n",
+ context->s5, context->s6, context->s7);
+#ifdef MIPS32_SAVE_GP
+ svdbg("fp:%08x sp:%08x ra:%08x gp:%08x\n",
+ context->fp, context->sp, context->ra, context->gp);
+#else
+ svdbg("fp:%08x sp:%08x ra:%08x\n",
+ context->fp context->sp, context->ra);
+#endif
+#else
+ svdbg("s5:%08x s6:%08x s7:%08x s8:%08x\n",
+ context->s5, context->s6, context->s7, context->s8);
+#ifdef MIPS32_SAVE_GP
+ svdbg("sp:%08x ra:%08x gp:%08x\n",
+ context->sp, context->ra, context->gp);
+#else
+ svdbg("sp:%08x ra:%08x\n",
+ context->sp, context->ra);
+#endif
+#endif
+
+ /* Allocate and initialize a TCB for the child task. */
+
+ child = task_vforksetup((start_t)context->ra);
+ if (!child)
+ {
+ sdbg("task_vforksetup failed\n");
+ return (pid_t)ERROR;
+ }
+
+ svdbg("Parent=%p Child=%p\n", parent, child);
+
+ /* Get the size of the parent task's stack. Due to alignment operations,
+ * the adjusted stack size may be smaller than the stack size originally
+ * requrested.
+ */
+
+ stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1;
+
+ /* Allocate the stack for the TCB */
+
+ ret = up_create_stack(child, stacksize);
+ if (ret != OK)
+ {
+ sdbg("up_create_stack failed: %d\n", ret);
+ task_vforkabort(child, -ret);
+ return (pid_t)ERROR;
+ }
+
+ /* How much of the parent's stack was utilized? The MIPS uses
+ * a push-down stack so that the current stack pointer should
+ * be lower than the initial, adjusted stack pointer. The
+ * stack usage should be the difference between those two.
+ */
+
+ DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp);
+ stackutil = (uint32_t)parent->adj_stack_ptr - context->sp;
+
+ svdbg("stacksize:%d stackutil:%d\n", stacksize, stackutil);
+
+ /* Make some feeble effort to perserve the stack contents. This is
+ * feeble because the stack surely contains invalid pointers and other
+ * content that will not work in the child context. However, if the
+ * user follows all of the caveats of vfor() usage, even this feeble
+ * effort is overkill.
+ */
+
+ newsp = (uint32_t)child->adj_stack_ptr - stackutil;
+ memcpy((void *)newsp, (const void *)context->sp, stackutil);
+
+ /* Was there a frame pointer in place before? */
+
+#if CONFIG_MIPS32_FRAMEPOINTER
+ if (context->fp <= (uint32_t)parent->adj_stack_ptr &&
+ context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
+ {
+ uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp;
+ newfp = (uint32_t)child->adj_stack_ptr - frameutil;
+ }
+ else
+ {
+ newfp = context->fp;
+ }
+
+ svdbg("Old stack base:%08x SP:%08x FP:%08x\n",
+ parent->adj_stack_ptr, context->sp, context->fp);
+ svdbg("New stack base:%08x SP:%08x FP:%08x\n",
+ child->adj_stack_ptr, newsp, newfp);
+#else
+ svdbg("Old stack base:%08x SP:%08x\n",
+ parent->adj_stack_ptr, context->sp);
+ svdbg("New stack base:%08x SP:%08x\n",
+ child->adj_stack_ptr, newsp);
+#endif
+
+ /* Update the stack pointer, frame pointer, global pointer and saved
+ * registers. When the child TCB was initialized, all of the values
+ * were set to zero. up_initial_state() altered a few values, but the
+ * return value in v0 should be cleared to zero, providing the
+ * indication to the newly started child thread.
+ */
+
+ child->xcp.regs[REG_S0] = context->s0; /* Saved register s0 */
+ child->xcp.regs[REG_S1] = context->s1; /* Saved register s1 */
+ child->xcp.regs[REG_S2] = context->s2; /* Saved register s2 */
+ child->xcp.regs[REG_S3] = context->s3; /* Volatile register s3 */
+ child->xcp.regs[REG_S4] = context->s4; /* Volatile register s4 */
+ child->xcp.regs[REG_S5] = context->s5; /* Volatile register s5 */
+ child->xcp.regs[REG_S6] = context->s6; /* Volatile register s6 */
+ child->xcp.regs[REG_S7] = context->s7; /* Volatile register s7 */
+#if CONFIG_MIPS32_FRAMEPOINTER
+ child->xcp.regs[REG_FP] = newfp; /* Frame pointer */
+#else
+ child->xcp.regs[REG_S8] = context->s8; /* Volatile register s8 */
+#endif
+ child->xcp.regs[REG_SP] = newsp; /* Stack pointer */
+#if MIPS32_SAVE_GP
+ child->xcp.regs[REG_GP] = newsp; /* Global pointer */
+#endif
+
+ /* And, finally, start the child task. On a failure, task_vforkstart()
+ * will discard the TCB by calling task_vforkabort().
+ */
+
+ return task_vforkstart(child);
+}
diff --git a/nuttx/arch/mips/src/mips32/up_vfork.h b/nuttx/arch/mips/src/mips32/up_vfork.h
new file mode 100644
index 000000000..556633072
--- /dev/null
+++ b/nuttx/arch/mips/src/mips32/up_vfork.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+ * arch/mips/src/mips/up_vfork.h
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_MIPS_SRC_MIPS32_VFORK_H
+#define __ARCH_MIPS_SRC_MIPS32_VFORK_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Register r30 may be a frame pointer in some ABIs. Or may just be saved
+ * register s8. It makes a difference for vfork handling.
+ */
+
+#undef VFORK_HAVE_FP
+
+/* r0 zero Always has the value 0.
+ * r1 at Temporary generally used by assembler.
+ * r2-r3 v0-v1 Used for expression evaluations and to hold the integer and
+ * pointer type function return values.
+ * r4-r7 a0-a3 Used for passing arguments to functions; values are not
+ * preserved across function calls.
+ * r8-r15 t0-t7 Temporary registers used for expression evaluation; values
+ * are not preserved across function calls.
+ * r16-r23 s0-s7 Saved registers; values are preserved across function calls.
+ * r24-r25 t8-t9 Temporary registers used for expression evaluations; values
+ * are not preserved across function calls. When calling
+ * position independent functions r25 must contain the address
+ * of the called function.
+ * r26-r27 k0-k1 Used only by the operating system.
+ * r28 gp Global pointer and context pointer.
+ * r29 sp Stack pointer.
+ * r30 s8 Saved register (like s0-s7). If a frame pointer is used,
+ * then this is the frame pointer.
+ * r31 ra Return address.
+ */
+
+#define VFORK_S0_OFFSET (0*4) /* Saved register s0 */
+#define VFORK_S1_OFFSET (1*4) /* Saved register s1 */
+#define VFORK_S2_OFFSET (2*4) /* Saved register s2 */
+#define VFORK_S3_OFFSET (3*4) /* Saved register s3 */
+#define VFORK_S4_OFFSET (4*4) /* Saved register s4 */
+#define VFORK_S5_OFFSET (5*4) /* Saved register s5 */
+#define VFORK_S6_OFFSET (6*4) /* Saved register s6 */
+#define VFORK_S7_OFFSET (7*4) /* Saved register s7 */
+
+#ifdef CONFIG_MIPS32_FRAMEPOINTER
+# define VFORK_FP_OFFSET (8*4) /* Frame pointer */
+#else
+# define VFORK_S8_OFFSET (8*4) /* Saved register s8 */
+#endif
+
+#define VFORK_SP_OFFSET (9*4) /* Stack pointer*/
+#define VFORK_RA_OFFSET (10*4) /* Return address*/
+#ifdef MIPS32_SAVE_GP
+# define VFORK_GP_OFFSET (11*4) /* Global pointer */
+# define VFORK_SIZEOF (12*4)
+#else
+# define VFORK_SIZEOF (11*4)
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+struct vfork_s
+{
+ /* CPU registers */
+
+ uint32_t s0; /* Saved register s0 */
+ uint32_t s1; /* Saved register s1 */
+ uint32_t s2; /* Saved register s2 */
+ uint32_t s3; /* Saved register s3 */
+ uint32_t s4; /* Saved register s4 */
+ uint32_t s5; /* Saved register s5 */
+ uint32_t s6; /* Saved register s6 */
+ uint32_t s7; /* Saved register s7 */
+#ifdef CONFIG_MIPS32_FRAMEPOINTER
+ uint32_t fp; /* Frame pointer */
+#else
+ uint32_t s8; /* Saved register s8 */
+#endif
+ uint32_t sp; /* Stack pointer*/
+ uint32_t ra; /* Return address*/
+#ifdef MIPS32_SAVE_GP
+ uint32_t gp; /* Global pointer */
+#endif
+
+ /* Floating point registers (not yet) */
+};
+#endif
+
+#endif /* __ARCH_MIPS_SRC_MIPS32_VFORK_H */
diff --git a/nuttx/arch/mips/src/mips32/vfork.S b/nuttx/arch/mips/src/mips32/vfork.S
new file mode 100644
index 000000000..2b7d180d3
--- /dev/null
+++ b/nuttx/arch/mips/src/mips32/vfork.S
@@ -0,0 +1,154 @@
+/************************************************************************************
+ * arch/mips/src/mips32/vfork.S
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include "up_vfork.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Global Symbols
+ ************************************************************************************/
+
+ .file "vfork.S"
+ .globl up_vfork
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: vfork
+ *
+ * Description:
+ * The vfork() function has the same effect as fork(), except that the behavior is
+ * undefined if the process created by vfork() either modifies any data other than
+ * a variable of type pid_t used to store the return value from vfork(), or returns
+ * from the function in which vfork() was called, or calls any other function before
+ * successfully calling _exit() or one of the exec family of functions.
+ *
+ * This thin layer implements vfork by simply calling up_vfork() with the vfork()
+ * context as an argument. The overall sequence is:
+ *
+ * 1) User code calls vfork(). vfork() collects context information and
+ * transfers control up up_vfork().
+ * 2) up_vfork()and calls task_vforksetup().
+ * 3) task_vforksetup() allocates and configures the child task's TCB. This
+ * consists of:
+ * - Allocation of the child task's TCB.
+ * - Initialization of file descriptors and streams
+ * - Configuration of environment variables
+ * - Setup the intput parameters for the task.
+ * - Initialization of the TCB (including call to up_initial_state()
+ * 4) up_vfork() provides any additional operating context. up_vfork must:
+ * - Allocate and initialize the stack
+ * - Initialize special values in any CPU registers that were not
+ * already configured by up_initial_state()
+ * 5) up_vfork() then calls task_vforkstart()
+ * 6) task_vforkstart() then executes the child thread.
+ *
+ * Input Paremeters:
+ * None
+ *
+ * Return:
+ * Upon successful completion, vfork() returns 0 to the child process and returns
+ * the process ID of the child process to the parent process. Otherwise, -1 is
+ * returned to the parent, no child process is created, and errno is set to
+ * indicate the error.
+ *
+ ************************************************************************************/
+
+ .text
+ .align 2
+ .globl vfork
+ .type vfork, function
+ .set nomips16
+ .ent vfork
+
+vfork:
+ /* Create a stack frame */
+
+ move $t0, $sp /* Save the value of the stack on entry */
+ addiu $sp, $sp, -VFORK_SIZEOF /* Allocate the structure on the stack */
+
+ /* CPU registers */
+ /* Save the saved registers */
+
+ sw $s0, VFORK_S0_OFFSET($sp)
+ sw $s1, VFORK_S1_OFFSET($sp)
+ sw $s2, VFORK_S2_OFFSET($sp)
+ sw $s3, VFORK_S3_OFFSET($sp)
+ sw $s4, VFORK_S4_OFFSET($sp)
+ sw $s5, VFORK_S5_OFFSET($sp)
+ sw $s6, VFORK_S6_OFFSET($sp)
+ sw $s7, VFORK_S7_OFFSET($sp)
+
+#ifdef CONFIG_MIPS32_FRAMEPOINTER
+ sw $fp, VFORK_FP_OFFSET($sp)
+#else
+ sw $s8, VFORK_S8_OFFSET($sp)
+#endif
+
+ /* Save the global pointer, stack pointer, and return address */
+
+ sw $t0, VFORK_SP_OFFSET($sp)
+ sw $ra, VFORK_RA_OFFSET($sp)
+#ifdef MIPS32_SAVE_GP
+ sw $gp, VFORK_GP_OFFSET($sp)
+#endif
+
+ /* Floating point registers (not yet) */
+
+ /* Then, call up_vfork(), passing it a pointer to the stack structure */
+
+ move $a0, $sp
+ jal up_vfork
+ nop
+
+ /* Release the stack data and return the value returned by up_vfork */
+
+ lw $ra, VFORK_RA_OFFSET($sp)
+ addiu $sp, $sp, VFORK_SIZEOF
+ j $ra
+
+ .end vfork
+ .size vfork, .-vfork
diff --git a/nuttx/arch/mips/src/pic32mx/Make.defs b/nuttx/arch/mips/src/pic32mx/Make.defs
index 46fef84dc..861e1c301 100644
--- a/nuttx/arch/mips/src/pic32mx/Make.defs
+++ b/nuttx/arch/mips/src/pic32mx/Make.defs
@@ -39,14 +39,14 @@ HEAD_ASRC = pic32mx-head.S
# Common MIPS files
-CMN_ASRCS = up_syscall0.S
+CMN_ASRCS = up_syscall0.S vfork.S
CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
up_createstack.c up_doirq.c up_exit.c up_idle.c up_initialize.c \
up_initialstate.c up_interruptcontext.c up_irq.c up_lowputs.c \
up_mdelay.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c \
up_puts.c up_releasepending.c up_releasestack.c up_reprioritizertr.c \
up_schedulesigaction.c up_sigdeliver.c up_swint0.c up_udelay.c \
- up_unblocktask.c up_usestack.c
+ up_unblocktask.c up_usestack.c up_vfork.c
# Configuration dependent common files
diff --git a/nuttx/configs/ubw32/ostest/defconfig b/nuttx/configs/ubw32/ostest/defconfig
index 3a387ab99..a722e25e7 100644
--- a/nuttx/configs/ubw32/ostest/defconfig
+++ b/nuttx/configs/ubw32/ostest/defconfig
@@ -72,13 +72,10 @@ CONFIG_ARCH_MIPS32=y
# MIPS32 Configuration Options
#
# CONFIG_MIPS32_TOOLCHAIN_GNU_ELF is not set
-# CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL is not set
-# CONFIG_MIPS32_TOOLCHAIN_MICROCHIPL_LITE is not set
# CONFIG_MIPS32_TOOLCHAIN_MICROCHIPW is not set
CONFIG_MIPS32_TOOLCHAIN_MICROCHIPW_LITE=y
-# CONFIG_MIPS32_TOOLCHAIN_MICROCHIPOPENL is not set
# CONFIG_MIPS32_TOOLCHAIN_PINGUINOW is not set
-# CONFIG_MIPS32_TOOLCHAIN_PINGUINOL is not set
+# CONFIG_MIPS32_FRAMEPOINTER is not set
#
# PIC32MX Configuration Options
@@ -245,7 +242,7 @@ CONFIG_ARCH_VECNOTIRQ=y
CONFIG_ARCH_IRQPRIO=y
# CONFIG_CUSTOM_STACK is not set
# CONFIG_ADDRENV is not set
-# CONFIG_ARCH_HAVE_VFORK is not set
+CONFIG_ARCH_HAVE_VFORK=y
CONFIG_ARCH_STACKDUMP=y
# CONFIG_ENDIAN_BIG is not set
CONFIG_ARCH_HAVE_RAMFUNCS=y
@@ -308,7 +305,7 @@ CONFIG_DEV_CONSOLE=y
# CONFIG_FDCLONE_STDIO is not set
CONFIG_SDCLONE_DISABLE=y
# CONFIG_SCHED_WORKQUEUE is not set
-# CONFIG_SCHED_WAITPID is not set
+CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_ATEXIT is not set
# CONFIG_SCHED_ONEXIT is not set
CONFIG_USER_ENTRYPOINT="ostest_main"
diff --git a/nuttx/sched/task_vfork.c b/nuttx/sched/task_vfork.c
index 4b42c7b36..46b2d8e9f 100644
--- a/nuttx/sched/task_vfork.c
+++ b/nuttx/sched/task_vfork.c
@@ -287,7 +287,11 @@ pid_t task_vforkstart(FAR _TCB *child)
#endif
#else
- /* Again exploiting that execv() bug: Check if the child thread is
+ /* The following logic does not appear to work... It gets stuff in an
+ * infinite kill() loop and hogs the processor. Therefore, it looks
+ * as though CONFIG_SCHED_WAITPID may be a requirement to used vfork().
+ *
+ * Again exploiting that execv() bug: Check if the child thread is
* still running.
*/
@@ -331,4 +335,4 @@ void task_vforkabort(FAR _TCB *child, int errcode)
sched_releasetcb(child);
set_errno(errcode);
-}
\ No newline at end of file
+}
--
cgit v1.2.3
|