diff options
-rw-r--r-- | apps/examples/ostest/Makefile | 2 | ||||
-rw-r--r-- | apps/examples/ostest/ostest.h | 3 | ||||
-rw-r--r-- | apps/examples/ostest/ostest_main.c | 3 | ||||
-rw-r--r-- | apps/examples/ostest/vfork.c | 9 | ||||
-rw-r--r-- | nuttx/configs/stm32f3discovery/ostest/defconfig | 2 | ||||
-rw-r--r-- | nuttx/sched/Makefile | 8 | ||||
-rw-r--r-- | nuttx/sched/task_vfork.c | 34 |
7 files changed, 24 insertions, 37 deletions
diff --git a/apps/examples/ostest/Makefile b/apps/examples/ostest/Makefile index fd8ef79e0..e0265fc31 100644 --- a/apps/examples/ostest/Makefile +++ b/apps/examples/ostest/Makefile @@ -89,8 +89,10 @@ CSRCS += posixtimer.c endif ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) +ifeq ($(CONFIG_SCHED_WAITPID),y) CSRCS += vfork.c endif +endif ifneq ($(CONFIG_DISABLE_SIGNALS),y) ifneq ($(CONFIG_DISABLE_PTHREAD),y) diff --git a/apps/examples/ostest/ostest.h b/apps/examples/ostest/ostest.h index 9c6bb082b..d5016540b 100644 --- a/apps/examples/ostest/ostest.h +++ b/apps/examples/ostest/ostest.h @@ -175,7 +175,8 @@ void priority_inheritance(void); /* vfork.c ******************************************************************/ -#ifdef CONFIG_ARCH_HAVE_VFORK +#if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID) && \ + !defined(CONFIG_DISABLE_SIGNALS) int vfork_test(void); #endif diff --git a/apps/examples/ostest/ostest_main.c b/apps/examples/ostest/ostest_main.c index 978f72f9e..21f5e6077 100644 --- a/apps/examples/ostest/ostest_main.c +++ b/apps/examples/ostest/ostest_main.c @@ -451,7 +451,8 @@ static int user_main(int argc, char *argv[]) check_test_memory_usage(); #endif /* CONFIG_PRIORITY_INHERITANCE && !CONFIG_DISABLE_SIGNALS && !CONFIG_DISABLE_PTHREAD */ -#ifdef CONFIG_ARCH_HAVE_VFORK +#if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID) && \ + !defined(CONFIG_DISABLE_SIGNALS) printf("\nuser_main: vfork() test\n"); vfork_test(); #endif diff --git a/apps/examples/ostest/vfork.c b/apps/examples/ostest/vfork.c index 4e1b8c892..fd99d1aea 100644 --- a/apps/examples/ostest/vfork.c +++ b/apps/examples/ostest/vfork.c @@ -47,6 +47,9 @@ #include "ostest.h" +#if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID) && \ + !defined(CONFIG_DISABLE_SIGNALS) + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -55,9 +58,7 @@ * Private Data ****************************************************************************/ -#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS) static volatile bool g_vforkchild; -#endif /**************************************************************************** * Public Functions @@ -65,7 +66,6 @@ static volatile bool g_vforkchild; int vfork_test(void) { -#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS) pid_t pid; g_vforkchild = false; @@ -97,7 +97,8 @@ int vfork_test(void) return -1; } } -#endif return 0; } + +#endif /* CONFIG_ARCH_HAVE_VFORK && CONFIG_SCHED_WAITPID && !CONFIG_DISABLE_SIGNALS */ diff --git a/nuttx/configs/stm32f3discovery/ostest/defconfig b/nuttx/configs/stm32f3discovery/ostest/defconfig index 8dad4a846..f5a51ccc5 100644 --- a/nuttx/configs/stm32f3discovery/ostest/defconfig +++ b/nuttx/configs/stm32f3discovery/ostest/defconfig @@ -280,7 +280,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_STARTHOOK is not set # CONFIG_SCHED_ATEXIT is not set # CONFIG_SCHED_ONEXIT is not set diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile index f7445142c..ffb6e0004 100644 --- a/nuttx/sched/Makefile +++ b/nuttx/sched/Makefile @@ -44,11 +44,17 @@ MISC_SRCS += sched_garbage.c sched_getfiles.c sched_getsockets.c sched_getstream TSK_SRCS = prctl.c exit.c getpid.c TSK_SRCS += task_create.c task_init.c task_setup.c task_activate.c task_start.c TSK_SRCS += task_delete.c task_deletecurrent.c task_exithook.c task_recover.c -TSK_SRCS += task_restart.c task_spawn.c task_spawnparms.c task_vfork.c +TSK_SRCS += task_restart.c task_spawn.c task_spawnparms.c TSK_SRCS += sched_addreadytorun.c sched_removereadytorun.c sched_addprioritized.c TSK_SRCS += sched_mergepending.c sched_addblocked.c sched_removeblocked.c TSK_SRCS += sched_free.c sched_gettcb.c sched_verifytcb.c sched_releasetcb.c +ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) +ifeq ($(CONFIG_SCHED_WAITPID),y) +TSK_SRCS += task_vfork.c +endif +endif + ifneq ($(CONFIG_BINFMT_DISABLE),y) ifeq ($(CONFIG_LIBC_EXECFUNCS),y) TSK_SRCS += task_posixspawn.c diff --git a/nuttx/sched/task_vfork.c b/nuttx/sched/task_vfork.c index 7008a016e..58b4152ed 100644 --- a/nuttx/sched/task_vfork.c +++ b/nuttx/sched/task_vfork.c @@ -54,6 +54,9 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* vfork() requires architecture-specific support as well as waipid(). */ + +#if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID) /**************************************************************************** * Private Functions @@ -220,9 +223,7 @@ pid_t task_vforkstart(FAR struct task_tcb_s *child) #endif FAR const char *name; pid_t pid; -#ifdef CONFIG_SCHED_WAITPID int rc; -#endif int ret; svdbg("Starting Child TCB=%p, parent=%p\n", child, g_readytorun.head); @@ -279,8 +280,6 @@ pid_t task_vforkstart(FAR struct task_tcb_s *child) * after the parent thread again? */ -#ifdef CONFIG_SCHED_WAITPID - /* We can also exploit a bug in the execv() implementation: The PID * of the task exec'ed by the child will not be the same as the PID of * the child task. Therefore, waitpid() on the child task's PID will @@ -299,31 +298,6 @@ pid_t task_vforkstart(FAR struct task_tcb_s *child) (void)waitpid(pid, &rc, 0); #endif -#else - /* 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. - */ - - 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 - * not depend on prioirities: It will halt the parent thread for one - * system clock tick. This will delay the return to the parent thread. - */ - -#ifndef CONFIG_DISABLE_SIGNALS - sleep(0); -#else - sched_yield(); -#endif - } -#endif - return pid; } @@ -349,3 +323,5 @@ void task_vforkabort(FAR struct task_tcb_s *child, int errcode) sched_releasetcb((FAR struct tcb_s *)child); set_errno(errcode); } + +#endif /* CONFIG_ARCH_HAVE_VFORK && CONFIG_SCHED_WAITPID */ |