sched/task/fork: add fork implementation

1. as we can use fork to implement vfork, so we rename the vfork to
fork, and use the fork method as the base to implement vfork method
2. create the vfork function as a libc function based on fork
function

Signed-off-by: guoshichao <guoshichao@xiaomi.com>
This commit is contained in:
guoshichao
2023-07-05 21:43:50 +08:00
committed by Xiang Xiao
parent 5d7864fbcb
commit c33d1c9c97
39 changed files with 797 additions and 740 deletions
+5 -5
View File
@@ -11,7 +11,7 @@ config ARCH_ARM
bool "ARM" bool "ARM"
select ARCH_HAVE_BACKTRACE select ARCH_HAVE_BACKTRACE
select ARCH_HAVE_INTERRUPTSTACK select ARCH_HAVE_INTERRUPTSTACK
select ARCH_HAVE_VFORK select ARCH_HAVE_FORK
select ARCH_HAVE_STACKCHECK select ARCH_HAVE_STACKCHECK
select ARCH_HAVE_CUSTOMOPT select ARCH_HAVE_CUSTOMOPT
select ARCH_HAVE_STDARG_H select ARCH_HAVE_STDARG_H
@@ -27,7 +27,7 @@ config ARCH_ARM64
select ALARM_ARCH select ALARM_ARCH
select ARCH_HAVE_BACKTRACE select ARCH_HAVE_BACKTRACE
select ARCH_HAVE_INTERRUPTSTACK select ARCH_HAVE_INTERRUPTSTACK
select ARCH_HAVE_VFORK select ARCH_HAVE_FORK
select ARCH_HAVE_STACKCHECK select ARCH_HAVE_STACKCHECK
select ARCH_HAVE_CUSTOMOPT select ARCH_HAVE_CUSTOMOPT
select ARCH_HAVE_STDARG_H select ARCH_HAVE_STDARG_H
@@ -81,7 +81,7 @@ config ARCH_RISCV
select ARCH_HAVE_CPUINFO select ARCH_HAVE_CPUINFO
select ARCH_HAVE_INTERRUPTSTACK select ARCH_HAVE_INTERRUPTSTACK
select ARCH_HAVE_STACKCHECK select ARCH_HAVE_STACKCHECK
select ARCH_HAVE_VFORK select ARCH_HAVE_FORK
select ARCH_HAVE_CUSTOMOPT select ARCH_HAVE_CUSTOMOPT
select ARCH_HAVE_SETJMP select ARCH_HAVE_SETJMP
select ARCH_HAVE_STDARG_H select ARCH_HAVE_STDARG_H
@@ -101,7 +101,7 @@ config ARCH_SIM
select ARCH_HAVE_TICKLESS select ARCH_HAVE_TICKLESS
select ARCH_HAVE_POWEROFF select ARCH_HAVE_POWEROFF
select ARCH_HAVE_TESTSET select ARCH_HAVE_TESTSET
select ARCH_HAVE_VFORK if !HOST_WINDOWS select ARCH_HAVE_FORK if !HOST_WINDOWS
select ARCH_HAVE_SETJMP select ARCH_HAVE_SETJMP
select ARCH_HAVE_CUSTOMOPT select ARCH_HAVE_CUSTOMOPT
select ARCH_HAVE_TEXT_HEAP select ARCH_HAVE_TEXT_HEAP
@@ -392,7 +392,7 @@ config ARCH_HAVE_MULTICPU
bool bool
default n default n
config ARCH_HAVE_VFORK config ARCH_HAVE_FORK
bool bool
default n default n
+2 -2
View File
@@ -25,7 +25,7 @@ CMN_CSRCS += arm_getintstack.c arm_initialize.c arm_lowputs.c
CMN_CSRCS += arm_modifyreg8.c arm_modifyreg16.c arm_modifyreg32.c CMN_CSRCS += arm_modifyreg8.c arm_modifyreg16.c arm_modifyreg32.c
CMN_CSRCS += arm_nputs.c arm_releasestack.c arm_registerdump.c CMN_CSRCS += arm_nputs.c arm_releasestack.c arm_registerdump.c
CMN_CSRCS += arm_stackframe.c arm_switchcontext.c CMN_CSRCS += arm_stackframe.c arm_switchcontext.c
CMN_CSRCS += arm_usestack.c arm_vfork.c CMN_CSRCS += arm_usestack.c arm_fork.c
ifneq ($(CONFIG_ALARM_ARCH),y) ifneq ($(CONFIG_ALARM_ARCH),y)
ifneq ($(CONFIG_TIMER_ARCH),y) ifneq ($(CONFIG_TIMER_ARCH),y)
@@ -73,7 +73,7 @@ ifeq ($(CONFIG_UNWINDER_ARM),y)
CMN_CSRCS += arm_backtrace_unwind.c CMN_CSRCS += arm_backtrace_unwind.c
endif endif
CMN_ASRCS += vfork.S CMN_ASRCS += fork.S
ifeq ($(CONFIG_ARCH_HAVE_TESTSET),y) ifeq ($(CONFIG_ARCH_HAVE_TESTSET),y)
ifeq ($(CONFIG_ARCH_ARMV6M),) ifeq ($(CONFIG_ARCH_ARMV6M),)
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/common/arm_vfork.c * arch/arm/src/common/arm_fork.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -35,7 +35,7 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <arch/irq.h> #include <arch/irq.h>
#include "arm_vfork.h" #include "arm_fork.h"
#include "arm_internal.h" #include "arm_internal.h"
#include "sched/sched.h" #include "sched/sched.h"
@@ -44,22 +44,22 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: up_vfork * Name: up_fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* The overall sequence is: * The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -67,27 +67,27 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* nxtask_abort_vfork() may be called if an error occurs between steps 3 and * nxtask_abort_fork() may be called if an error occurs between steps 3 and
* 6. * 6.
* *
* Input Parameters: * Input Parameters:
* context - Caller context information saved by vfork() * context - Caller context information saved by fork()
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
pid_t up_vfork(const struct vfork_s *context) pid_t up_fork(const struct fork_s *context)
{ {
struct tcb_s *parent = this_task(); struct tcb_s *parent = this_task();
struct task_tcb_s *child; struct task_tcb_s *child;
@@ -97,7 +97,7 @@ pid_t up_vfork(const struct vfork_s *context)
uint32_t stacktop; uint32_t stacktop;
uint32_t stackutil; uint32_t stackutil;
sinfo("vfork context [%p]:\n", context); sinfo("fork context [%p]:\n", context);
sinfo(" r4:%08" PRIx32 " r5:%08" PRIx32 sinfo(" r4:%08" PRIx32 " r5:%08" PRIx32
" r6:%08" PRIx32 " r7:%08" PRIx32 "\n", " r6:%08" PRIx32 " r7:%08" PRIx32 "\n",
context->r4, context->r5, context->r6, context->r7); context->r4, context->r5, context->r6, context->r7);
@@ -108,10 +108,10 @@ pid_t up_vfork(const struct vfork_s *context)
/* Allocate and initialize a TCB for the child task. */ /* Allocate and initialize a TCB for the child task. */
child = nxtask_setup_vfork((start_t)(context->lr & ~1)); child = nxtask_setup_fork((start_t)(context->lr & ~1));
if (!child) if (!child)
{ {
serr("ERROR: nxtask_setup_vfork failed\n"); serr("ERROR: nxtask_setup_fork failed\n");
return (pid_t)ERROR; return (pid_t)ERROR;
} }
@@ -133,7 +133,7 @@ pid_t up_vfork(const struct vfork_s *context)
/* Make some feeble effort to preserve the stack contents. This is /* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other * feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the * content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble * user follows all of the caveats of fork() usage, even this feeble
* effort is overkill. * effort is overkill.
*/ */
@@ -229,9 +229,9 @@ pid_t up_vfork(const struct vfork_s *context)
} }
#endif #endif
/* And, finally, start the child task. On a failure, nxtask_start_vfork() /* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_vfork(). * will discard the TCB by calling nxtask_abort_fork().
*/ */
return nxtask_start_vfork(child); return nxtask_start_fork(child);
} }
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/common/arm_vfork.h * arch/arm/src/common/arm_fork.h
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -18,8 +18,8 @@
* *
****************************************************************************/ ****************************************************************************/
#ifndef __ARCH_ARM_SRC_COMMON_ARM_VFORK_H #ifndef __ARCH_ARM_SRC_COMMON_ARM_FORK_H
#define __ARCH_ARM_SRC_COMMON_ARM_VFORK_H #define __ARCH_ARM_SRC_COMMON_ARM_FORK_H
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
@@ -31,26 +31,26 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define VFORK_R4_OFFSET (0*4) /* Volatile register r4 */ #define FORK_R4_OFFSET (0*4) /* Volatile register r4 */
#define VFORK_R5_OFFSET (1*4) /* Volatile register r5 */ #define FORK_R5_OFFSET (1*4) /* Volatile register r5 */
#define VFORK_R6_OFFSET (2*4) /* Volatile register r6 */ #define FORK_R6_OFFSET (2*4) /* Volatile register r6 */
#define VFORK_R7_OFFSET (3*4) /* Volatile register r7 */ #define FORK_R7_OFFSET (3*4) /* Volatile register r7 */
#define VFORK_R8_OFFSET (4*4) /* Volatile register r8 */ #define FORK_R8_OFFSET (4*4) /* Volatile register r8 */
#define VFORK_R9_OFFSET (5*4) /* Volatile register r9 */ #define FORK_R9_OFFSET (5*4) /* Volatile register r9 */
#define VFORK_R10_OFFSET (6*4) /* Volatile register r10 */ #define FORK_R10_OFFSET (6*4) /* Volatile register r10 */
#define VFORK_FP_OFFSET (7*4) /* Frame pointer */ #define FORK_FP_OFFSET (7*4) /* Frame pointer */
#define VFORK_SP_OFFSET (8*4) /* Stack pointer*/ #define FORK_SP_OFFSET (8*4) /* Stack pointer*/
#define VFORK_LR_OFFSET (9*4) /* Return address*/ #define FORK_LR_OFFSET (9*4) /* Return address*/
#define VFORK_SIZEOF (10*4) #define FORK_SIZEOF (10*4)
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
struct vfork_s struct fork_s
{ {
/* CPU registers */ /* CPU registers */
@@ -70,4 +70,4 @@ struct vfork_s
}; };
#endif #endif
#endif /* __ARCH_ARM_SRC_COMMON_ARM_VFORK_H */ #endif /* __ARCH_ARM_SRC_COMMON_ARM_FORK_H */
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/common/vfork.S * arch/arm/src/common/fork.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -24,33 +24,33 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include "arm_vfork.h" #include "arm_fork.h"
.syntax unified .syntax unified
.file "vfork.S" .file "fork.S"
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the * This thin layer implements fork by simply calling up_fork() with the
* vfork() context as an argument. The overall sequence is: * fork() context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -58,31 +58,31 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
.globl vfork .globl fork
.type vfork, function .type fork, function
vfork: fork:
/* Create a stack frame */ /* Create a stack frame */
mov r0, sp /* Save the value of the stack on entry */ mov r0, sp /* Save the value of the stack on entry */
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */ sub sp, sp, #FORK_SIZEOF /* Allocate the structure on the stack */
/* CPU registers */ /* CPU registers */
/* Save the volatile registers */ /* Save the volatile registers */
@@ -97,22 +97,22 @@ vfork:
mov r5, lr /* Copy lr to a low register */ mov r5, lr /* Copy lr to a low register */
stmia r1!, {r0,r5} /* Save sp and lr in the structure */ stmia r1!, {r0,r5} /* Save sp and lr in the structure */
/* Then, call up_vfork(), passing it a pointer to the stack structure */ /* Then, call up_fork(), passing it a pointer to the stack structure */
mov r0, sp mov r0, sp
bl up_vfork bl up_fork
/* Recover r4-r7 that were destroyed before up_vfork was called */ /* Recover r4-r7 that were destroyed before up_fork was called */
mov r1, sp mov r1, sp
ldmia r1!, {r4-r7} ldmia r1!, {r4-r7}
/* Release the stack data and return the value returned by up_vfork */ /* Release the stack data and return the value returned by up_fork */
ldr r1, [sp, #VFORK_LR_OFFSET] ldr r1, [sp, #FORK_LR_OFFSET]
mov r14, r1 mov r14, r1
add sp, sp, #VFORK_SIZEOF add sp, sp, #FORK_SIZEOF
bx lr bx lr
.size vfork, .-vfork .size fork, .-fork
.end .end
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/common/iar/vfork.S * arch/arm/src/common/iar/fork.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -24,9 +24,9 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include "arm_vfork.h" #include "arm_fork.h"
MODULE vfork MODULE fork
SECTION .text:CODE:NOROOT(2) SECTION .text:CODE:NOROOT(2)
/**************************************************************************** /****************************************************************************
@@ -37,31 +37,31 @@
* Public Symbols * Public Symbols
****************************************************************************/ ****************************************************************************/
PUBLIC vfork PUBLIC fork
EXTERN up_vfork EXTERN up_fork
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the * This thin layer implements fork by simply calling up_fork() with the
* vfork() context as an argument. The overall sequence is: * fork() context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -69,17 +69,17 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
@@ -88,40 +88,40 @@
THUMB THUMB
vfork: fork:
/* Create a stack frame */ /* Create a stack frame */
mov r0, sp /* Save the value of the stack on entry */ mov r0, sp /* Save the value of the stack on entry */
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */ sub sp, sp, #FORK_SIZEOF /* Allocate the structure on the stack */
/* CPU registers */ /* CPU registers */
/* Save the volatile registers */ /* Save the volatile registers */
str r4, [sp, #VFORK_R4_OFFSET] str r4, [sp, #FORK_R4_OFFSET]
str r5, [sp, #VFORK_R5_OFFSET] str r5, [sp, #FORK_R5_OFFSET]
str r6, [sp, #VFORK_R6_OFFSET] str r6, [sp, #FORK_R6_OFFSET]
str r7, [sp, #VFORK_R7_OFFSET] str r7, [sp, #FORK_R7_OFFSET]
str r8, [sp, #VFORK_R8_OFFSET] str r8, [sp, #FORK_R8_OFFSET]
str r9, [sp, #VFORK_R9_OFFSET] str r9, [sp, #FORK_R9_OFFSET]
str r10, [sp, #VFORK_R10_OFFSET] str r10, [sp, #FORK_R10_OFFSET]
/* Save the frame pointer, stack pointer, and return address */ /* Save the frame pointer, stack pointer, and return address */
str r11, [sp, #VFORK_FP_OFFSET] /* fp not defined. use r11 */ str r11, [sp, #FORK_FP_OFFSET] /* fp not defined. use r11 */
str r0, [sp, #VFORK_SP_OFFSET] str r0, [sp, #FORK_SP_OFFSET]
str lr, [sp, #VFORK_LR_OFFSET] str lr, [sp, #FORK_LR_OFFSET]
/* Floating point registers (not yet) */ /* Floating point registers (not yet) */
/* Then, call up_vfork(), passing it a pointer to the stack structure */ /* Then, call up_fork(), passing it a pointer to the stack structure */
mov r0, sp mov r0, sp
bl up_vfork bl up_fork
/* Release the stack data and return the value returned by up_vfork */ /* Release the stack data and return the value returned by up_fork */
ldr lr, [sp, #VFORK_LR_OFFSET] ldr lr, [sp, #FORK_LR_OFFSET]
add sp, sp, #VFORK_SIZEOF add sp, sp, #FORK_SIZEOF
bx lr bx lr
END END
+2 -2
View File
@@ -35,7 +35,7 @@ endif
# Common assembly language files # Common assembly language files
CMN_ASRCS = arm64_vector_table.S arm64_vectors.S arm64_smccc.S CMN_ASRCS = arm64_vector_table.S arm64_vectors.S arm64_smccc.S
CMN_ASRCS += arm64_cpu_idle.S arm64_vfork_func.S CMN_ASRCS += arm64_cpu_idle.S arm64_fork_func.S
ifeq ($(CONFIG_ARCH_HAVE_TESTSET),y) ifeq ($(CONFIG_ARCH_HAVE_TESTSET),y)
CMN_ASRCS += arm64_testset.S CMN_ASRCS += arm64_testset.S
@@ -45,7 +45,7 @@ endif
CMN_CSRCS = arm64_initialize.c arm64_initialstate.c arm64_boot.c CMN_CSRCS = arm64_initialize.c arm64_initialstate.c arm64_boot.c
CMN_CSRCS += arm64_nputs.c arm64_idle.c arm64_copystate.c arm64_createstack.c CMN_CSRCS += arm64_nputs.c arm64_idle.c arm64_copystate.c arm64_createstack.c
CMN_CSRCS += arm64_releasestack.c arm64_stackframe.c arm64_usestack.c CMN_CSRCS += arm64_releasestack.c arm64_stackframe.c arm64_usestack.c
CMN_CSRCS += arm64_task_sched.c arm64_exit.c arm64_vfork.c arm64_switchcontext.c CMN_CSRCS += arm64_task_sched.c arm64_exit.c arm64_fork.c arm64_switchcontext.c
CMN_CSRCS += arm64_schedulesigaction.c arm64_sigdeliver.c CMN_CSRCS += arm64_schedulesigaction.c arm64_sigdeliver.c
CMN_CSRCS += arm64_getintstack.c arm64_registerdump.c CMN_CSRCS += arm64_getintstack.c arm64_registerdump.c
CMN_CSRCS += arm64_perf.c CMN_CSRCS += arm64_perf.c
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/arm64/src/common/arm64_vfork.c * arch/arm64/src/common/arm64_fork.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -37,7 +37,7 @@
#include "sched/sched.h" #include "sched/sched.h"
#include "arm64_arch.h" #include "arm64_arch.h"
#include "arm64_vfork.h" #include "arm64_fork.h"
#include "arm64_internal.h" #include "arm64_internal.h"
#include "arm64_fatal.h" #include "arm64_fatal.h"
@@ -55,7 +55,7 @@
#ifdef CONFIG_ARCH_FPU #ifdef CONFIG_ARCH_FPU
void arm64_vfork_fpureg_save(struct vfork_s *context) void arm64_fork_fpureg_save(struct fork_s *context)
{ {
irqstate_t flags; irqstate_t flags;
@@ -75,22 +75,22 @@ void arm64_vfork_fpureg_save(struct vfork_s *context)
#endif #endif
/**************************************************************************** /****************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* The overall sequence is: * The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -98,27 +98,27 @@ void arm64_vfork_fpureg_save(struct vfork_s *context)
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* nxtask_abort_vfork() may be called if an error occurs between steps 3 and * nxtask_abort_fork() may be called if an error occurs between steps 3 and
* 6. * 6.
* *
* Input Parameters: * Input Parameters:
* context - Caller context information saved by vfork() * context - Caller context information saved by fork()
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
pid_t up_vfork(const struct vfork_s *context) pid_t up_fork(const struct fork_s *context)
{ {
struct tcb_s *parent = this_task(); struct tcb_s *parent = this_task();
struct task_tcb_s *child; struct task_tcb_s *child;
@@ -128,17 +128,17 @@ pid_t up_vfork(const struct vfork_s *context)
uint64_t stacktop; uint64_t stacktop;
uint64_t stackutil; uint64_t stackutil;
char *stack_ptr; char *stack_ptr;
struct regs_context *pvforkctx; struct regs_context *pforkctx;
#ifdef CONFIG_ARCH_FPU #ifdef CONFIG_ARCH_FPU
struct fpu_reg *pfpuctx; struct fpu_reg *pfpuctx;
#endif #endif
/* Allocate and initialize a TCB for the child task. */ /* Allocate and initialize a TCB for the child task. */
child = nxtask_setup_vfork((start_t)(context->lr & ~1)); child = nxtask_setup_fork((start_t)(context->lr & ~1));
if (!child) if (!child)
{ {
serr("ERROR: nxtask_setup_vfork failed\n"); serr("ERROR: nxtask_setup_fork failed\n");
return (pid_t)ERROR; return (pid_t)ERROR;
} }
@@ -156,7 +156,7 @@ pid_t up_vfork(const struct vfork_s *context)
/* Make some feeble effort to preserve the stack contents. This is /* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other * feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the * content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble * user follows all of the caveats of fork() usage, even this feeble
* effort is overkill. * effort is overkill.
*/ */
@@ -184,7 +184,7 @@ pid_t up_vfork(const struct vfork_s *context)
* child thread. * child thread.
*/ */
/* make the vfork stack frame */ /* make the fork stack frame */
stack_ptr = (char *)newsp; stack_ptr = (char *)newsp;
@@ -198,51 +198,51 @@ pid_t up_vfork(const struct vfork_s *context)
#endif #endif
pvforkctx = STACK_PTR_TO_FRAME(struct regs_context, stack_ptr); pforkctx = STACK_PTR_TO_FRAME(struct regs_context, stack_ptr);
pvforkctx->regs[REG_X0] = 0; pforkctx->regs[REG_X0] = 0;
pvforkctx->regs[REG_X8] = context->regs[VFORK_REG_X8]; pforkctx->regs[REG_X8] = context->regs[FORK_REG_X8];
pvforkctx->regs[REG_X9] = context->regs[VFORK_REG_X9]; pforkctx->regs[REG_X9] = context->regs[FORK_REG_X9];
pvforkctx->regs[REG_X10] = context->regs[VFORK_REG_X10]; pforkctx->regs[REG_X10] = context->regs[FORK_REG_X10];
pvforkctx->regs[REG_X11] = context->regs[VFORK_REG_X11]; pforkctx->regs[REG_X11] = context->regs[FORK_REG_X11];
pvforkctx->regs[REG_X12] = context->regs[VFORK_REG_X12]; pforkctx->regs[REG_X12] = context->regs[FORK_REG_X12];
pvforkctx->regs[REG_X13] = context->regs[VFORK_REG_X13]; pforkctx->regs[REG_X13] = context->regs[FORK_REG_X13];
pvforkctx->regs[REG_X14] = context->regs[VFORK_REG_X14]; pforkctx->regs[REG_X14] = context->regs[FORK_REG_X14];
pvforkctx->regs[REG_X15] = context->regs[VFORK_REG_X15]; pforkctx->regs[REG_X15] = context->regs[FORK_REG_X15];
pvforkctx->regs[REG_X16] = context->regs[VFORK_REG_X16]; pforkctx->regs[REG_X16] = context->regs[FORK_REG_X16];
pvforkctx->regs[REG_X17] = context->regs[VFORK_REG_X17]; pforkctx->regs[REG_X17] = context->regs[FORK_REG_X17];
pvforkctx->regs[REG_X18] = context->regs[VFORK_REG_X18]; pforkctx->regs[REG_X18] = context->regs[FORK_REG_X18];
pvforkctx->regs[REG_X19] = context->regs[VFORK_REG_X19]; pforkctx->regs[REG_X19] = context->regs[FORK_REG_X19];
pvforkctx->regs[REG_X20] = context->regs[VFORK_REG_X20]; pforkctx->regs[REG_X20] = context->regs[FORK_REG_X20];
pvforkctx->regs[REG_X21] = context->regs[VFORK_REG_X21]; pforkctx->regs[REG_X21] = context->regs[FORK_REG_X21];
pvforkctx->regs[REG_X22] = context->regs[VFORK_REG_X22]; pforkctx->regs[REG_X22] = context->regs[FORK_REG_X22];
pvforkctx->regs[REG_X23] = context->regs[VFORK_REG_X23]; pforkctx->regs[REG_X23] = context->regs[FORK_REG_X23];
pvforkctx->regs[REG_X24] = context->regs[VFORK_REG_X24]; pforkctx->regs[REG_X24] = context->regs[FORK_REG_X24];
pvforkctx->regs[REG_X25] = context->regs[VFORK_REG_X25]; pforkctx->regs[REG_X25] = context->regs[FORK_REG_X25];
pvforkctx->regs[REG_X26] = context->regs[VFORK_REG_X26]; pforkctx->regs[REG_X26] = context->regs[FORK_REG_X26];
pvforkctx->regs[REG_X27] = context->regs[VFORK_REG_X27]; pforkctx->regs[REG_X27] = context->regs[FORK_REG_X27];
pvforkctx->regs[REG_X28] = context->regs[VFORK_REG_X28]; pforkctx->regs[REG_X28] = context->regs[FORK_REG_X28];
pvforkctx->regs[REG_X29] = newfp; pforkctx->regs[REG_X29] = newfp;
pvforkctx->spsr = SPSR_MODE_EL1H; pforkctx->spsr = SPSR_MODE_EL1H;
#ifdef CONFIG_SUPPRESS_INTERRUPTS #ifdef CONFIG_SUPPRESS_INTERRUPTS
pvforkctx->spsr |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT); pforkctx->spsr |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT);
#endif /* CONFIG_SUPPRESS_INTERRUPTS */ #endif /* CONFIG_SUPPRESS_INTERRUPTS */
pvforkctx->elr = (uint64_t)context->lr; pforkctx->elr = (uint64_t)context->lr;
pvforkctx->exe_depth = 0; pforkctx->exe_depth = 0;
pvforkctx->sp_elx = (uint64_t)pvforkctx; pforkctx->sp_elx = (uint64_t)pforkctx;
pvforkctx->sp_el0 = (uint64_t)pvforkctx; pforkctx->sp_el0 = (uint64_t)pforkctx;
pvforkctx->tpidr_el0 = (uint64_t)(&child->cmn); pforkctx->tpidr_el0 = (uint64_t)(&child->cmn);
pvforkctx->tpidr_el1 = (uint64_t)(&child->cmn); pforkctx->tpidr_el1 = (uint64_t)(&child->cmn);
child->cmn.xcp.regs = (uint64_t *)pvforkctx; child->cmn.xcp.regs = (uint64_t *)pforkctx;
/* And, finally, start the child task. On a failure, nxtask_start_vfork() /* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_vfork(). * will discard the TCB by calling nxtask_abort_fork().
*/ */
return nxtask_start_vfork(child); return nxtask_start_fork(child);
} }
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/arm64/src/common/arm64_vfork.h * arch/arm64/src/common/arm64_fork.h
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -18,8 +18,8 @@
* *
****************************************************************************/ ****************************************************************************/
#ifndef __ARCH_ARM_SRC_COMMON_ARM_VFORK_H #ifndef __ARCH_ARM_SRC_COMMON_ARM_FORK_H
#define __ARCH_ARM_SRC_COMMON_ARM_VFORK_H #define __ARCH_ARM_SRC_COMMON_ARM_FORK_H
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
@@ -32,48 +32,48 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define VFORK_REG_X0 (0) #define FORK_REG_X0 (0)
#define VFORK_REG_X1 (1) #define FORK_REG_X1 (1)
#define VFORK_REG_X2 (2) #define FORK_REG_X2 (2)
#define VFORK_REG_X3 (3) #define FORK_REG_X3 (3)
#define VFORK_REG_X4 (4) #define FORK_REG_X4 (4)
#define VFORK_REG_X5 (5) #define FORK_REG_X5 (5)
#define VFORK_REG_X6 (6) #define FORK_REG_X6 (6)
#define VFORK_REG_X7 (7) #define FORK_REG_X7 (7)
#define VFORK_REG_X8 (8) #define FORK_REG_X8 (8)
#define VFORK_REG_X9 (9) #define FORK_REG_X9 (9)
#define VFORK_REG_X10 (10) #define FORK_REG_X10 (10)
#define VFORK_REG_X11 (11) #define FORK_REG_X11 (11)
#define VFORK_REG_X12 (12) #define FORK_REG_X12 (12)
#define VFORK_REG_X13 (13) #define FORK_REG_X13 (13)
#define VFORK_REG_X14 (14) #define FORK_REG_X14 (14)
#define VFORK_REG_X15 (15) #define FORK_REG_X15 (15)
#define VFORK_REG_X16 (16) #define FORK_REG_X16 (16)
#define VFORK_REG_X17 (17) #define FORK_REG_X17 (17)
#define VFORK_REG_X18 (18) #define FORK_REG_X18 (18)
#define VFORK_REG_X19 (19) #define FORK_REG_X19 (19)
#define VFORK_REG_X20 (20) #define FORK_REG_X20 (20)
#define VFORK_REG_X21 (21) #define FORK_REG_X21 (21)
#define VFORK_REG_X22 (22) #define FORK_REG_X22 (22)
#define VFORK_REG_X23 (23) #define FORK_REG_X23 (23)
#define VFORK_REG_X24 (24) #define FORK_REG_X24 (24)
#define VFORK_REG_X25 (25) #define FORK_REG_X25 (25)
#define VFORK_REG_X26 (26) #define FORK_REG_X26 (26)
#define VFORK_REG_X27 (27) #define FORK_REG_X27 (27)
#define VFORK_REG_X28 (28) #define FORK_REG_X28 (28)
#define VFORK_REG_FP (29) /* Frame pointer*/ #define FORK_REG_FP (29) /* Frame pointer*/
#define VFORK_REG_LR (30) /* Return address*/ #define FORK_REG_LR (30) /* Return address*/
#define VFORK_REG_SP (31) /* Stack pointer*/ #define FORK_REG_SP (31) /* Stack pointer*/
#ifdef CONFIG_ARCH_FPU #ifdef CONFIG_ARCH_FPU
#define VFORK_REGS_SIZE (32 + XCPTCONTEXT_FPU_REGS) #define FORK_REGS_SIZE (32 + XCPTCONTEXT_FPU_REGS)
#else #else
#define VFORK_REGS_SIZE (32) #define FORK_REGS_SIZE (32)
#endif #endif
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
struct vfork_s struct fork_s
{ {
uint64_t regs[29]; uint64_t regs[29];
uint64_t fp; uint64_t fp;
@@ -86,4 +86,4 @@ struct vfork_s
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_COMMON_ARM_VFORK_H */ #endif /* __ARCH_ARM_SRC_COMMON_ARM_FORK_H */
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/arm64/src/common/arm64_vfork_func.S * arch/arm64/src/common/arm64_fork_func.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -26,36 +26,36 @@
#include "arch/syscall.h" #include "arch/syscall.h"
#include "arm64_macro.inc" #include "arm64_macro.inc"
#include "arm64_vfork.h" #include "arm64_fork.h"
/**************************************************************************** /****************************************************************************
* Public Symbols * Public Symbols
****************************************************************************/ ****************************************************************************/
.file "arm64_vfork_func.S" .file "arm64_fork_func.S"
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the * This thin layer implements fork by simply calling up_fork() with the
* vfork() context as an argument. The overall sequence is: * fork() context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -63,69 +63,70 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
GTEXT(vfork) GTEXT(fork)
SECTION_FUNC(text, vfork) SECTION_FUNC(text, fork)
/* Create a stack frame */ /* Create a stack frame */
mov x0, sp /* Save the value of the stack on entry */ mov x0, sp /* Save the value of the stack on entry */
stp x29, x30, [sp] stp x29, x30, [sp]
sub sp, sp, #8 * VFORK_REGS_SIZE /* Allocate the structure on the stack */ sub sp, sp, #8 * FORK_REGS_SIZE /* Allocate the structure on the stack */
/* CPU registers, save all register*/ /* CPU registers, save all register*/
stp x0, x1, [sp, #8 * VFORK_REG_X0] stp x0, x1, [sp, #8 * FORK_REG_X0]
stp x2, x3, [sp, #8 * VFORK_REG_X2] stp x2, x3, [sp, #8 * FORK_REG_X2]
stp x4, x5, [sp, #8 * VFORK_REG_X4] stp x4, x5, [sp, #8 * FORK_REG_X4]
stp x6, x7, [sp, #8 * VFORK_REG_X6] stp x6, x7, [sp, #8 * FORK_REG_X6]
stp x8, x9, [sp, #8 * VFORK_REG_X8] stp x8, x9, [sp, #8 * FORK_REG_X8]
stp x10, x11, [sp, #8 * VFORK_REG_X10] stp x10, x11, [sp, #8 * FORK_REG_X10]
stp x12, x13, [sp, #8 * VFORK_REG_X12] stp x12, x13, [sp, #8 * FORK_REG_X12]
stp x14, x15, [sp, #8 * VFORK_REG_X14] stp x14, x15, [sp, #8 * FORK_REG_X14]
stp x16, x17, [sp, #8 * VFORK_REG_X16] stp x16, x17, [sp, #8 * FORK_REG_X16]
stp x18, x19, [sp, #8 * VFORK_REG_X18] stp x18, x19, [sp, #8 * FORK_REG_X18]
stp x20, x21, [sp, #8 * VFORK_REG_X20] stp x20, x21, [sp, #8 * FORK_REG_X20]
stp x22, x23, [sp, #8 * VFORK_REG_X22] stp x22, x23, [sp, #8 * FORK_REG_X22]
stp x24, x25, [sp, #8 * VFORK_REG_X24] stp x24, x25, [sp, #8 * FORK_REG_X24]
stp x26, x27, [sp, #8 * VFORK_REG_X26] stp x26, x27, [sp, #8 * FORK_REG_X26]
stp x28, x29, [sp, #8 * VFORK_REG_X28] stp x28, x29, [sp, #8 * FORK_REG_X28]
/* Save the LR, stack pointer */ /* Save the LR, stack pointer */
stp x30, x0, [sp, #8 * VFORK_REG_LR] stp x30, x0, [sp, #8 * FORK_REG_LR]
/* Floating point registers */ /* Floating point registers */
#ifdef CONFIG_ARCH_FPU #ifdef CONFIG_ARCH_FPU
mov x0, sp mov x0, sp
stp x0, x30, [sp, #-16]! stp x0, x30, [sp, #-16]!
bl arm64_vfork_fpureg_save bl arm64_fork_fpureg_save
ldp x0, x30, [sp], #16 ldp x0, x30, [sp], #16
#endif #endif
/* Then, call up_vfork(), passing it a pointer to the stack structure */ /* Then, call up_fork(), passing it a pointer to the stack structure */
mov x0, sp mov x0, sp
bl up_vfork mov x1, #0
bl up_fork
/* Release the stack data and return the value returned by up_vfork */ /* Release the stack data and return the value returned by up_fork */
add sp, sp, #8 * VFORK_REGS_SIZE add sp, sp, #8 * FORK_REGS_SIZE
ldp x29, x30, [sp] ldp x29, x30, [sp]
ret ret
+1 -1
View File
@@ -42,7 +42,7 @@
#include "sched/sched.h" #include "sched/sched.h"
#include "arm64_arch.h" #include "arm64_arch.h"
#include "arm64_vfork.h" #include "arm64_fork.h"
#include "arm64_internal.h" #include "arm64_internal.h"
#include "arm64_fatal.h" #include "arm64_fatal.h"
#include "arm64_fpu.h" #include "arm64_fpu.h"
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/ceva/src/common/ceva_vfork.c * arch/ceva/src/common/ceva_fork.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -38,49 +38,49 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: up_vfork * Name: up_fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* The overall sequence is: * The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork()and calls nxtask_vforksetup(). * 2) up_fork()and calls nxtask_forksetup().
* 3) nxtask_vforksetup() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - Configuration of environment variables
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state() * - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_vforkstart() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* nxtask_vforkabort() may be called if an error occurs between steps 3 & 6. * nxtask_abort_fork() may be called if an error occurs between steps 3 & 6.
* *
* Input Parameters: * Input Parameters:
* regs - Caller context information saved by vfork() * regs - Caller context information saved by fork()
* *
* Return: * Return:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
pid_t up_vfork(const uint32_t *regs) pid_t up_fork(const uint32_t *regs)
{ {
#ifdef CONFIG_SCHED_WAITPID #ifdef CONFIG_SCHED_WAITPID
struct tcb_s *parent = this_task(); struct tcb_s *parent = this_task();
@@ -96,10 +96,10 @@ pid_t up_vfork(const uint32_t *regs)
/* Allocate and initialize a TCB for the child task. */ /* Allocate and initialize a TCB for the child task. */
child = nxtask_vforksetup(parent->start, &argsize); child = nxtask_setup_fork(parent->start, &argsize);
if (!child) if (!child)
{ {
serr("ERROR: nxtask_vforksetup failed\n"); serr("ERROR: nxtask_setup_fork failed\n");
return (pid_t)ERROR; return (pid_t)ERROR;
} }
@@ -116,7 +116,7 @@ pid_t up_vfork(const uint32_t *regs)
if (ret != OK) if (ret != OK)
{ {
serr("ERROR: up_create_stack failed: %d\n", ret); serr("ERROR: up_create_stack failed: %d\n", ret);
nxtask_vforkabort(child, -ret); nxtask_abort_fork(child, -ret);
return (pid_t)ERROR; return (pid_t)ERROR;
} }
@@ -139,7 +139,7 @@ pid_t up_vfork(const uint32_t *regs)
/* Make some feeble effort to preserve the stack contents. This is /* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other * feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the * content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble * user follows all of the caveats of fork() usage, even this feeble
* effort is overkill. * effort is overkill.
*/ */
@@ -197,11 +197,11 @@ pid_t up_vfork(const uint32_t *regs)
} }
#endif #endif
/* And, finally, start the child task. On a failure, nxtask_vforkstart() /* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_vforkabort(). * will discard the TCB by calling nxtask_abort_fork().
*/ */
return nxtask_vforkstart(child); return nxtask_start_fork(child);
#else /* CONFIG_SCHED_WAITPID */ #else /* CONFIG_SCHED_WAITPID */
return (pid_t)ERROR; return (pid_t)ERROR;
#endif #endif
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/ceva/src/xc5/vfork.S * arch/ceva/src/xc5/fork.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -31,48 +31,48 @@
* Public Symbols * Public Symbols
****************************************************************************/ ****************************************************************************/
.file "vfork.S" .file "fork.S"
.extern _up_vfork .extern _up_fork
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the behavior is * The fork() function has the same effect as posix fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than * undefined if the process created by fork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns * a variable of type pid_t used to store the return value from fork(), or returns
* from the function in which vfork() was called, or calls any other function before * from the function in which fork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions. * successfully calling _exit() or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the vfork() * This thin layer implements fork by simply calling up_fork() with the fork()
* context as an argument. The overall sequence is: * context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork()and calls nxtask_vforksetup(). * 2) up_fork()and calls nxtask_forksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB. This * 3) task_forksetup() allocates and configures the child task's TCB. This
* consists of: * consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - Configuration of environment variables
* - Setup the intput parameters for the task. * - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state() * - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart() * 5) up_fork() then calls nxtask_forkstart()
* 6) nxtask_vforkstart() then executes the child thread. * 6) nxtask_forkstart() then executes the child thread.
* *
* Input Paremeters: * Input Paremeters:
* None * None
* *
* Return: * Return:
* Upon successful completion, vfork() returns 0 to the child process and returns * Upon successful completion, fork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is * 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 * returned to the parent, no child process is created, and errno is set to
* indicate the error. * indicate the error.
@@ -80,10 +80,10 @@
****************************************************************************/ ****************************************************************************/
.text .text
.public _vfork .public _fork
.func_start 3 _vfork .func_start 3 _fork
_vfork: _fork:
/* Create a stack frame */ /* Create a stack frame */
subs sp, #XCPTCONTEXT_SIZE, sp subs sp, #XCPTCONTEXT_SIZE, sp
@@ -94,19 +94,19 @@ _vfork:
mov sp, a1 mov sp, a1
trap trap
/* Then, call up_vfork(), passing it a pointer to the stack structure */ /* Then, call up_fork(), passing it a pointer to the stack structure */
mov sp, a0 mov sp, a0
nop nop
push {dw} retreg push {dw} retreg
callr {t} _up_vfork callr {t} _up_fork
pop {dw} retreg pop {dw} retreg
nop nop
/* Release the stack data and return the value returned by up_vfork */ /* Release the stack data and return the value returned by up_fork */
adds sp, #XCPTCONTEXT_SIZE, sp adds sp, #XCPTCONTEXT_SIZE, sp
ret ret
.func_end 3 _vfork .func_end 3 _fork
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/ceva/src/xm6/vfork.S * arch/ceva/src/xm6/fork.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -41,48 +41,48 @@
* Public Symbols * Public Symbols
****************************************************************************/ ****************************************************************************/
.file "vfork.S" .file "fork.S"
.extern _up_vfork .extern _up_fork
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the behavior is * The fork() function has the same effect as posix fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than * undefined if the process created by fork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns * a variable of type pid_t used to store the return value from fork(), or returns
* from the function in which vfork() was called, or calls any other function before * from the function in which fork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions. * successfully calling _exit() or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the vfork() * This thin layer implements fork by simply calling up_fork() with the fork()
* context as an argument. The overall sequence is: * context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork()and calls nxtask_vforksetup(). * 2) up_fork()and calls nxtask_forksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB. This * 3) task_forksetup() allocates and configures the child task's TCB. This
* consists of: * consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
* - Configuration of environment variables * - Configuration of environment variables
* - Setup the intput parameters for the task. * - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state() * - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart() * 5) up_fork() then calls nxtask_forkstart()
* 6) nxtask_vforkstart() then executes the child thread. * 6) nxtask_forkstart() then executes the child thread.
* *
* Input Paremeters: * Input Paremeters:
* None * None
* *
* Return: * Return:
* Upon successful completion, vfork() returns 0 to the child process and returns * Upon successful completion, fork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is * 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 * returned to the parent, no child process is created, and errno is set to
* indicate the error. * indicate the error.
@@ -90,10 +90,10 @@
****************************************************************************/ ****************************************************************************/
.text .text
.public _vfork .public _fork
.func_start 3 _vfork .func_start 3 _fork
_vfork: _fork:
/* Create a stack frame */ /* Create a stack frame */
modr (sp.ui).ui +#-XCPTCONTEXT_SIZE /* Allocate the structure on the stack */ modr (sp.ui).ui +#-XCPTCONTEXT_SIZE /* Allocate the structure on the stack */
@@ -104,18 +104,18 @@ _vfork:
mov sp.ui, r1.ui mov sp.ui, r1.ui
trap {t0} trap {t0}
/* Then, call up_vfork(), passing it a pointer to the stack structure */ /* Then, call up_fork(), passing it a pointer to the stack structure */
mov sp.ui, r0.ui mov sp.ui, r0.ui
nop nop
push retreg.ui push retreg.ui
callr #_up_vfork, ?prx.b callr #_up_fork, ?prx.b
pop retreg.ui pop retreg.ui
nop nop
/* Release the stack data and return the value returned by up_vfork */ /* Release the stack data and return the value returned by up_fork */
modr (sp.ui).ui +#XCPTCONTEXT_SIZE modr (sp.ui).ui +#XCPTCONTEXT_SIZE
ret ?prx.b ret ?prx.b
.func_end 3 _vfork .func_end 3 _fork
+1 -1
View File
@@ -41,7 +41,7 @@ endchoice
config ARCH_MIPS32 config ARCH_MIPS32
bool bool
default n default n
select ARCH_HAVE_VFORK select ARCH_HAVE_FORK
config ARCH_MIPS_M4K config ARCH_MIPS_M4K
bool bool
+2 -2
View File
@@ -87,10 +87,10 @@ config MIPS32_TOOLCHAIN_MICROCHIP_XC32_LICENSED
config MIPS32_FRAMEPOINTER config MIPS32_FRAMEPOINTER
bool "ABI Uses Frame Pointer" bool "ABI Uses Frame Pointer"
default n default n
depends on ARCH_HAVE_VFORK depends on ARCH_HAVE_FORK
---help--- ---help---
Register r30 may be a frame pointer in some ABIs. Or may just be Register r30 may be a frame pointer in some ABIs. Or may just be
saved register s8. It makes a difference for vfork handling. saved register s8. It makes a difference for fork handling.
config MIPS32_HAVE_ICACHE config MIPS32_HAVE_ICACHE
bool bool
@@ -1,5 +1,5 @@
/************************************************************************************ /************************************************************************************
* arch/mips/src/mips32/vfork.S * arch/mips/src/mips32/fork.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -24,7 +24,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include "mips_vfork.h" #include "mips_fork.h"
/************************************************************************************ /************************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
@@ -34,30 +34,30 @@
* Public Symbols * Public Symbols
************************************************************************************/ ************************************************************************************/
.file "vfork.S" .file "fork.S"
.globl up_vfork .globl up_fork
/************************************************************************************ /************************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ************************************************************************************/
/************************************************************************************ /************************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the behavior is * The fork() function has the same effect as posix fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than * undefined if the process created by fork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns * a variable of type pid_t used to store the return value from fork(), or returns
* from the function in which vfork() was called, or calls any other function before * from the function in which fork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions. * successfully calling _exit() or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the vfork() * This thin layer implements fork by simply calling up_fork() with the fork()
* context as an argument. The overall sequence is: * context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This * 3) nxtask_setup_fork() allocates and configures the child task's TCB. This
* consists of: * consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -65,17 +65,17 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and returns * Upon successful completion, fork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is * 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 * returned to the parent, no child process is created, and errno is set to
* indicate the error. * indicate the error.
@@ -84,59 +84,59 @@
.text .text
.align 2 .align 2
.globl vfork .globl fork
.type vfork, function .type fork, function
.set nomips16 .set nomips16
#ifdef CONFIG_MIPS_MICROMIPS #ifdef CONFIG_MIPS_MICROMIPS
.set micromips .set micromips
#endif #endif
.ent vfork .ent fork
vfork: fork:
/* Create a stack frame */ /* Create a stack frame */
move $t0, $sp /* Save the value of the stack on entry */ move $t0, $sp /* Save the value of the stack on entry */
addiu $sp, $sp, -VFORK_SIZEOF /* Allocate the structure on the stack */ addiu $sp, $sp, -FORK_SIZEOF /* Allocate the structure on the stack */
/* CPU registers */ /* CPU registers */
/* Save the saved registers */ /* Save the saved registers */
sw $s0, VFORK_S0_OFFSET($sp) sw $s0, FORK_S0_OFFSET($sp)
sw $s1, VFORK_S1_OFFSET($sp) sw $s1, FORK_S1_OFFSET($sp)
sw $s2, VFORK_S2_OFFSET($sp) sw $s2, FORK_S2_OFFSET($sp)
sw $s3, VFORK_S3_OFFSET($sp) sw $s3, FORK_S3_OFFSET($sp)
sw $s4, VFORK_S4_OFFSET($sp) sw $s4, FORK_S4_OFFSET($sp)
sw $s5, VFORK_S5_OFFSET($sp) sw $s5, FORK_S5_OFFSET($sp)
sw $s6, VFORK_S6_OFFSET($sp) sw $s6, FORK_S6_OFFSET($sp)
sw $s7, VFORK_S7_OFFSET($sp) sw $s7, FORK_S7_OFFSET($sp)
#ifdef CONFIG_MIPS32_FRAMEPOINTER #ifdef CONFIG_MIPS32_FRAMEPOINTER
sw $fp, VFORK_FP_OFFSET($sp) sw $fp, FORK_FP_OFFSET($sp)
#else #else
sw $s8, VFORK_S8_OFFSET($sp) sw $s8, FORK_S8_OFFSET($sp)
#endif #endif
/* Save the global pointer, stack pointer, and return address */ /* Save the global pointer, stack pointer, and return address */
sw $t0, VFORK_SP_OFFSET($sp) sw $t0, FORK_SP_OFFSET($sp)
sw $ra, VFORK_RA_OFFSET($sp) sw $ra, FORK_RA_OFFSET($sp)
#ifdef MIPS32_SAVE_GP #ifdef MIPS32_SAVE_GP
sw $gp, VFORK_GP_OFFSET($sp) sw $gp, FORK_GP_OFFSET($sp)
#endif #endif
/* Floating point registers (not yet) */ /* Floating point registers (not yet) */
/* Then, call up_vfork(), passing it a pointer to the stack structure */ /* Then, call up_fork(), passing it a pointer to the stack structure */
move $a0, $sp move $a0, $sp
jal up_vfork jal up_fork
nop nop
/* Release the stack data and return the value returned by up_vfork */ /* Release the stack data and return the value returned by up_fork */
lw $ra, VFORK_RA_OFFSET($sp) lw $ra, FORK_RA_OFFSET($sp)
addiu $sp, $sp, VFORK_SIZEOF addiu $sp, $sp, FORK_SIZEOF
j $ra j $ra
.end vfork .end fork
.size vfork, .-vfork .size fork, .-fork
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/mips/src/mips32/mips_vfork.c * arch/mips/src/mips32/mips_fork.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -35,7 +35,7 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <arch/irq.h> #include <arch/irq.h>
#include "mips_vfork.h" #include "mips_fork.h"
#include "sched/sched.h" #include "sched/sched.h"
/**************************************************************************** /****************************************************************************
@@ -43,22 +43,22 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: up_vfork * Name: up_fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* The overall sequence is: * The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* this consists of: * this consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -66,27 +66,27 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* nxtask_abort_vfork() may be called if an error occurs between steps 3 * nxtask_abort_fork() may be called if an error occurs between steps 3
* and 6 * and 6
* *
* Input Parameters: * Input Parameters:
* context - Caller context information saved by vfork() * context - Caller context information saved by fork()
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
pid_t up_vfork(const struct vfork_s *context) pid_t up_fork(const struct fork_s *context)
{ {
struct tcb_s *parent = this_task(); struct tcb_s *parent = this_task();
struct task_tcb_s *child; struct task_tcb_s *child;
@@ -127,10 +127,10 @@ pid_t up_vfork(const struct vfork_s *context)
/* Allocate and initialize a TCB for the child task. */ /* Allocate and initialize a TCB for the child task. */
child = nxtask_setup_vfork((start_t)context->ra); child = nxtask_setup_fork((start_t)context->ra);
if (!child) if (!child)
{ {
sinfo("nxtask_setup_vfork failed\n"); sinfo("nxtask_setup_fork failed\n");
return (pid_t)ERROR; return (pid_t)ERROR;
} }
@@ -152,7 +152,7 @@ pid_t up_vfork(const struct vfork_s *context)
/* Make some feeble effort to perserve the stack contents. This is /* Make some feeble effort to perserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other * feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the * content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble * user follows all of the caveats of fork() usage, even this feeble
* effort is overkill. * effort is overkill.
*/ */
@@ -210,9 +210,9 @@ pid_t up_vfork(const struct vfork_s *context)
child->cmn.xcp.regs[REG_GP] = context->gp; /* Global pointer */ child->cmn.xcp.regs[REG_GP] = context->gp; /* Global pointer */
#endif #endif
/* And, finally, start the child task. On a failure, nxtask_start_vfork() /* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_vfork(). * will discard the TCB by calling nxtask_abort_fork().
*/ */
return nxtask_start_vfork(child); return nxtask_start_fork(child);
} }
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/mips/src/mips32/mips_vfork.h * arch/mips/src/mips32/mips_fork.h
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -18,8 +18,8 @@
* *
****************************************************************************/ ****************************************************************************/
#ifndef __ARCH_MIPS_SRC_MIPS32_MIPS_VFORK_H #ifndef __ARCH_MIPS_SRC_MIPS32_MIPS_FORK_H
#define __ARCH_MIPS_SRC_MIPS32_MIPS_VFORK_H #define __ARCH_MIPS_SRC_MIPS32_MIPS_FORK_H
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
@@ -33,10 +33,10 @@
****************************************************************************/ ****************************************************************************/
/* Register r30 may be a frame pointer in some ABIs. Or may just be saved /* Register r30 may be a frame pointer in some ABIs. Or may just be saved
* register s8. It makes a difference for vfork handling. * register s8. It makes a difference for fork handling.
*/ */
#undef VFORK_HAVE_FP #undef FORK_HAVE_FP
/* r0 zero Always has the value 0. /* r0 zero Always has the value 0.
* r1 at Temporary generally used by assembler. * r1 at Temporary generally used by assembler.
@@ -59,28 +59,28 @@
* r31 ra Return address. * r31 ra Return address.
*/ */
#define VFORK_S0_OFFSET (0*4) /* Saved register s0 */ #define FORK_S0_OFFSET (0*4) /* Saved register s0 */
#define VFORK_S1_OFFSET (1*4) /* Saved register s1 */ #define FORK_S1_OFFSET (1*4) /* Saved register s1 */
#define VFORK_S2_OFFSET (2*4) /* Saved register s2 */ #define FORK_S2_OFFSET (2*4) /* Saved register s2 */
#define VFORK_S3_OFFSET (3*4) /* Saved register s3 */ #define FORK_S3_OFFSET (3*4) /* Saved register s3 */
#define VFORK_S4_OFFSET (4*4) /* Saved register s4 */ #define FORK_S4_OFFSET (4*4) /* Saved register s4 */
#define VFORK_S5_OFFSET (5*4) /* Saved register s5 */ #define FORK_S5_OFFSET (5*4) /* Saved register s5 */
#define VFORK_S6_OFFSET (6*4) /* Saved register s6 */ #define FORK_S6_OFFSET (6*4) /* Saved register s6 */
#define VFORK_S7_OFFSET (7*4) /* Saved register s7 */ #define FORK_S7_OFFSET (7*4) /* Saved register s7 */
#ifdef CONFIG_MIPS32_FRAMEPOINTER #ifdef CONFIG_MIPS32_FRAMEPOINTER
# define VFORK_FP_OFFSET (8*4) /* Frame pointer */ # define FORK_FP_OFFSET (8*4) /* Frame pointer */
#else #else
# define VFORK_S8_OFFSET (8*4) /* Saved register s8 */ # define FORK_S8_OFFSET (8*4) /* Saved register s8 */
#endif #endif
#define VFORK_SP_OFFSET (9*4) /* Stack pointer*/ #define FORK_SP_OFFSET (9*4) /* Stack pointer*/
#define VFORK_RA_OFFSET (10*4) /* Return address*/ #define FORK_RA_OFFSET (10*4) /* Return address*/
#ifdef MIPS32_SAVE_GP #ifdef MIPS32_SAVE_GP
# define VFORK_GP_OFFSET (11*4) /* Global pointer */ # define FORK_GP_OFFSET (11*4) /* Global pointer */
# define VFORK_SIZEOF (12*4) # define FORK_SIZEOF (12*4)
#else #else
# define VFORK_SIZEOF (11*4) # define FORK_SIZEOF (11*4)
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -88,7 +88,7 @@
****************************************************************************/ ****************************************************************************/
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
struct vfork_s struct fork_s
{ {
/* CPU registers */ /* CPU registers */
@@ -115,4 +115,4 @@ struct vfork_s
}; };
#endif #endif
#endif /* __ARCH_MIPS_SRC_MIPS32_MIPS_VFORK_H */ #endif /* __ARCH_MIPS_SRC_MIPS32_MIPS_FORK_H */
+2 -2
View File
@@ -24,7 +24,7 @@ HEAD_ASRC = pic32mx_head.S
# Common MIPS files # Common MIPS files
CMN_ASRCS = mips_syscall0.S vfork.S CMN_ASRCS = mips_syscall0.S fork.S
CMN_CSRCS = mips_allocateheap.c mips_copystate.c mips_createstack.c CMN_CSRCS = mips_allocateheap.c mips_copystate.c mips_createstack.c
CMN_CSRCS += mips_doirq.c mips_exit.c mips_getintstack.c mips_initialize.c CMN_CSRCS += mips_doirq.c mips_exit.c mips_getintstack.c mips_initialize.c
CMN_CSRCS += mips_initialstate.c mips_irq.c mips_lowputs.c mips_mdelay.c CMN_CSRCS += mips_initialstate.c mips_irq.c mips_lowputs.c mips_mdelay.c
@@ -32,7 +32,7 @@ CMN_CSRCS += mips_modifyreg8.c mips_modifyreg16.c mips_modifyreg32.c
CMN_CSRCS += mips_nputs.c mips_releasestack.c mips_registerdump.c CMN_CSRCS += mips_nputs.c mips_releasestack.c mips_registerdump.c
CMN_CSRCS += mips_schedulesigaction.c mips_sigdeliver.c mips_swint0.c CMN_CSRCS += mips_schedulesigaction.c mips_sigdeliver.c mips_swint0.c
CMN_CSRCS += mips_stackframe.c mips_switchcontext.c mips_saveusercontext.c CMN_CSRCS += mips_stackframe.c mips_switchcontext.c mips_saveusercontext.c
CMN_CSRCS += mips_udelay.c mips_usestack.c mips_vfork.c CMN_CSRCS += mips_udelay.c mips_usestack.c mips_fork.c
# Configuration dependent common files # Configuration dependent common files
+2 -2
View File
@@ -24,7 +24,7 @@ HEAD_ASRC = pic32mz_head.S
# Common MIPS files # Common MIPS files
CMN_ASRCS = mips_syscall0.S vfork.S mips_cache.S CMN_ASRCS = mips_syscall0.S fork.S mips_cache.S
CMN_CSRCS = mips_allocateheap.c mips_copystate.c mips_createstack.c CMN_CSRCS = mips_allocateheap.c mips_copystate.c mips_createstack.c
CMN_CSRCS += mips_doirq.c mips_exit.c mips_getintstack.c mips_initialize.c CMN_CSRCS += mips_doirq.c mips_exit.c mips_getintstack.c mips_initialize.c
CMN_CSRCS += mips_initialstate.c mips_irq.c mips_lowputs.c mips_mdelay.c CMN_CSRCS += mips_initialstate.c mips_irq.c mips_lowputs.c mips_mdelay.c
@@ -32,7 +32,7 @@ CMN_CSRCS += mips_modifyreg8.c mips_modifyreg16.c mips_modifyreg32.c
CMN_CSRCS += mips_nputs.c mips_releasestack.c mips_registerdump.c CMN_CSRCS += mips_nputs.c mips_releasestack.c mips_registerdump.c
CMN_CSRCS += mips_schedulesigaction.c mips_sigdeliver.c mips_swint0.c CMN_CSRCS += mips_schedulesigaction.c mips_sigdeliver.c mips_swint0.c
CMN_CSRCS += mips_stackframe.c mips_switchcontext.c mips_saveusercontext.c CMN_CSRCS += mips_stackframe.c mips_switchcontext.c mips_saveusercontext.c
CMN_CSRCS += mips_udelay.c mips_usestack.c mips_vfork.c CMN_CSRCS += mips_udelay.c mips_usestack.c mips_fork.c
# Configuration dependent common files # Configuration dependent common files
+3 -3
View File
@@ -65,9 +65,9 @@ ifeq ($(CONFIG_STACK_COLORATION),y)
CMN_CSRCS += riscv_checkstack.c CMN_CSRCS += riscv_checkstack.c
endif endif
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) ifeq ($(CONFIG_ARCH_HAVE_FORK),y)
CMN_ASRCS += vfork.S CMN_ASRCS += fork.S
CMN_CSRCS += riscv_vfork.c CMN_CSRCS += riscv_fork.c
endif endif
ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y) ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/risc-v/src/common/vfork.S * arch/risc-v/src/common/fork.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -25,7 +25,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include "riscv_vfork.h" #include "riscv_fork.h"
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
@@ -35,32 +35,32 @@
* Public Symbols * Public Symbols
****************************************************************************/ ****************************************************************************/
.file "vfork.S" .file "fork.S"
.globl up_vfork .globl up_fork
.globl vfork .globl fork
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the * This thin layer implements fork by simply calling up_fork() with the
* vfork() context as an argument. The overall sequence is: * fork() context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -68,84 +68,84 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
.type vfork, function .type fork, function
vfork: fork:
/* Create a stack frame */ /* Create a stack frame */
addi sp, sp, -VFORK_SIZEOF addi sp, sp, -FORK_SIZEOF
/* CPU registers */ /* CPU registers */
/* Save the volatile registers */ /* Save the volatile registers */
REGSTORE s1, VFORK_S1_OFFSET(sp) REGSTORE s1, FORK_S1_OFFSET(sp)
REGSTORE s2, VFORK_S2_OFFSET(sp) REGSTORE s2, FORK_S2_OFFSET(sp)
REGSTORE s3, VFORK_S3_OFFSET(sp) REGSTORE s3, FORK_S3_OFFSET(sp)
REGSTORE s4, VFORK_S4_OFFSET(sp) REGSTORE s4, FORK_S4_OFFSET(sp)
REGSTORE s5, VFORK_S5_OFFSET(sp) REGSTORE s5, FORK_S5_OFFSET(sp)
REGSTORE s6, VFORK_S6_OFFSET(sp) REGSTORE s6, FORK_S6_OFFSET(sp)
REGSTORE s7, VFORK_S7_OFFSET(sp) REGSTORE s7, FORK_S7_OFFSET(sp)
REGSTORE s8, VFORK_S8_OFFSET(sp) REGSTORE s8, FORK_S8_OFFSET(sp)
REGSTORE s9, VFORK_S9_OFFSET(sp) REGSTORE s9, FORK_S9_OFFSET(sp)
REGSTORE s10, VFORK_S10_OFFSET(sp) REGSTORE s10, FORK_S10_OFFSET(sp)
REGSTORE s11, VFORK_S11_OFFSET(sp) REGSTORE s11, FORK_S11_OFFSET(sp)
/* Save the frame pointer, stack pointer, and return address */ /* Save the frame pointer, stack pointer, and return address */
#ifdef CONFIG_RISCV_FRAMEPOINTER #ifdef CONFIG_RISCV_FRAMEPOINTER
REGSTORE fp, VFORK_FP_OFFSET(sp) REGSTORE fp, FORK_FP_OFFSET(sp)
#else #else
REGSTORE s0, VFORK_S0_OFFSET(sp) REGSTORE s0, FORK_S0_OFFSET(sp)
#endif #endif
addi s0, sp, VFORK_SIZEOF addi s0, sp, FORK_SIZEOF
REGSTORE s0, VFORK_SP_OFFSET(sp) /* original SP */ REGSTORE s0, FORK_SP_OFFSET(sp) /* original SP */
REGSTORE x1, VFORK_RA_OFFSET(sp) /* return address */ REGSTORE x1, FORK_RA_OFFSET(sp) /* return address */
/* Floating point registers */ /* Floating point registers */
#ifdef CONFIG_ARCH_FPU #ifdef CONFIG_ARCH_FPU
FSTORE fs0, VFORK_FS0_OFFSET(sp) FSTORE fs0, FORK_FS0_OFFSET(sp)
FSTORE fs1, VFORK_FS1_OFFSET(sp) FSTORE fs1, FORK_FS1_OFFSET(sp)
FSTORE fs2, VFORK_FS2_OFFSET(sp) FSTORE fs2, FORK_FS2_OFFSET(sp)
FSTORE fs3, VFORK_FS3_OFFSET(sp) FSTORE fs3, FORK_FS3_OFFSET(sp)
FSTORE fs4, VFORK_FS4_OFFSET(sp) FSTORE fs4, FORK_FS4_OFFSET(sp)
FSTORE fs5, VFORK_FS5_OFFSET(sp) FSTORE fs5, FORK_FS5_OFFSET(sp)
FSTORE fs6, VFORK_FS6_OFFSET(sp) FSTORE fs6, FORK_FS6_OFFSET(sp)
FSTORE fs7, VFORK_FS7_OFFSET(sp) FSTORE fs7, FORK_FS7_OFFSET(sp)
FSTORE fs8, VFORK_FS8_OFFSET(sp) FSTORE fs8, FORK_FS8_OFFSET(sp)
FSTORE fs9, VFORK_FS9_OFFSET(sp) FSTORE fs9, FORK_FS9_OFFSET(sp)
FSTORE fs10, VFORK_FS10_OFFSET(sp) FSTORE fs10, FORK_FS10_OFFSET(sp)
FSTORE fs11, VFORK_FS11_OFFSET(sp) FSTORE fs11, FORK_FS11_OFFSET(sp)
#endif #endif
/* Then, call up_vfork(), passing it a pointer to the stack frame */ /* Then, call up_fork(), passing it a pointer to the stack frame */
mv a0, sp mv a0, sp
call up_vfork call up_fork
/* Release the stack frame and return the value returned by up_vfork */ /* Release the stack frame and return the value returned by up_fork */
REGLOAD x1, VFORK_RA_OFFSET(sp) REGLOAD x1, FORK_RA_OFFSET(sp)
addi sp, sp, VFORK_SIZEOF addi sp, sp, FORK_SIZEOF
ret ret
.size vfork, .-vfork .size fork, .-fork
.end .end
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/risc-v/src/common/riscv_vfork.c * arch/risc-v/src/common/riscv_fork.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -34,7 +34,7 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <arch/irq.h> #include <arch/irq.h>
#include "riscv_vfork.h" #include "riscv_fork.h"
#include "riscv_internal.h" #include "riscv_internal.h"
#include "sched/sched.h" #include "sched/sched.h"
@@ -52,22 +52,22 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: up_vfork * Name: up_fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* The overall sequence is: * The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -75,29 +75,29 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* nxtask_abort_vfork() may be called if an error occurs between steps 3 * nxtask_abort_fork() may be called if an error occurs between steps 3
* and 6. * and 6.
* *
* Input Parameters: * Input Parameters:
* context - Caller context information saved by vfork() * context - Caller context information saved by fork()
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_ARCH_HAVE_VFORK #ifdef CONFIG_ARCH_HAVE_FORK
pid_t up_vfork(const struct vfork_s *context) pid_t up_fork(const struct fork_s *context)
{ {
struct tcb_s *parent = this_task(); struct tcb_s *parent = this_task();
struct task_tcb_s *child; struct task_tcb_s *child;
@@ -136,10 +136,10 @@ pid_t up_vfork(const struct vfork_s *context)
/* Allocate and initialize a TCB for the child task. */ /* Allocate and initialize a TCB for the child task. */
child = nxtask_setup_vfork((start_t)context->ra); child = nxtask_setup_fork((start_t)context->ra);
if (!child) if (!child)
{ {
sinfo("nxtask_setup_vfork failed\n"); sinfo("nxtask_setup_fork failed\n");
return (pid_t)ERROR; return (pid_t)ERROR;
} }
@@ -160,7 +160,7 @@ pid_t up_vfork(const struct vfork_s *context)
/* Make some feeble effort to preserve the stack contents. This is /* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other * feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the * content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble * user follows all of the caveats of fork() usage, even this feeble
* effort is overkill. * effort is overkill.
*/ */
@@ -264,11 +264,11 @@ pid_t up_vfork(const struct vfork_s *context)
} }
#endif /* CONFIG_LIB_SYSCALL */ #endif /* CONFIG_LIB_SYSCALL */
/* And, finally, start the child task. On a failure, nxtask_start_vfork() /* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_vfork(). * will discard the TCB by calling nxtask_abort_fork().
*/ */
return nxtask_start_vfork(child); return nxtask_start_fork(child);
} }
#endif /* CONFIG_ARCH_HAVE_VFORK */ #endif /* CONFIG_ARCH_HAVE_FORK */
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/risc-v/src/common/riscv_vfork.h * arch/risc-v/src/common/riscv_fork.h
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -18,8 +18,8 @@
* *
****************************************************************************/ ****************************************************************************/
#ifndef __ARCH_RISCV_SRC_COMMON_RISCV_VFORK_H #ifndef __ARCH_RISCV_SRC_COMMON_RISCV_FORK_H
#define __ARCH_RISCV_SRC_COMMON_RISCV_VFORK_H #define __ARCH_RISCV_SRC_COMMON_RISCV_FORK_H
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
@@ -35,10 +35,10 @@
****************************************************************************/ ****************************************************************************/
/* Register x8 may be a frame pointer in some ABIs. Or may just be saved /* Register x8 may be a frame pointer in some ABIs. Or may just be saved
* register s0. It makes a difference for vfork handling. * register s0. It makes a difference for fork handling.
*/ */
#undef VFORK_HAVE_FP #undef FORK_HAVE_FP
/* Register ABI Name Description Saver /* Register ABI Name Description Saver
* *
@@ -62,59 +62,59 @@
* f2831 ft811 FP temporaries Caller * f2831 ft811 FP temporaries Caller
*/ */
#define VFORK_S1_OFFSET (1*INT_REG_SIZE) /* Saved register s1 */ #define FORK_S1_OFFSET (1*INT_REG_SIZE) /* Saved register s1 */
#define VFORK_S2_OFFSET (2*INT_REG_SIZE) /* Saved register s2 */ #define FORK_S2_OFFSET (2*INT_REG_SIZE) /* Saved register s2 */
#define VFORK_S3_OFFSET (3*INT_REG_SIZE) /* Saved register s3 */ #define FORK_S3_OFFSET (3*INT_REG_SIZE) /* Saved register s3 */
#define VFORK_S4_OFFSET (4*INT_REG_SIZE) /* Saved register s4 */ #define FORK_S4_OFFSET (4*INT_REG_SIZE) /* Saved register s4 */
#define VFORK_S5_OFFSET (5*INT_REG_SIZE) /* Saved register s5 */ #define FORK_S5_OFFSET (5*INT_REG_SIZE) /* Saved register s5 */
#define VFORK_S6_OFFSET (6*INT_REG_SIZE) /* Saved register s6 */ #define FORK_S6_OFFSET (6*INT_REG_SIZE) /* Saved register s6 */
#define VFORK_S7_OFFSET (7*INT_REG_SIZE) /* Saved register s7 */ #define FORK_S7_OFFSET (7*INT_REG_SIZE) /* Saved register s7 */
#define VFORK_S8_OFFSET (8*INT_REG_SIZE) /* Saved register s8 */ #define FORK_S8_OFFSET (8*INT_REG_SIZE) /* Saved register s8 */
#define VFORK_S9_OFFSET (9*INT_REG_SIZE) /* Saved register s9 */ #define FORK_S9_OFFSET (9*INT_REG_SIZE) /* Saved register s9 */
#define VFORK_S10_OFFSET (10*INT_REG_SIZE) /* Saved register s10 */ #define FORK_S10_OFFSET (10*INT_REG_SIZE) /* Saved register s10 */
#define VFORK_S11_OFFSET (11*INT_REG_SIZE) /* Saved register s11 */ #define FORK_S11_OFFSET (11*INT_REG_SIZE) /* Saved register s11 */
#ifdef CONFIG_RISCV_FRAMEPOINTER #ifdef CONFIG_RISCV_FRAMEPOINTER
# define VFORK_FP_OFFSET (0*INT_REG_SIZE) /* Frame pointer */ # define FORK_FP_OFFSET (0*INT_REG_SIZE) /* Frame pointer */
#else #else
# define VFORK_S0_OFFSET (0*INT_REG_SIZE) /* Saved register s0 */ # define FORK_S0_OFFSET (0*INT_REG_SIZE) /* Saved register s0 */
#endif #endif
#define VFORK_SP_OFFSET (12*INT_REG_SIZE) /* Stack pointer*/ #define FORK_SP_OFFSET (12*INT_REG_SIZE) /* Stack pointer*/
#define VFORK_RA_OFFSET (13*INT_REG_SIZE) /* Return address*/ #define FORK_RA_OFFSET (13*INT_REG_SIZE) /* Return address*/
#ifdef RISCV_SAVE_GP #ifdef RISCV_SAVE_GP
# define VFORK_GP_OFFSET (14*INT_REG_SIZE) /* Global pointer */ # define FORK_GP_OFFSET (14*INT_REG_SIZE) /* Global pointer */
# define VFORK_INT_SIZE (15*INT_REG_SIZE) # define FORK_INT_SIZE (15*INT_REG_SIZE)
#else #else
# define VFORK_INT_SIZE (14*INT_REG_SIZE) # define FORK_INT_SIZE (14*INT_REG_SIZE)
#endif #endif
#ifdef CONFIG_ARCH_FPU #ifdef CONFIG_ARCH_FPU
# define VFORK_FS0_OFFSET (VFORK_INT_SIZE + 0*FPU_REG_FULL_SIZE) # define FORK_FS0_OFFSET (FORK_INT_SIZE + 0*FPU_REG_FULL_SIZE)
# define VFORK_FS1_OFFSET (VFORK_INT_SIZE + 1*FPU_REG_FULL_SIZE) # define FORK_FS1_OFFSET (FORK_INT_SIZE + 1*FPU_REG_FULL_SIZE)
# define VFORK_FS2_OFFSET (VFORK_INT_SIZE + 2*FPU_REG_FULL_SIZE) # define FORK_FS2_OFFSET (FORK_INT_SIZE + 2*FPU_REG_FULL_SIZE)
# define VFORK_FS3_OFFSET (VFORK_INT_SIZE + 3*FPU_REG_FULL_SIZE) # define FORK_FS3_OFFSET (FORK_INT_SIZE + 3*FPU_REG_FULL_SIZE)
# define VFORK_FS4_OFFSET (VFORK_INT_SIZE + 4*FPU_REG_FULL_SIZE) # define FORK_FS4_OFFSET (FORK_INT_SIZE + 4*FPU_REG_FULL_SIZE)
# define VFORK_FS5_OFFSET (VFORK_INT_SIZE + 5*FPU_REG_FULL_SIZE) # define FORK_FS5_OFFSET (FORK_INT_SIZE + 5*FPU_REG_FULL_SIZE)
# define VFORK_FS6_OFFSET (VFORK_INT_SIZE + 6*FPU_REG_FULL_SIZE) # define FORK_FS6_OFFSET (FORK_INT_SIZE + 6*FPU_REG_FULL_SIZE)
# define VFORK_FS7_OFFSET (VFORK_INT_SIZE + 7*FPU_REG_FULL_SIZE) # define FORK_FS7_OFFSET (FORK_INT_SIZE + 7*FPU_REG_FULL_SIZE)
# define VFORK_FS8_OFFSET (VFORK_INT_SIZE + 8*FPU_REG_FULL_SIZE) # define FORK_FS8_OFFSET (FORK_INT_SIZE + 8*FPU_REG_FULL_SIZE)
# define VFORK_FS9_OFFSET (VFORK_INT_SIZE + 9*FPU_REG_FULL_SIZE) # define FORK_FS9_OFFSET (FORK_INT_SIZE + 9*FPU_REG_FULL_SIZE)
# define VFORK_FS10_OFFSET (VFORK_INT_SIZE + 10*FPU_REG_FULL_SIZE) # define FORK_FS10_OFFSET (FORK_INT_SIZE + 10*FPU_REG_FULL_SIZE)
# define VFORK_FS11_OFFSET (VFORK_INT_SIZE + 11*FPU_REG_FULL_SIZE) # define FORK_FS11_OFFSET (FORK_INT_SIZE + 11*FPU_REG_FULL_SIZE)
# define VFORK_FPU_SIZE (12*FPU_REG_FULL_SIZE) # define FORK_FPU_SIZE (12*FPU_REG_FULL_SIZE)
#else #else
# define VFORK_FPU_SIZE (0) # define FORK_FPU_SIZE (0)
#endif #endif
#define VFORK_SIZEOF STACK_ALIGN_UP(VFORK_INT_SIZE + VFORK_FPU_SIZE) #define FORK_SIZEOF STACK_ALIGN_UP(FORK_INT_SIZE + FORK_FPU_SIZE)
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
struct vfork_s struct fork_s
{ {
/* CPU registers */ /* CPU registers */
@@ -159,4 +159,4 @@ struct vfork_s
}; };
#endif #endif
#endif /* __ARCH_RISCV_SRC_COMMON_RISCV_VFORK_H */ #endif /* __ARCH_RISCV_SRC_COMMON_RISCV_FORK_H */
+7 -9
View File
@@ -46,16 +46,16 @@ endif
ifeq ($(CONFIG_HOST_X86_64),y) ifeq ($(CONFIG_HOST_X86_64),y)
ifeq ($(CONFIG_SIM_M32),y) ifeq ($(CONFIG_SIM_M32),y)
ASRCS += sim_vfork_x86.S ASRCS += sim_fork_x86.S
else else
ASRCS += sim_vfork_x86_64.S ASRCS += sim_fork_x86_64.S
endif endif
else ifeq ($(CONFIG_HOST_X86),y) else ifeq ($(CONFIG_HOST_X86),y)
ASRCS += sim_vfork_x86.S ASRCS += sim_fork_x86.S
else ifeq ($(CONFIG_HOST_ARM),y) else ifeq ($(CONFIG_HOST_ARM),y)
ASRCS += sim_vfork_arm.S ASRCS += sim_fork_arm.S
else ifeq ($(CONFIG_HOST_ARM64),y) else ifeq ($(CONFIG_HOST_ARM64),y)
ASRCS += sim_vfork_arm64.S ASRCS += sim_fork_arm64.S
endif endif
AOBJS = $(ASRCS:.S=$(OBJEXT)) AOBJS = $(ASRCS:.S=$(OBJEXT))
@@ -70,10 +70,8 @@ ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CSRCS += sim_backtrace.c CSRCS += sim_backtrace.c
endif endif
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) ifeq ($(CONFIG_ARCH_HAVE_FORK),y)
ifeq ($(CONFIG_SCHED_WAITPID),y) CSRCS += sim_fork.c
CSRCS += sim_vfork.c
endif
endif endif
VPATH = :sim VPATH = :sim
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/sim/src/sim/sim_vfork.c * arch/sim/src/sim/sim_fork.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -43,22 +43,22 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: up_vfork * Name: up_fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* The overall sequence is: * The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -66,17 +66,17 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* nxtask_abort_vfork() may be called if an error occurs between steps 3 and * nxtask_abort_fork() may be called if an error occurs between steps 3 and
* 6. * 6.
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
@@ -86,7 +86,7 @@
#ifdef CONFIG_SIM_ASAN #ifdef CONFIG_SIM_ASAN
nosanitize_address nosanitize_address
#endif #endif
pid_t up_vfork(const xcpt_reg_t *context) pid_t up_fork(const xcpt_reg_t *context)
{ {
struct tcb_s *parent = this_task(); struct tcb_s *parent = this_task();
struct task_tcb_s *child; struct task_tcb_s *child;
@@ -98,16 +98,16 @@ pid_t up_vfork(const xcpt_reg_t *context)
xcpt_reg_t stacktop; xcpt_reg_t stacktop;
xcpt_reg_t stackutil; xcpt_reg_t stackutil;
sinfo("vfork context [%p]:\n", context); sinfo("fork context [%p]:\n", context);
sinfo(" frame pointer:%lx sp:%lx pc:%lx\n", sinfo(" frame pointer:%lx sp:%lx pc:%lx\n",
context[JB_FP], context[JB_SP], context[JB_PC]); context[JB_FP], context[JB_SP], context[JB_PC]);
/* Allocate and initialize a TCB for the child task. */ /* Allocate and initialize a TCB for the child task. */
child = nxtask_setup_vfork((start_t)context[JB_PC]); child = nxtask_setup_fork((start_t)context[JB_PC]);
if (!child) if (!child)
{ {
serr("ERROR: nxtask_setup_vfork failed\n"); serr("ERROR: nxtask_setup_fork failed\n");
return (pid_t)ERROR; return (pid_t)ERROR;
} }
@@ -129,7 +129,7 @@ pid_t up_vfork(const xcpt_reg_t *context)
/* Make some feeble effort to preserve the stack contents. This is /* Make some feeble effort to preserve the stack contents. This is
* feeble because the stack surely contains invalid pointers and other * feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the * content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble * user follows all of the caveats of fork() usage, even this feeble
* effort is overkill. * effort is overkill.
*/ */
@@ -169,9 +169,9 @@ pid_t up_vfork(const xcpt_reg_t *context)
child->cmn.xcp.regs[JB_FP] = newfp; /* Frame pointer */ child->cmn.xcp.regs[JB_FP] = newfp; /* Frame pointer */
child->cmn.xcp.regs[JB_SP] = newsp; /* Stack pointer */ child->cmn.xcp.regs[JB_SP] = newsp; /* Stack pointer */
/* And, finally, start the child task. On a failure, nxtask_start_vfork() /* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_vfork(). * will discard the TCB by calling nxtask_abort_fork().
*/ */
return nxtask_start_vfork(child); return nxtask_start_fork(child);
} }
@@ -1,5 +1,5 @@
/************************************************************************************ /************************************************************************************
* arch/sim/src/sim/sim_vfork_arm.S * arch/sim/src/sim/sim_fork_arm.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -33,30 +33,30 @@
* Public Symbols * Public Symbols
************************************************************************************/ ************************************************************************************/
.file "vfork.S" .file "fork.S"
.globl up_vfork .globl up_fork
/************************************************************************************ /************************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ************************************************************************************/
/************************************************************************************ /************************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the behavior is * The fork() function has the same effect as posix fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than * undefined if the process created by fork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns * a variable of type pid_t used to store the return value from fork(), or returns
* from the function in which vfork() was called, or calls any other function before * from the function in which fork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions. * successfully calling _exit() or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the vfork() * This thin layer implements fork by simply calling up_fork() with the fork()
* context as an argument. The overall sequence is: * context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This * 3) nxtask_setup_fork() allocates and configures the child task's TCB. This
* consists of: * consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -64,17 +64,17 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and returns * Upon successful completion, fork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is * 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 * returned to the parent, no child process is created, and errno is set to
* indicate the error. * indicate the error.
@@ -82,18 +82,18 @@
************************************************************************************/ ************************************************************************************/
.text .text
.globl vfork .globl fork
.type vfork, @function .type fork, @function
vfork: fork:
sub sp, sp, #XCPTCONTEXT_SIZE sub sp, sp, #XCPTCONTEXT_SIZE
mov r0, sp mov r0, sp
bl setjmp bl setjmp
subs r0, #1 subs r0, #1
jz child jz child
bl up_vfork bl up_fork
child: child:
add sp, sp, #XCPTCONTEXT_SIZE add sp, sp, #XCPTCONTEXT_SIZE
ret ret
.size vfork, . - vfork .size fork, . - fork
.end .end
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* arch/sim/src/sim/sim_vfork_arm64.S * arch/sim/src/sim/sim_fork_arm64.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -41,8 +41,8 @@
* Public Symbols * Public Symbols
***************************************************************************/ ***************************************************************************/
.file "up_vfork_arm64.S" .file "up_fork_arm64.S"
.globl SYMBOL(up_vfork) .globl SYMBOL(up_fork)
.globl SYMBOL(setjmp) .globl SYMBOL(setjmp)
/**************************************************************************** /****************************************************************************
@@ -50,23 +50,23 @@
***************************************************************************/ ***************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the * This thin layer implements fork by simply calling up_fork() with the
* vfork() context as an argument. The overall sequence is: * fork() context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -74,17 +74,17 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
@@ -92,10 +92,10 @@
***************************************************************************/ ***************************************************************************/
.text .text
.globl SYMBOL(vfork) .globl SYMBOL(fork)
.align 4 .align 4
SYMBOL(vfork): SYMBOL(fork):
stp x29, x30, [sp] /* save FP/LR register */ stp x29, x30, [sp] /* save FP/LR register */
sub sp, sp, #XCPTCONTEXT_SIZE /* area from stack for setjmp() */ sub sp, sp, #XCPTCONTEXT_SIZE /* area from stack for setjmp() */
@@ -106,8 +106,8 @@ SYMBOL(vfork):
subs x0, x0, #1 /* 0: parent / 1: child */ subs x0, x0, #1 /* 0: parent / 1: child */
cbz x0, 1f /* child --> return */ cbz x0, 1f /* child --> return */
mov x0, sp /* pass stack area to up_vfork() */ mov x0, sp /* pass stack area to up_fork() */
bl SYMBOL(up_vfork) /* further process task creation */ bl SYMBOL(up_fork) /* further process task creation */
1: 1:
add sp, sp, #XCPTCONTEXT_SIZE /* release area from stack */ add sp, sp, #XCPTCONTEXT_SIZE /* release area from stack */
@@ -1,5 +1,5 @@
/************************************************************************************ /************************************************************************************
* arch/sim/src/sim/sim_vfork_x86.S * arch/sim/src/sim/sim_fork_x86.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -41,30 +41,30 @@
* Public Symbols * Public Symbols
************************************************************************************/ ************************************************************************************/
.file "vfork.S" .file "fork.S"
.globl up_vfork .globl up_fork
/************************************************************************************ /************************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ************************************************************************************/
/************************************************************************************ /************************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the behavior is * The fork() function has the same effect as posix fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than * undefined if the process created by fork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns * a variable of type pid_t used to store the return value from fork(), or returns
* from the function in which vfork() was called, or calls any other function before * from the function in which fork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions. * successfully calling _exit() or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the vfork() * This thin layer implements fork by simply calling up_fork() with the fork()
* context as an argument. The overall sequence is: * context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This * 3) nxtask_setup_fork() allocates and configures the child task's TCB. This
* consists of: * consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -72,17 +72,17 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and returns * Upon successful completion, fork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is * 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 * returned to the parent, no child process is created, and errno is set to
* indicate the error. * indicate the error.
@@ -90,22 +90,22 @@
************************************************************************************/ ************************************************************************************/
.text .text
.globl SYMBOL(vfork) .globl SYMBOL(fork)
#ifdef __ELF__ #ifdef __ELF__
.type SYMBOL(vfork), @function .type SYMBOL(fork), @function
#endif #endif
SYMBOL(vfork): SYMBOL(fork):
sub $XCPTCONTEXT_SIZE, %esp sub $XCPTCONTEXT_SIZE, %esp
push %esp push %esp
call SYMBOL(setjmp) call SYMBOL(setjmp)
sub $1, %eax sub $1, %eax
jz child jz child
call SYMBOL(up_vfork) call SYMBOL(up_fork)
child: child:
add $XCPTCONTEXT_SIZE+4, %esp add $XCPTCONTEXT_SIZE+4, %esp
ret ret
#ifdef __ELF__ #ifdef __ELF__
.size SYMBOL(vfork), . - SYMBOL(vfork) .size SYMBOL(fork), . - SYMBOL(fork)
#endif #endif
@@ -1,5 +1,5 @@
/************************************************************************************ /************************************************************************************
* arch/sim/src/sim/sim_vfork_x86_64.S * arch/sim/src/sim/sim_fork_x86_64.S
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -41,30 +41,30 @@
* Public Symbols * Public Symbols
************************************************************************************/ ************************************************************************************/
.file "vfork.S" .file "fork.S"
.globl up_vfork .globl up_fork
/************************************************************************************ /************************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ************************************************************************************/
/************************************************************************************ /************************************************************************************
* Name: vfork * Name: fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the behavior is * The fork() function has the same effect as posix fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than * undefined if the process created by fork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns * a variable of type pid_t used to store the return value from fork(), or returns
* from the function in which vfork() was called, or calls any other function before * from the function in which fork() was called, or calls any other function before
* successfully calling _exit() or one of the exec family of functions. * successfully calling _exit() or one of the exec family of functions.
* *
* This thin layer implements vfork by simply calling up_vfork() with the vfork() * This thin layer implements fork by simply calling up_fork() with the fork()
* context as an argument. The overall sequence is: * context as an argument. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() collects context information and * 1) User code calls fork(). fork() collects context information and
* transfers control up up_vfork(). * transfers control up up_fork().
* 2) up_vfork() and calls nxtask_setup_vfork(). * 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This * 3) nxtask_setup_fork() allocates and configures the child task's TCB. This
* consists of: * consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -72,17 +72,17 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and returns * Upon successful completion, fork() returns 0 to the child process and returns
* the process ID of the child process to the parent process. Otherwise, -1 is * 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 * returned to the parent, no child process is created, and errno is set to
* indicate the error. * indicate the error.
@@ -90,12 +90,12 @@
************************************************************************************/ ************************************************************************************/
.text .text
.globl SYMBOL(vfork) .globl SYMBOL(fork)
#ifdef __ELF__ #ifdef __ELF__
.type SYMBOL(vfork), @function .type SYMBOL(fork), @function
#endif #endif
SYMBOL(vfork): SYMBOL(fork):
sub $XCPTCONTEXT_SIZE, %rsp sub $XCPTCONTEXT_SIZE, %rsp
#ifdef CONFIG_SIM_X8664_MICROSOFT #ifdef CONFIG_SIM_X8664_MICROSOFT
mov %rsp, %rcx mov %rsp, %rcx
@@ -106,10 +106,11 @@ SYMBOL(vfork):
sub $1, %eax sub $1, %eax
jz child jz child
call SYMBOL(up_vfork)
call SYMBOL(up_fork)
child: child:
add $XCPTCONTEXT_SIZE, %rsp add $XCPTCONTEXT_SIZE, %rsp
ret ret
#ifdef __ELF__ #ifdef __ELF__
.size SYMBOL(vfork), . - SYMBOL(vfork) .size SYMBOL(fork), . - SYMBOL(fork)
#endif #endif
+11 -11
View File
@@ -1078,12 +1078,12 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]);
#endif #endif
/**************************************************************************** /****************************************************************************
* Internal vfork support. The overall sequence is: * Internal fork support. The overall sequence is:
* *
* 1) User code calls vfork(). vfork() is provided in architecture-specific * 1) User code calls fork(). fork() is provided in architecture-specific
* code. * code.
* 2) vfork()and calls nxtask_setup_vfork(). * 2) fork()and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -1091,20 +1091,20 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]);
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) vfork() provides any additional operating context. vfork must: * 4) fork() provides any additional operating context. fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) vfork() then calls nxtask_start_vfork() * 5) fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* nxtask_abort_vfork() may be called if an error occurs between * nxtask_abort_fork() may be called if an error occurs between
* steps 3 and 6. * steps 3 and 6.
* *
****************************************************************************/ ****************************************************************************/
FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr); FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr);
pid_t nxtask_start_vfork(FAR struct task_tcb_s *child); pid_t nxtask_start_fork(FAR struct task_tcb_s *child);
void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode); void nxtask_abort_fork(FAR struct task_tcb_s *child, int errcode);
/**************************************************************************** /****************************************************************************
* Name: group_argvstr * Name: group_argvstr
+2 -2
View File
@@ -114,8 +114,8 @@ SYSCALL_LOOKUP(task_setcancelstate, 2)
/* The following can be individually enabled */ /* The following can be individually enabled */
#if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_ARCH_HAVE_VFORK) #ifdef CONFIG_ARCH_HAVE_FORK
SYSCALL_LOOKUP(vfork, 0) SYSCALL_LOOKUP(fork, 0)
#endif #endif
#ifdef CONFIG_SCHED_WAITPID #ifdef CONFIG_SCHED_WAITPID
+1
View File
@@ -307,6 +307,7 @@ extern "C"
/* Task Control Interfaces */ /* Task Control Interfaces */
pid_t fork(void);
pid_t vfork(void); pid_t vfork(void);
pid_t getpid(void); pid_t getpid(void);
pid_t getpgrp(void); pid_t getpgrp(void);
+6
View File
@@ -48,6 +48,12 @@ ifneq ($(CONFIG_DISABLE_MOUNTPOINTS),y)
CSRCS += lib_truncate.c lib_posix_fallocate.c CSRCS += lib_truncate.c lib_posix_fallocate.c
endif endif
ifeq ($(CONFIG_ARCH_HAVE_FORK),y)
ifeq ($(CONFIG_SCHED_WAITPID),y)
CSRCS += lib_vfork.c
endif
endif
# Add the unistd directory to the build # Add the unistd directory to the build
DEPPATH += --dep-path unistd DEPPATH += --dep-path unistd
+76
View File
@@ -0,0 +1,76 @@
/****************************************************************************
* libs/libc/unistd/lib_vfork.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <debug.h>
#if defined(CONFIG_ARCH_HAVE_FORK) && defined(CONFIG_SCHED_WAITPID)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
*
* Description:
* The vfork() function is implemented based on fork() function, on
* vfork(), the parent task need to wait until the child task is performing
* exec or running finished.
*
* Returned Value:
* 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 vfork(void)
{
int status = 0;
int ret;
pid_t pid = fork();
if (pid != 0)
{
/* we are in parent task, and we need to wait the child task
* until running finished or performing exec
*/
ret = waitpid(pid, &status, 0);
if (ret < 0)
{
serr("ERROR: waitpid failed: %d\n", get_errno());
}
}
return pid;
}
#endif /* CONFIG_ARCH_HAVE_FORK && CONFIG_SCHED_WAITPID */
+2 -4
View File
@@ -29,10 +29,8 @@ ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
CSRCS += task_getppid.c task_reparent.c CSRCS += task_getppid.c task_reparent.c
endif endif
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) ifeq ($(CONFIG_ARCH_HAVE_FORK),y)
ifeq ($(CONFIG_SCHED_WAITPID),y) CSRCS += task_fork.c
CSRCS += task_vfork.c
endif
endif endif
ifneq ($(CONFIG_BUILD_KERNEL),y) ifneq ($(CONFIG_BUILD_KERNEL),y)
@@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* sched/task/task_vfork.c * sched/task/task_fork.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@@ -40,33 +40,33 @@
#include "task/task.h" #include "task/task.h"
#include "tls/tls.h" #include "tls/tls.h"
/* vfork() requires architecture-specific support as well as waipid(). */ /* fork() requires architecture-specific support as well as waipid(). */
#if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID) #ifdef CONFIG_ARCH_HAVE_FORK
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: nxtask_setup_vfork * Name: nxtask_setup_fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as posix fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* This function provides one step in the overall vfork() sequence: It * This function provides one step in the overall fork() sequence: It
* Allocates and initializes the child task's TCB. The overall sequence * Allocates and initializes the child task's TCB. The overall sequence
* is: * is:
* *
* 1) User code calls vfork(). vfork() is provided in * 1) User code calls fork(). fork() is provided in
* architecture-specific code. * architecture-specific code.
* 2) vfork()and calls nxtask_setup_vfork(). * 2) fork()and calls nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -74,24 +74,24 @@
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must: * 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork() * 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* retaddr - Return address * retaddr - Return address
* argsize - Location to return the argument size * argsize - Location to return the argument size
* *
* Returned Value: * Returned Value:
* Upon successful completion, nxtask_setup_vfork() returns a pointer to * Upon successful completion, nxtask_setup_fork() returns a pointer to
* newly allocated and initialized child task's TCB. NULL is returned * newly allocated and initialized child task's TCB. NULL is returned
* on any failure and the errno is set appropriately. * on any failure and the errno is set appropriately.
* *
****************************************************************************/ ****************************************************************************/
FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr) FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr)
{ {
FAR struct tcb_s *ptcb = this_task(); FAR struct tcb_s *ptcb = this_task();
FAR struct tcb_s *parent; FAR struct tcb_s *parent;
@@ -226,24 +226,24 @@ errout:
} }
/**************************************************************************** /****************************************************************************
* Name: nxtask_start_vfork * Name: nxtask_start_fork
* *
* Description: * Description:
* The vfork() function has the same effect as fork(), except that the * The fork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies * behavior is undefined if the process created by fork() either modifies
* any data other than a variable of type pid_t used to store the return * 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 * value from fork(), or returns from the function in which fork() was
* called, or calls any other function before successfully calling _exit() * called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions. * or one of the exec family of functions.
* *
* This function provides one step in the overall vfork() sequence: It * This function provides one step in the overall fork() sequence: It
* starts execution of the previously initialized TCB. The overall * starts execution of the previously initialized TCB. The overall
* sequence is: * sequence is:
* *
* 1) User code calls vfork() * 1) User code calls fork()
* 2) Architecture-specific code provides vfork()and calls * 2) Architecture-specific code provides fork()and calls
* nxtask_setup_vfork(). * nxtask_setup_fork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. * 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of: * This consists of:
* - Allocation of the child task's TCB. * - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams * - Initialization of file descriptors and streams
@@ -251,29 +251,28 @@ errout:
* - Allocate and initialize the stack * - Allocate and initialize the stack
* - Setup the input parameters for the task. * - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()) * - Initialization of the TCB (including call to up_initial_state())
* 4) vfork() provides any additional operating context. vfork must: * 4) fork() provides any additional operating context. fork must:
* - Initialize special values in any CPU registers that were not * - Initialize special values in any CPU registers that were not
* already configured by up_initial_state() * already configured by up_initial_state()
* 5) vfork() then calls nxtask_start_vfork() * 5) fork() then calls nxtask_start_fork()
* 6) nxtask_start_vfork() then executes the child thread. * 6) nxtask_start_fork() then executes the child thread.
* *
* Input Parameters: * Input Parameters:
* retaddr - The return address from vfork() where the child task * child - The task_tcb_s struct instance that created by
* will be started. * nxtask_setup_fork() method
* wait_child - whether need to wait until the child is running finished
* *
* Returned Value: * Returned Value:
* Upon successful completion, vfork() returns 0 to the child process and * Upon successful completion, fork() returns 0 to the child process and
* returns the process ID of the child process to the parent process. * returns the process ID of the child process to the parent process.
* Otherwise, -1 is returned to the parent, no child process is created, * Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error. * and errno is set to indicate the error.
* *
****************************************************************************/ ****************************************************************************/
pid_t nxtask_start_vfork(FAR struct task_tcb_s *child) pid_t nxtask_start_fork(FAR struct task_tcb_s *child)
{ {
pid_t pid; pid_t pid;
int rc = 0;
int ret;
sinfo("Starting Child TCB=%p\n", child); sinfo("Starting Child TCB=%p\n", child);
DEBUGASSERT(child); DEBUGASSERT(child);
@@ -294,45 +293,22 @@ pid_t nxtask_start_vfork(FAR struct task_tcb_s *child)
nxtask_activate((FAR struct tcb_s *)child); nxtask_activate((FAR struct tcb_s *)child);
/* The child task has not yet ran because pre-emption is disabled.
* The child task has the same priority as the parent task, so that
* would typically be the case anyway. However, in the SMP
* configuration, the child thread might have already ran on
* another CPU if pre-emption were not disabled.
*
* It is a requirement that the parent environment be stable while
* vfork runs; the child thread is still dependent on things in the
* parent thread... like the pointers into parent thread's stack
* which will still appear in the child's registers and environment.
*
* We assure that by waiting for the child thread to exit before
* returning to the parent thread. NOTE that pre-emption will be
* re-enabled while we are waiting, giving the child thread the
* opportunity to run.
*/
ret = waitpid(pid, &rc, 0);
if (ret < 0)
{
serr("ERROR: waitpid failed: %d\n", get_errno());
}
sched_unlock(); sched_unlock();
return pid; return pid;
} }
/**************************************************************************** /****************************************************************************
* Name: nxtask_abort_vfork * Name: nxtask_abort_fork
* *
* Description: * Description:
* Recover from any errors after nxtask_setup_vfork() was called. * Recover from any errors after nxtask_setup_fork() was called.
* *
* Returned Value: * Returned Value:
* None * None
* *
****************************************************************************/ ****************************************************************************/
void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode) void nxtask_abort_fork(FAR struct task_tcb_s *child, int errcode)
{ {
/* The TCB was added to the active task list by nxtask_setup_scheduler() */ /* The TCB was added to the active task list by nxtask_setup_scheduler() */
@@ -345,4 +321,4 @@ void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode)
set_errno(errcode); set_errno(errcode);
} }
#endif /* CONFIG_ARCH_HAVE_VFORK && CONFIG_SCHED_WAITPID */ #endif /* CONFIG_ARCH_HAVE_FORK */
+1 -1
View File
@@ -29,6 +29,7 @@
"fchmod","sys/stat.h","","int","int","mode_t" "fchmod","sys/stat.h","","int","int","mode_t"
"fchown","unistd.h","","int","int","uid_t","gid_t" "fchown","unistd.h","","int","int","uid_t","gid_t"
"fcntl","fcntl.h","","int","int","int","...","int" "fcntl","fcntl.h","","int","int","int","...","int"
"fork","unistd.h","defined(CONFIG_ARCH_HAVE_FORK)","pid_t"
"fs_fdopen","nuttx/fs/fs.h","defined(CONFIG_FILE_STREAM)","int","int","int","FAR struct tcb_s *","FAR struct file_struct **" "fs_fdopen","nuttx/fs/fs.h","defined(CONFIG_FILE_STREAM)","int","int","int","FAR struct tcb_s *","FAR struct file_struct **"
"fstat","sys/stat.h","","int","int","FAR struct stat *" "fstat","sys/stat.h","","int","int","FAR struct stat *"
"fstatfs","sys/statfs.h","","int","int","FAR struct statfs *" "fstatfs","sys/statfs.h","","int","int","FAR struct statfs *"
@@ -204,7 +205,6 @@
"unlink","unistd.h","!defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char *" "unlink","unistd.h","!defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char *"
"unsetenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","FAR const char *" "unsetenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","FAR const char *"
"utimens","sys/stat.h","","int","FAR const char *","const struct timespec [2]|FAR const struct timespec *" "utimens","sys/stat.h","","int","FAR const char *","const struct timespec [2]|FAR const struct timespec *"
"vfork","unistd.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_ARCH_HAVE_VFORK)","pid_t"
"wait","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","pid_t","FAR int *" "wait","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","pid_t","FAR int *"
"waitid","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","int","idtype_t","id_t"," FAR siginfo_t *","int" "waitid","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","int","idtype_t","id_t"," FAR siginfo_t *","int"
"waitpid","sys/wait.h","defined(CONFIG_SCHED_WAITPID)","pid_t","pid_t","FAR int *","int" "waitpid","sys/wait.h","defined(CONFIG_SCHED_WAITPID)","pid_t","pid_t","FAR int *","int"
1 _assert assert.h void FAR const char * int FAR const char * FAR void *
29 fchmod sys/stat.h int int mode_t
30 fchown unistd.h int int uid_t gid_t
31 fcntl fcntl.h int int int ... int
32 fork unistd.h defined(CONFIG_ARCH_HAVE_FORK) pid_t
33 fs_fdopen nuttx/fs/fs.h defined(CONFIG_FILE_STREAM) int int int FAR struct tcb_s * FAR struct file_struct **
34 fstat sys/stat.h int int FAR struct stat *
35 fstatfs sys/statfs.h int int FAR struct statfs *
205 unlink unistd.h !defined(CONFIG_DISABLE_MOUNTPOINT) int FAR const char *
206 unsetenv stdlib.h !defined(CONFIG_DISABLE_ENVIRON) int FAR const char *
207 utimens sys/stat.h int FAR const char * const struct timespec [2]|FAR const struct timespec *
vfork unistd.h defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_ARCH_HAVE_VFORK) pid_t
208 wait sys/wait.h defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT) pid_t FAR int *
209 waitid sys/wait.h defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT) int idtype_t id_t FAR siginfo_t * int
210 waitpid sys/wait.h defined(CONFIG_SCHED_WAITPID) pid_t pid_t FAR int * int