1
0
Fork 0
forked from nuttx/nuttx-update

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

View file

@ -11,7 +11,7 @@ config ARCH_ARM
bool "ARM"
select ARCH_HAVE_BACKTRACE
select ARCH_HAVE_INTERRUPTSTACK
select ARCH_HAVE_VFORK
select ARCH_HAVE_FORK
select ARCH_HAVE_STACKCHECK
select ARCH_HAVE_CUSTOMOPT
select ARCH_HAVE_STDARG_H
@ -27,7 +27,7 @@ config ARCH_ARM64
select ALARM_ARCH
select ARCH_HAVE_BACKTRACE
select ARCH_HAVE_INTERRUPTSTACK
select ARCH_HAVE_VFORK
select ARCH_HAVE_FORK
select ARCH_HAVE_STACKCHECK
select ARCH_HAVE_CUSTOMOPT
select ARCH_HAVE_STDARG_H
@ -81,7 +81,7 @@ config ARCH_RISCV
select ARCH_HAVE_CPUINFO
select ARCH_HAVE_INTERRUPTSTACK
select ARCH_HAVE_STACKCHECK
select ARCH_HAVE_VFORK
select ARCH_HAVE_FORK
select ARCH_HAVE_CUSTOMOPT
select ARCH_HAVE_SETJMP
select ARCH_HAVE_STDARG_H
@ -101,7 +101,7 @@ config ARCH_SIM
select ARCH_HAVE_TICKLESS
select ARCH_HAVE_POWEROFF
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_CUSTOMOPT
select ARCH_HAVE_TEXT_HEAP
@ -392,7 +392,7 @@ config ARCH_HAVE_MULTICPU
bool
default n
config ARCH_HAVE_VFORK
config ARCH_HAVE_FORK
bool
default n

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_nputs.c arm_releasestack.c arm_registerdump.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_TIMER_ARCH),y)
@ -73,7 +73,7 @@ ifeq ($(CONFIG_UNWINDER_ARM),y)
CMN_CSRCS += arm_backtrace_unwind.c
endif
CMN_ASRCS += vfork.S
CMN_ASRCS += fork.S
ifeq ($(CONFIG_ARCH_HAVE_TESTSET),y)
ifeq ($(CONFIG_ARCH_ARMV6M),)

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -35,7 +35,7 @@
#include <nuttx/arch.h>
#include <arch/irq.h>
#include "arm_vfork.h"
#include "arm_fork.h"
#include "arm_internal.h"
#include "sched/sched.h"
@ -44,22 +44,22 @@
****************************************************************************/
/****************************************************************************
* Name: up_vfork
* Name: up_fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -67,27 +67,27 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 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.
*
* Input Parameters:
* context - Caller context information saved by vfork()
* context - Caller context information saved by fork()
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
pid_t up_vfork(const struct vfork_s *context)
pid_t up_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
@ -97,7 +97,7 @@ pid_t up_vfork(const struct vfork_s *context)
uint32_t stacktop;
uint32_t stackutil;
sinfo("vfork context [%p]:\n", context);
sinfo("fork context [%p]:\n", context);
sinfo(" r4:%08" PRIx32 " r5:%08" PRIx32
" r6:%08" PRIx32 " r7:%08" PRIx32 "\n",
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. */
child = nxtask_setup_vfork((start_t)(context->lr & ~1));
child = nxtask_setup_fork((start_t)(context->lr & ~1));
if (!child)
{
serr("ERROR: nxtask_setup_vfork failed\n");
serr("ERROR: nxtask_setup_fork failed\n");
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
* feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble
* user follows all of the caveats of fork() usage, even this feeble
* effort is overkill.
*/
@ -229,9 +229,9 @@ pid_t up_vfork(const struct vfork_s *context)
}
#endif
/* And, finally, start the child task. On a failure, nxtask_start_vfork()
* will discard the TCB by calling nxtask_abort_vfork().
/* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_fork().
*/
return nxtask_start_vfork(child);
return nxtask_start_fork(child);
}

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -18,8 +18,8 @@
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_COMMON_ARM_VFORK_H
#define __ARCH_ARM_SRC_COMMON_ARM_VFORK_H
#ifndef __ARCH_ARM_SRC_COMMON_ARM_FORK_H
#define __ARCH_ARM_SRC_COMMON_ARM_FORK_H
/****************************************************************************
* Included Files
@ -31,26 +31,26 @@
* Pre-processor Definitions
****************************************************************************/
#define VFORK_R4_OFFSET (0*4) /* Volatile register r4 */
#define VFORK_R5_OFFSET (1*4) /* Volatile register r5 */
#define VFORK_R6_OFFSET (2*4) /* Volatile register r6 */
#define VFORK_R7_OFFSET (3*4) /* Volatile register r7 */
#define VFORK_R8_OFFSET (4*4) /* Volatile register r8 */
#define VFORK_R9_OFFSET (5*4) /* Volatile register r9 */
#define VFORK_R10_OFFSET (6*4) /* Volatile register r10 */
#define FORK_R4_OFFSET (0*4) /* Volatile register r4 */
#define FORK_R5_OFFSET (1*4) /* Volatile register r5 */
#define FORK_R6_OFFSET (2*4) /* Volatile register r6 */
#define FORK_R7_OFFSET (3*4) /* Volatile register r7 */
#define FORK_R8_OFFSET (4*4) /* Volatile register r8 */
#define FORK_R9_OFFSET (5*4) /* Volatile register r9 */
#define FORK_R10_OFFSET (6*4) /* Volatile register r10 */
#define VFORK_FP_OFFSET (7*4) /* Frame pointer */
#define VFORK_SP_OFFSET (8*4) /* Stack pointer*/
#define VFORK_LR_OFFSET (9*4) /* Return address*/
#define FORK_FP_OFFSET (7*4) /* Frame pointer */
#define FORK_SP_OFFSET (8*4) /* Stack pointer*/
#define FORK_LR_OFFSET (9*4) /* Return address*/
#define VFORK_SIZEOF (10*4)
#define FORK_SIZEOF (10*4)
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
struct vfork_s
struct fork_s
{
/* CPU registers */
@ -70,4 +70,4 @@ struct vfork_s
};
#endif
#endif /* __ARCH_ARM_SRC_COMMON_ARM_VFORK_H */
#endif /* __ARCH_ARM_SRC_COMMON_ARM_FORK_H */

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -24,33 +24,33 @@
#include <nuttx/config.h>
#include "arm_vfork.h"
#include "arm_fork.h"
.syntax unified
.file "vfork.S"
.file "fork.S"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the
* vfork() context as an argument. The overall sequence is:
* This thin layer implements fork by simply calling up_fork() with the
* fork() context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -58,31 +58,31 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
.globl vfork
.type vfork, function
.globl fork
.type fork, function
vfork:
fork:
/* Create a stack frame */
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 */
/* Save the volatile registers */
@ -97,22 +97,22 @@ vfork:
mov r5, lr /* Copy lr to a low register */
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
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
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
add sp, sp, #VFORK_SIZEOF
add sp, sp, #FORK_SIZEOF
bx lr
.size vfork, .-vfork
.size fork, .-fork
.end

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -24,9 +24,9 @@
#include <nuttx/config.h>
#include "arm_vfork.h"
#include "arm_fork.h"
MODULE vfork
MODULE fork
SECTION .text:CODE:NOROOT(2)
/****************************************************************************
@ -37,31 +37,31 @@
* Public Symbols
****************************************************************************/
PUBLIC vfork
EXTERN up_vfork
PUBLIC fork
EXTERN up_fork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the
* vfork() context as an argument. The overall sequence is:
* This thin layer implements fork by simply calling up_fork() with the
* fork() context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -69,17 +69,17 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
@ -88,40 +88,40 @@
THUMB
vfork:
fork:
/* Create a stack frame */
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 */
/* Save the volatile registers */
str r4, [sp, #VFORK_R4_OFFSET]
str r5, [sp, #VFORK_R5_OFFSET]
str r6, [sp, #VFORK_R6_OFFSET]
str r7, [sp, #VFORK_R7_OFFSET]
str r8, [sp, #VFORK_R8_OFFSET]
str r9, [sp, #VFORK_R9_OFFSET]
str r10, [sp, #VFORK_R10_OFFSET]
str r4, [sp, #FORK_R4_OFFSET]
str r5, [sp, #FORK_R5_OFFSET]
str r6, [sp, #FORK_R6_OFFSET]
str r7, [sp, #FORK_R7_OFFSET]
str r8, [sp, #FORK_R8_OFFSET]
str r9, [sp, #FORK_R9_OFFSET]
str r10, [sp, #FORK_R10_OFFSET]
/* Save the frame pointer, stack pointer, and return address */
str r11, [sp, #VFORK_FP_OFFSET] /* fp not defined. use r11 */
str r0, [sp, #VFORK_SP_OFFSET]
str lr, [sp, #VFORK_LR_OFFSET]
str r11, [sp, #FORK_FP_OFFSET] /* fp not defined. use r11 */
str r0, [sp, #FORK_SP_OFFSET]
str lr, [sp, #FORK_LR_OFFSET]
/* 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
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]
add sp, sp, #VFORK_SIZEOF
ldr lr, [sp, #FORK_LR_OFFSET]
add sp, sp, #FORK_SIZEOF
bx lr
END

View file

@ -35,7 +35,7 @@ endif
# Common assembly language files
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)
CMN_ASRCS += arm64_testset.S
@ -45,7 +45,7 @@ endif
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_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_getintstack.c arm64_registerdump.c
CMN_CSRCS += arm64_perf.c

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -37,7 +37,7 @@
#include "sched/sched.h"
#include "arm64_arch.h"
#include "arm64_vfork.h"
#include "arm64_fork.h"
#include "arm64_internal.h"
#include "arm64_fatal.h"
@ -55,7 +55,7 @@
#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;
@ -75,22 +75,22 @@ void arm64_vfork_fpureg_save(struct vfork_s *context)
#endif
/****************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -98,27 +98,27 @@ void arm64_vfork_fpureg_save(struct vfork_s *context)
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 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.
*
* Input Parameters:
* context - Caller context information saved by vfork()
* context - Caller context information saved by fork()
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
pid_t up_vfork(const struct vfork_s *context)
pid_t up_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;
@ -128,17 +128,17 @@ pid_t up_vfork(const struct vfork_s *context)
uint64_t stacktop;
uint64_t stackutil;
char *stack_ptr;
struct regs_context *pvforkctx;
struct regs_context *pforkctx;
#ifdef CONFIG_ARCH_FPU
struct fpu_reg *pfpuctx;
#endif
/* 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)
{
serr("ERROR: nxtask_setup_vfork failed\n");
serr("ERROR: nxtask_setup_fork failed\n");
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
* feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble
* user follows all of the caveats of fork() usage, even this feeble
* effort is overkill.
*/
@ -184,7 +184,7 @@ pid_t up_vfork(const struct vfork_s *context)
* child thread.
*/
/* make the vfork stack frame */
/* make the fork stack frame */
stack_ptr = (char *)newsp;
@ -198,51 +198,51 @@ pid_t up_vfork(const struct vfork_s *context)
#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;
pvforkctx->regs[REG_X8] = context->regs[VFORK_REG_X8];
pvforkctx->regs[REG_X9] = context->regs[VFORK_REG_X9];
pvforkctx->regs[REG_X10] = context->regs[VFORK_REG_X10];
pvforkctx->regs[REG_X11] = context->regs[VFORK_REG_X11];
pvforkctx->regs[REG_X12] = context->regs[VFORK_REG_X12];
pvforkctx->regs[REG_X13] = context->regs[VFORK_REG_X13];
pvforkctx->regs[REG_X14] = context->regs[VFORK_REG_X14];
pvforkctx->regs[REG_X15] = context->regs[VFORK_REG_X15];
pvforkctx->regs[REG_X16] = context->regs[VFORK_REG_X16];
pvforkctx->regs[REG_X17] = context->regs[VFORK_REG_X17];
pvforkctx->regs[REG_X18] = context->regs[VFORK_REG_X18];
pvforkctx->regs[REG_X19] = context->regs[VFORK_REG_X19];
pvforkctx->regs[REG_X20] = context->regs[VFORK_REG_X20];
pvforkctx->regs[REG_X21] = context->regs[VFORK_REG_X21];
pvforkctx->regs[REG_X22] = context->regs[VFORK_REG_X22];
pvforkctx->regs[REG_X23] = context->regs[VFORK_REG_X23];
pvforkctx->regs[REG_X24] = context->regs[VFORK_REG_X24];
pvforkctx->regs[REG_X25] = context->regs[VFORK_REG_X25];
pvforkctx->regs[REG_X26] = context->regs[VFORK_REG_X26];
pvforkctx->regs[REG_X27] = context->regs[VFORK_REG_X27];
pvforkctx->regs[REG_X28] = context->regs[VFORK_REG_X28];
pvforkctx->regs[REG_X29] = newfp;
pforkctx->regs[REG_X0] = 0;
pforkctx->regs[REG_X8] = context->regs[FORK_REG_X8];
pforkctx->regs[REG_X9] = context->regs[FORK_REG_X9];
pforkctx->regs[REG_X10] = context->regs[FORK_REG_X10];
pforkctx->regs[REG_X11] = context->regs[FORK_REG_X11];
pforkctx->regs[REG_X12] = context->regs[FORK_REG_X12];
pforkctx->regs[REG_X13] = context->regs[FORK_REG_X13];
pforkctx->regs[REG_X14] = context->regs[FORK_REG_X14];
pforkctx->regs[REG_X15] = context->regs[FORK_REG_X15];
pforkctx->regs[REG_X16] = context->regs[FORK_REG_X16];
pforkctx->regs[REG_X17] = context->regs[FORK_REG_X17];
pforkctx->regs[REG_X18] = context->regs[FORK_REG_X18];
pforkctx->regs[REG_X19] = context->regs[FORK_REG_X19];
pforkctx->regs[REG_X20] = context->regs[FORK_REG_X20];
pforkctx->regs[REG_X21] = context->regs[FORK_REG_X21];
pforkctx->regs[REG_X22] = context->regs[FORK_REG_X22];
pforkctx->regs[REG_X23] = context->regs[FORK_REG_X23];
pforkctx->regs[REG_X24] = context->regs[FORK_REG_X24];
pforkctx->regs[REG_X25] = context->regs[FORK_REG_X25];
pforkctx->regs[REG_X26] = context->regs[FORK_REG_X26];
pforkctx->regs[REG_X27] = context->regs[FORK_REG_X27];
pforkctx->regs[REG_X28] = context->regs[FORK_REG_X28];
pforkctx->regs[REG_X29] = newfp;
pvforkctx->spsr = SPSR_MODE_EL1H;
pforkctx->spsr = SPSR_MODE_EL1H;
#ifdef CONFIG_SUPPRESS_INTERRUPTS
pvforkctx->spsr |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT);
pforkctx->spsr |= (DAIF_IRQ_BIT | DAIF_FIQ_BIT);
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
pvforkctx->elr = (uint64_t)context->lr;
pforkctx->elr = (uint64_t)context->lr;
pvforkctx->exe_depth = 0;
pvforkctx->sp_elx = (uint64_t)pvforkctx;
pvforkctx->sp_el0 = (uint64_t)pvforkctx;
pvforkctx->tpidr_el0 = (uint64_t)(&child->cmn);
pvforkctx->tpidr_el1 = (uint64_t)(&child->cmn);
pforkctx->exe_depth = 0;
pforkctx->sp_elx = (uint64_t)pforkctx;
pforkctx->sp_el0 = (uint64_t)pforkctx;
pforkctx->tpidr_el0 = (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()
* will discard the TCB by calling nxtask_abort_vfork().
/* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_fork().
*/
return nxtask_start_vfork(child);
return nxtask_start_fork(child);
}

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -18,8 +18,8 @@
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_COMMON_ARM_VFORK_H
#define __ARCH_ARM_SRC_COMMON_ARM_VFORK_H
#ifndef __ARCH_ARM_SRC_COMMON_ARM_FORK_H
#define __ARCH_ARM_SRC_COMMON_ARM_FORK_H
/****************************************************************************
* Included Files
@ -32,48 +32,48 @@
* Pre-processor Definitions
****************************************************************************/
#define VFORK_REG_X0 (0)
#define VFORK_REG_X1 (1)
#define VFORK_REG_X2 (2)
#define VFORK_REG_X3 (3)
#define VFORK_REG_X4 (4)
#define VFORK_REG_X5 (5)
#define VFORK_REG_X6 (6)
#define VFORK_REG_X7 (7)
#define VFORK_REG_X8 (8)
#define VFORK_REG_X9 (9)
#define VFORK_REG_X10 (10)
#define VFORK_REG_X11 (11)
#define VFORK_REG_X12 (12)
#define VFORK_REG_X13 (13)
#define VFORK_REG_X14 (14)
#define VFORK_REG_X15 (15)
#define VFORK_REG_X16 (16)
#define VFORK_REG_X17 (17)
#define VFORK_REG_X18 (18)
#define VFORK_REG_X19 (19)
#define VFORK_REG_X20 (20)
#define VFORK_REG_X21 (21)
#define VFORK_REG_X22 (22)
#define VFORK_REG_X23 (23)
#define VFORK_REG_X24 (24)
#define VFORK_REG_X25 (25)
#define VFORK_REG_X26 (26)
#define VFORK_REG_X27 (27)
#define VFORK_REG_X28 (28)
#define VFORK_REG_FP (29) /* Frame pointer*/
#define VFORK_REG_LR (30) /* Return address*/
#define VFORK_REG_SP (31) /* Stack pointer*/
#define FORK_REG_X0 (0)
#define FORK_REG_X1 (1)
#define FORK_REG_X2 (2)
#define FORK_REG_X3 (3)
#define FORK_REG_X4 (4)
#define FORK_REG_X5 (5)
#define FORK_REG_X6 (6)
#define FORK_REG_X7 (7)
#define FORK_REG_X8 (8)
#define FORK_REG_X9 (9)
#define FORK_REG_X10 (10)
#define FORK_REG_X11 (11)
#define FORK_REG_X12 (12)
#define FORK_REG_X13 (13)
#define FORK_REG_X14 (14)
#define FORK_REG_X15 (15)
#define FORK_REG_X16 (16)
#define FORK_REG_X17 (17)
#define FORK_REG_X18 (18)
#define FORK_REG_X19 (19)
#define FORK_REG_X20 (20)
#define FORK_REG_X21 (21)
#define FORK_REG_X22 (22)
#define FORK_REG_X23 (23)
#define FORK_REG_X24 (24)
#define FORK_REG_X25 (25)
#define FORK_REG_X26 (26)
#define FORK_REG_X27 (27)
#define FORK_REG_X28 (28)
#define FORK_REG_FP (29) /* Frame pointer*/
#define FORK_REG_LR (30) /* Return address*/
#define FORK_REG_SP (31) /* Stack pointer*/
#ifdef CONFIG_ARCH_FPU
#define VFORK_REGS_SIZE (32 + XCPTCONTEXT_FPU_REGS)
#define FORK_REGS_SIZE (32 + XCPTCONTEXT_FPU_REGS)
#else
#define VFORK_REGS_SIZE (32)
#define FORK_REGS_SIZE (32)
#endif
#ifndef __ASSEMBLY__
struct vfork_s
struct fork_s
{
uint64_t regs[29];
uint64_t fp;
@ -86,4 +86,4 @@ struct vfork_s
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_COMMON_ARM_VFORK_H */
#endif /* __ARCH_ARM_SRC_COMMON_ARM_FORK_H */

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -26,36 +26,36 @@
#include "arch/syscall.h"
#include "arm64_macro.inc"
#include "arm64_vfork.h"
#include "arm64_fork.h"
/****************************************************************************
* Public Symbols
****************************************************************************/
.file "arm64_vfork_func.S"
.file "arm64_fork_func.S"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the
* vfork() context as an argument. The overall sequence is:
* This thin layer implements fork by simply calling up_fork() with the
* fork() context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -63,69 +63,70 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
GTEXT(vfork)
SECTION_FUNC(text, vfork)
GTEXT(fork)
SECTION_FUNC(text, fork)
/* Create a stack frame */
mov x0, sp /* Save the value of the stack on entry */
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*/
stp x0, x1, [sp, #8 * VFORK_REG_X0]
stp x2, x3, [sp, #8 * VFORK_REG_X2]
stp x4, x5, [sp, #8 * VFORK_REG_X4]
stp x6, x7, [sp, #8 * VFORK_REG_X6]
stp x8, x9, [sp, #8 * VFORK_REG_X8]
stp x10, x11, [sp, #8 * VFORK_REG_X10]
stp x12, x13, [sp, #8 * VFORK_REG_X12]
stp x14, x15, [sp, #8 * VFORK_REG_X14]
stp x16, x17, [sp, #8 * VFORK_REG_X16]
stp x18, x19, [sp, #8 * VFORK_REG_X18]
stp x20, x21, [sp, #8 * VFORK_REG_X20]
stp x22, x23, [sp, #8 * VFORK_REG_X22]
stp x24, x25, [sp, #8 * VFORK_REG_X24]
stp x26, x27, [sp, #8 * VFORK_REG_X26]
stp x28, x29, [sp, #8 * VFORK_REG_X28]
stp x0, x1, [sp, #8 * FORK_REG_X0]
stp x2, x3, [sp, #8 * FORK_REG_X2]
stp x4, x5, [sp, #8 * FORK_REG_X4]
stp x6, x7, [sp, #8 * FORK_REG_X6]
stp x8, x9, [sp, #8 * FORK_REG_X8]
stp x10, x11, [sp, #8 * FORK_REG_X10]
stp x12, x13, [sp, #8 * FORK_REG_X12]
stp x14, x15, [sp, #8 * FORK_REG_X14]
stp x16, x17, [sp, #8 * FORK_REG_X16]
stp x18, x19, [sp, #8 * FORK_REG_X18]
stp x20, x21, [sp, #8 * FORK_REG_X20]
stp x22, x23, [sp, #8 * FORK_REG_X22]
stp x24, x25, [sp, #8 * FORK_REG_X24]
stp x26, x27, [sp, #8 * FORK_REG_X26]
stp x28, x29, [sp, #8 * FORK_REG_X28]
/* Save the LR, stack pointer */
stp x30, x0, [sp, #8 * VFORK_REG_LR]
stp x30, x0, [sp, #8 * FORK_REG_LR]
/* Floating point registers */
#ifdef CONFIG_ARCH_FPU
mov x0, sp
stp x0, x30, [sp, #-16]!
bl arm64_vfork_fpureg_save
bl arm64_fork_fpureg_save
ldp x0, x30, [sp], #16
#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
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]
ret

View file

@ -42,7 +42,7 @@
#include "sched/sched.h"
#include "arm64_arch.h"
#include "arm64_vfork.h"
#include "arm64_fork.h"
#include "arm64_internal.h"
#include "arm64_fatal.h"
#include "arm64_fpu.h"

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -38,49 +38,49 @@
****************************************************************************/
/****************************************************************************
* Name: up_vfork
* Name: up_fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls nxtask_vforksetup().
* 3) nxtask_vforksetup() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork()and calls nxtask_forksetup().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart()
* 6) nxtask_vforkstart() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 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:
* regs - Caller context information saved by vfork()
* regs - Caller context information saved by fork()
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
pid_t up_vfork(const uint32_t *regs)
pid_t up_fork(const uint32_t *regs)
{
#ifdef CONFIG_SCHED_WAITPID
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. */
child = nxtask_vforksetup(parent->start, &argsize);
child = nxtask_setup_fork(parent->start, &argsize);
if (!child)
{
serr("ERROR: nxtask_vforksetup failed\n");
serr("ERROR: nxtask_setup_fork failed\n");
return (pid_t)ERROR;
}
@ -116,7 +116,7 @@ pid_t up_vfork(const uint32_t *regs)
if (ret != OK)
{
serr("ERROR: up_create_stack failed: %d\n", ret);
nxtask_vforkabort(child, -ret);
nxtask_abort_fork(child, -ret);
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
* feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble
* user follows all of the caveats of fork() usage, even this feeble
* effort is overkill.
*/
@ -197,11 +197,11 @@ pid_t up_vfork(const uint32_t *regs)
}
#endif
/* And, finally, start the child task. On a failure, nxtask_vforkstart()
* will discard the TCB by calling nxtask_vforkabort().
/* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_fork().
*/
return nxtask_vforkstart(child);
return nxtask_start_fork(child);
#else /* CONFIG_SCHED_WAITPID */
return (pid_t)ERROR;
#endif

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -31,48 +31,48 @@
* Public Symbols
****************************************************************************/
.file "vfork.S"
.extern _up_vfork
.file "fork.S"
.extern _up_fork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* The fork() function has the same effect as posix fork(), except that the 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 value from fork(), or returns
* 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.
*
* 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:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls nxtask_vforksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB. This
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork()and calls nxtask_forksetup().
* 3) task_forksetup() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart()
* 6) nxtask_vforkstart() then executes the child thread.
* 5) up_fork() then calls nxtask_forkstart()
* 6) nxtask_forkstart() then executes the child thread.
*
* Input Paremeters:
* None
*
* 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
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
@ -80,10 +80,10 @@
****************************************************************************/
.text
.public _vfork
.func_start 3 _vfork
.public _fork
.func_start 3 _fork
_vfork:
_fork:
/* Create a stack frame */
subs sp, #XCPTCONTEXT_SIZE, sp
@ -94,19 +94,19 @@ _vfork:
mov sp, a1
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
nop
push {dw} retreg
callr {t} _up_vfork
callr {t} _up_fork
pop {dw} retreg
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
ret
.func_end 3 _vfork
.func_end 3 _fork

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -41,48 +41,48 @@
* Public Symbols
****************************************************************************/
.file "vfork.S"
.extern _up_vfork
.file "fork.S"
.extern _up_fork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* The fork() function has the same effect as posix fork(), except that the 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 value from fork(), or returns
* 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.
*
* 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:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork()and calls nxtask_vforksetup().
* 3) task_vforksetup() allocates and configures the child task's TCB. This
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork()and calls nxtask_forksetup().
* 3) task_forksetup() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Allocate and initialize the stack
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_vforkstart()
* 6) nxtask_vforkstart() then executes the child thread.
* 5) up_fork() then calls nxtask_forkstart()
* 6) nxtask_forkstart() then executes the child thread.
*
* Input Paremeters:
* None
*
* 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
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
@ -90,10 +90,10 @@
****************************************************************************/
.text
.public _vfork
.func_start 3 _vfork
.public _fork
.func_start 3 _fork
_vfork:
_fork:
/* Create a stack frame */
modr (sp.ui).ui +#-XCPTCONTEXT_SIZE /* Allocate the structure on the stack */
@ -104,18 +104,18 @@ _vfork:
mov sp.ui, r1.ui
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
nop
push retreg.ui
callr #_up_vfork, ?prx.b
callr #_up_fork, ?prx.b
pop retreg.ui
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
ret ?prx.b
.func_end 3 _vfork
.func_end 3 _fork

View file

@ -41,7 +41,7 @@ endchoice
config ARCH_MIPS32
bool
default n
select ARCH_HAVE_VFORK
select ARCH_HAVE_FORK
config ARCH_MIPS_M4K
bool

View file

@ -87,10 +87,10 @@ config MIPS32_TOOLCHAIN_MICROCHIP_XC32_LICENSED
config MIPS32_FRAMEPOINTER
bool "ABI Uses Frame Pointer"
default n
depends on ARCH_HAVE_VFORK
depends on ARCH_HAVE_FORK
---help---
Register r30 may be a frame pointer in some ABIs. Or may just be
saved register s8. It makes a difference for vfork handling.
saved register s8. It makes a difference for fork handling.
config MIPS32_HAVE_ICACHE
bool

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -24,7 +24,7 @@
#include <nuttx/config.h>
#include "mips_vfork.h"
#include "mips_fork.h"
/************************************************************************************
* Pre-processor Definitions
@ -34,30 +34,30 @@
* Public Symbols
************************************************************************************/
.file "vfork.S"
.globl up_vfork
.file "fork.S"
.globl up_fork
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* The fork() function has the same effect as posix fork(), except that the 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 value from fork(), or returns
* 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.
*
* 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:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -65,17 +65,17 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
@ -84,59 +84,59 @@
.text
.align 2
.globl vfork
.type vfork, function
.globl fork
.type fork, function
.set nomips16
#ifdef CONFIG_MIPS_MICROMIPS
.set micromips
#endif
.ent vfork
.ent fork
vfork:
fork:
/* Create a stack frame */
move $t0, $sp /* Save the value of the stack on entry */
addiu $sp, $sp, -VFORK_SIZEOF /* Allocate the structure on the stack */
addiu $sp, $sp, -FORK_SIZEOF /* Allocate the structure on the stack */
/* CPU registers */
/* Save the saved registers */
sw $s0, VFORK_S0_OFFSET($sp)
sw $s1, VFORK_S1_OFFSET($sp)
sw $s2, VFORK_S2_OFFSET($sp)
sw $s3, VFORK_S3_OFFSET($sp)
sw $s4, VFORK_S4_OFFSET($sp)
sw $s5, VFORK_S5_OFFSET($sp)
sw $s6, VFORK_S6_OFFSET($sp)
sw $s7, VFORK_S7_OFFSET($sp)
sw $s0, FORK_S0_OFFSET($sp)
sw $s1, FORK_S1_OFFSET($sp)
sw $s2, FORK_S2_OFFSET($sp)
sw $s3, FORK_S3_OFFSET($sp)
sw $s4, FORK_S4_OFFSET($sp)
sw $s5, FORK_S5_OFFSET($sp)
sw $s6, FORK_S6_OFFSET($sp)
sw $s7, FORK_S7_OFFSET($sp)
#ifdef CONFIG_MIPS32_FRAMEPOINTER
sw $fp, VFORK_FP_OFFSET($sp)
sw $fp, FORK_FP_OFFSET($sp)
#else
sw $s8, VFORK_S8_OFFSET($sp)
sw $s8, FORK_S8_OFFSET($sp)
#endif
/* Save the global pointer, stack pointer, and return address */
sw $t0, VFORK_SP_OFFSET($sp)
sw $ra, VFORK_RA_OFFSET($sp)
sw $t0, FORK_SP_OFFSET($sp)
sw $ra, FORK_RA_OFFSET($sp)
#ifdef MIPS32_SAVE_GP
sw $gp, VFORK_GP_OFFSET($sp)
sw $gp, FORK_GP_OFFSET($sp)
#endif
/* 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
jal up_vfork
jal up_fork
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)
addiu $sp, $sp, VFORK_SIZEOF
lw $ra, FORK_RA_OFFSET($sp)
addiu $sp, $sp, FORK_SIZEOF
j $ra
.end vfork
.size vfork, .-vfork
.end fork
.size fork, .-fork

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -35,7 +35,7 @@
#include <nuttx/arch.h>
#include <arch/irq.h>
#include "mips_vfork.h"
#include "mips_fork.h"
#include "sched/sched.h"
/****************************************************************************
@ -43,22 +43,22 @@
****************************************************************************/
/****************************************************************************
* Name: up_vfork
* Name: up_fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* this consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -66,27 +66,27 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 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
*
* Input Parameters:
* context - Caller context information saved by vfork()
* context - Caller context information saved by fork()
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
pid_t up_vfork(const struct vfork_s *context)
pid_t up_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
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. */
child = nxtask_setup_vfork((start_t)context->ra);
child = nxtask_setup_fork((start_t)context->ra);
if (!child)
{
sinfo("nxtask_setup_vfork failed\n");
sinfo("nxtask_setup_fork failed\n");
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
* feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble
* user follows all of the caveats of fork() usage, even this feeble
* 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 */
#endif
/* And, finally, start the child task. On a failure, nxtask_start_vfork()
* will discard the TCB by calling nxtask_abort_vfork().
/* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_fork().
*/
return nxtask_start_vfork(child);
return nxtask_start_fork(child);
}

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -18,8 +18,8 @@
*
****************************************************************************/
#ifndef __ARCH_MIPS_SRC_MIPS32_MIPS_VFORK_H
#define __ARCH_MIPS_SRC_MIPS32_MIPS_VFORK_H
#ifndef __ARCH_MIPS_SRC_MIPS32_MIPS_FORK_H
#define __ARCH_MIPS_SRC_MIPS32_MIPS_FORK_H
/****************************************************************************
* Included Files
@ -33,10 +33,10 @@
****************************************************************************/
/* 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.
* r1 at Temporary generally used by assembler.
@ -59,28 +59,28 @@
* r31 ra Return address.
*/
#define VFORK_S0_OFFSET (0*4) /* Saved register s0 */
#define VFORK_S1_OFFSET (1*4) /* Saved register s1 */
#define VFORK_S2_OFFSET (2*4) /* Saved register s2 */
#define VFORK_S3_OFFSET (3*4) /* Saved register s3 */
#define VFORK_S4_OFFSET (4*4) /* Saved register s4 */
#define VFORK_S5_OFFSET (5*4) /* Saved register s5 */
#define VFORK_S6_OFFSET (6*4) /* Saved register s6 */
#define VFORK_S7_OFFSET (7*4) /* Saved register s7 */
#define FORK_S0_OFFSET (0*4) /* Saved register s0 */
#define FORK_S1_OFFSET (1*4) /* Saved register s1 */
#define FORK_S2_OFFSET (2*4) /* Saved register s2 */
#define FORK_S3_OFFSET (3*4) /* Saved register s3 */
#define FORK_S4_OFFSET (4*4) /* Saved register s4 */
#define FORK_S5_OFFSET (5*4) /* Saved register s5 */
#define FORK_S6_OFFSET (6*4) /* Saved register s6 */
#define FORK_S7_OFFSET (7*4) /* Saved register s7 */
#ifdef CONFIG_MIPS32_FRAMEPOINTER
# define VFORK_FP_OFFSET (8*4) /* Frame pointer */
# define FORK_FP_OFFSET (8*4) /* Frame pointer */
#else
# define VFORK_S8_OFFSET (8*4) /* Saved register s8 */
# define FORK_S8_OFFSET (8*4) /* Saved register s8 */
#endif
#define VFORK_SP_OFFSET (9*4) /* Stack pointer*/
#define VFORK_RA_OFFSET (10*4) /* Return address*/
#define FORK_SP_OFFSET (9*4) /* Stack pointer*/
#define FORK_RA_OFFSET (10*4) /* Return address*/
#ifdef MIPS32_SAVE_GP
# define VFORK_GP_OFFSET (11*4) /* Global pointer */
# define VFORK_SIZEOF (12*4)
# define FORK_GP_OFFSET (11*4) /* Global pointer */
# define FORK_SIZEOF (12*4)
#else
# define VFORK_SIZEOF (11*4)
# define FORK_SIZEOF (11*4)
#endif
/****************************************************************************
@ -88,7 +88,7 @@
****************************************************************************/
#ifndef __ASSEMBLY__
struct vfork_s
struct fork_s
{
/* CPU registers */
@ -115,4 +115,4 @@ struct vfork_s
};
#endif
#endif /* __ARCH_MIPS_SRC_MIPS32_MIPS_VFORK_H */
#endif /* __ARCH_MIPS_SRC_MIPS32_MIPS_FORK_H */

View file

@ -24,7 +24,7 @@ HEAD_ASRC = pic32mx_head.S
# 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_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
@ -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_schedulesigaction.c mips_sigdeliver.c mips_swint0.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

View file

@ -24,7 +24,7 @@ HEAD_ASRC = pic32mz_head.S
# 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_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
@ -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_schedulesigaction.c mips_sigdeliver.c mips_swint0.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

View file

@ -65,9 +65,9 @@ ifeq ($(CONFIG_STACK_COLORATION),y)
CMN_CSRCS += riscv_checkstack.c
endif
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
CMN_ASRCS += vfork.S
CMN_CSRCS += riscv_vfork.c
ifeq ($(CONFIG_ARCH_HAVE_FORK),y)
CMN_ASRCS += fork.S
CMN_CSRCS += riscv_fork.c
endif
ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -25,7 +25,7 @@
#include <nuttx/config.h>
#include "riscv_vfork.h"
#include "riscv_fork.h"
/****************************************************************************
* Pre-processor Definitions
@ -35,32 +35,32 @@
* Public Symbols
****************************************************************************/
.file "vfork.S"
.globl up_vfork
.globl vfork
.file "fork.S"
.globl up_fork
.globl fork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the
* vfork() context as an argument. The overall sequence is:
* This thin layer implements fork by simply calling up_fork() with the
* fork() context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -68,84 +68,84 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
*
****************************************************************************/
.type vfork, function
.type fork, function
vfork:
fork:
/* Create a stack frame */
addi sp, sp, -VFORK_SIZEOF
addi sp, sp, -FORK_SIZEOF
/* CPU registers */
/* Save the volatile registers */
REGSTORE s1, VFORK_S1_OFFSET(sp)
REGSTORE s2, VFORK_S2_OFFSET(sp)
REGSTORE s3, VFORK_S3_OFFSET(sp)
REGSTORE s4, VFORK_S4_OFFSET(sp)
REGSTORE s5, VFORK_S5_OFFSET(sp)
REGSTORE s6, VFORK_S6_OFFSET(sp)
REGSTORE s7, VFORK_S7_OFFSET(sp)
REGSTORE s8, VFORK_S8_OFFSET(sp)
REGSTORE s9, VFORK_S9_OFFSET(sp)
REGSTORE s10, VFORK_S10_OFFSET(sp)
REGSTORE s11, VFORK_S11_OFFSET(sp)
REGSTORE s1, FORK_S1_OFFSET(sp)
REGSTORE s2, FORK_S2_OFFSET(sp)
REGSTORE s3, FORK_S3_OFFSET(sp)
REGSTORE s4, FORK_S4_OFFSET(sp)
REGSTORE s5, FORK_S5_OFFSET(sp)
REGSTORE s6, FORK_S6_OFFSET(sp)
REGSTORE s7, FORK_S7_OFFSET(sp)
REGSTORE s8, FORK_S8_OFFSET(sp)
REGSTORE s9, FORK_S9_OFFSET(sp)
REGSTORE s10, FORK_S10_OFFSET(sp)
REGSTORE s11, FORK_S11_OFFSET(sp)
/* Save the frame pointer, stack pointer, and return address */
#ifdef CONFIG_RISCV_FRAMEPOINTER
REGSTORE fp, VFORK_FP_OFFSET(sp)
REGSTORE fp, FORK_FP_OFFSET(sp)
#else
REGSTORE s0, VFORK_S0_OFFSET(sp)
REGSTORE s0, FORK_S0_OFFSET(sp)
#endif
addi s0, sp, VFORK_SIZEOF
REGSTORE s0, VFORK_SP_OFFSET(sp) /* original SP */
REGSTORE x1, VFORK_RA_OFFSET(sp) /* return address */
addi s0, sp, FORK_SIZEOF
REGSTORE s0, FORK_SP_OFFSET(sp) /* original SP */
REGSTORE x1, FORK_RA_OFFSET(sp) /* return address */
/* Floating point registers */
#ifdef CONFIG_ARCH_FPU
FSTORE fs0, VFORK_FS0_OFFSET(sp)
FSTORE fs1, VFORK_FS1_OFFSET(sp)
FSTORE fs2, VFORK_FS2_OFFSET(sp)
FSTORE fs3, VFORK_FS3_OFFSET(sp)
FSTORE fs4, VFORK_FS4_OFFSET(sp)
FSTORE fs5, VFORK_FS5_OFFSET(sp)
FSTORE fs6, VFORK_FS6_OFFSET(sp)
FSTORE fs7, VFORK_FS7_OFFSET(sp)
FSTORE fs8, VFORK_FS8_OFFSET(sp)
FSTORE fs9, VFORK_FS9_OFFSET(sp)
FSTORE fs10, VFORK_FS10_OFFSET(sp)
FSTORE fs11, VFORK_FS11_OFFSET(sp)
FSTORE fs0, FORK_FS0_OFFSET(sp)
FSTORE fs1, FORK_FS1_OFFSET(sp)
FSTORE fs2, FORK_FS2_OFFSET(sp)
FSTORE fs3, FORK_FS3_OFFSET(sp)
FSTORE fs4, FORK_FS4_OFFSET(sp)
FSTORE fs5, FORK_FS5_OFFSET(sp)
FSTORE fs6, FORK_FS6_OFFSET(sp)
FSTORE fs7, FORK_FS7_OFFSET(sp)
FSTORE fs8, FORK_FS8_OFFSET(sp)
FSTORE fs9, FORK_FS9_OFFSET(sp)
FSTORE fs10, FORK_FS10_OFFSET(sp)
FSTORE fs11, FORK_FS11_OFFSET(sp)
#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
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)
addi sp, sp, VFORK_SIZEOF
REGLOAD x1, FORK_RA_OFFSET(sp)
addi sp, sp, FORK_SIZEOF
ret
.size vfork, .-vfork
.size fork, .-fork
.end

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -34,7 +34,7 @@
#include <nuttx/arch.h>
#include <arch/irq.h>
#include "riscv_vfork.h"
#include "riscv_fork.h"
#include "riscv_internal.h"
#include "sched/sched.h"
@ -52,22 +52,22 @@
****************************************************************************/
/****************************************************************************
* Name: up_vfork
* Name: up_fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -75,29 +75,29 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 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.
*
* Input Parameters:
* context - Caller context information saved by vfork()
* context - Caller context information saved by fork()
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* 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 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. */
child = nxtask_setup_vfork((start_t)context->ra);
child = nxtask_setup_fork((start_t)context->ra);
if (!child)
{
sinfo("nxtask_setup_vfork failed\n");
sinfo("nxtask_setup_fork failed\n");
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
* feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble
* user follows all of the caveats of fork() usage, even this feeble
* effort is overkill.
*/
@ -264,11 +264,11 @@ pid_t up_vfork(const struct vfork_s *context)
}
#endif /* CONFIG_LIB_SYSCALL */
/* And, finally, start the child task. On a failure, nxtask_start_vfork()
* will discard the TCB by calling nxtask_abort_vfork().
/* And, finally, start the child task. On a failure, nxtask_start_fork()
* 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 */

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -18,8 +18,8 @@
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_COMMON_RISCV_VFORK_H
#define __ARCH_RISCV_SRC_COMMON_RISCV_VFORK_H
#ifndef __ARCH_RISCV_SRC_COMMON_RISCV_FORK_H
#define __ARCH_RISCV_SRC_COMMON_RISCV_FORK_H
/****************************************************************************
* Included Files
@ -35,10 +35,10 @@
****************************************************************************/
/* 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
*
@ -62,59 +62,59 @@
* f2831 ft811 FP temporaries Caller
*/
#define VFORK_S1_OFFSET (1*INT_REG_SIZE) /* Saved register s1 */
#define VFORK_S2_OFFSET (2*INT_REG_SIZE) /* Saved register s2 */
#define VFORK_S3_OFFSET (3*INT_REG_SIZE) /* Saved register s3 */
#define VFORK_S4_OFFSET (4*INT_REG_SIZE) /* Saved register s4 */
#define VFORK_S5_OFFSET (5*INT_REG_SIZE) /* Saved register s5 */
#define VFORK_S6_OFFSET (6*INT_REG_SIZE) /* Saved register s6 */
#define VFORK_S7_OFFSET (7*INT_REG_SIZE) /* Saved register s7 */
#define VFORK_S8_OFFSET (8*INT_REG_SIZE) /* Saved register s8 */
#define VFORK_S9_OFFSET (9*INT_REG_SIZE) /* Saved register s9 */
#define VFORK_S10_OFFSET (10*INT_REG_SIZE) /* Saved register s10 */
#define VFORK_S11_OFFSET (11*INT_REG_SIZE) /* Saved register s11 */
#define FORK_S1_OFFSET (1*INT_REG_SIZE) /* Saved register s1 */
#define FORK_S2_OFFSET (2*INT_REG_SIZE) /* Saved register s2 */
#define FORK_S3_OFFSET (3*INT_REG_SIZE) /* Saved register s3 */
#define FORK_S4_OFFSET (4*INT_REG_SIZE) /* Saved register s4 */
#define FORK_S5_OFFSET (5*INT_REG_SIZE) /* Saved register s5 */
#define FORK_S6_OFFSET (6*INT_REG_SIZE) /* Saved register s6 */
#define FORK_S7_OFFSET (7*INT_REG_SIZE) /* Saved register s7 */
#define FORK_S8_OFFSET (8*INT_REG_SIZE) /* Saved register s8 */
#define FORK_S9_OFFSET (9*INT_REG_SIZE) /* Saved register s9 */
#define FORK_S10_OFFSET (10*INT_REG_SIZE) /* Saved register s10 */
#define FORK_S11_OFFSET (11*INT_REG_SIZE) /* Saved register s11 */
#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
# define VFORK_S0_OFFSET (0*INT_REG_SIZE) /* Saved register s0 */
# define FORK_S0_OFFSET (0*INT_REG_SIZE) /* Saved register s0 */
#endif
#define VFORK_SP_OFFSET (12*INT_REG_SIZE) /* Stack pointer*/
#define VFORK_RA_OFFSET (13*INT_REG_SIZE) /* Return address*/
#define FORK_SP_OFFSET (12*INT_REG_SIZE) /* Stack pointer*/
#define FORK_RA_OFFSET (13*INT_REG_SIZE) /* Return address*/
#ifdef RISCV_SAVE_GP
# define VFORK_GP_OFFSET (14*INT_REG_SIZE) /* Global pointer */
# define VFORK_INT_SIZE (15*INT_REG_SIZE)
# define FORK_GP_OFFSET (14*INT_REG_SIZE) /* Global pointer */
# define FORK_INT_SIZE (15*INT_REG_SIZE)
#else
# define VFORK_INT_SIZE (14*INT_REG_SIZE)
# define FORK_INT_SIZE (14*INT_REG_SIZE)
#endif
#ifdef CONFIG_ARCH_FPU
# define VFORK_FS0_OFFSET (VFORK_INT_SIZE + 0*FPU_REG_FULL_SIZE)
# define VFORK_FS1_OFFSET (VFORK_INT_SIZE + 1*FPU_REG_FULL_SIZE)
# define VFORK_FS2_OFFSET (VFORK_INT_SIZE + 2*FPU_REG_FULL_SIZE)
# define VFORK_FS3_OFFSET (VFORK_INT_SIZE + 3*FPU_REG_FULL_SIZE)
# define VFORK_FS4_OFFSET (VFORK_INT_SIZE + 4*FPU_REG_FULL_SIZE)
# define VFORK_FS5_OFFSET (VFORK_INT_SIZE + 5*FPU_REG_FULL_SIZE)
# define VFORK_FS6_OFFSET (VFORK_INT_SIZE + 6*FPU_REG_FULL_SIZE)
# define VFORK_FS7_OFFSET (VFORK_INT_SIZE + 7*FPU_REG_FULL_SIZE)
# define VFORK_FS8_OFFSET (VFORK_INT_SIZE + 8*FPU_REG_FULL_SIZE)
# define VFORK_FS9_OFFSET (VFORK_INT_SIZE + 9*FPU_REG_FULL_SIZE)
# define VFORK_FS10_OFFSET (VFORK_INT_SIZE + 10*FPU_REG_FULL_SIZE)
# define VFORK_FS11_OFFSET (VFORK_INT_SIZE + 11*FPU_REG_FULL_SIZE)
# define VFORK_FPU_SIZE (12*FPU_REG_FULL_SIZE)
# define FORK_FS0_OFFSET (FORK_INT_SIZE + 0*FPU_REG_FULL_SIZE)
# define FORK_FS1_OFFSET (FORK_INT_SIZE + 1*FPU_REG_FULL_SIZE)
# define FORK_FS2_OFFSET (FORK_INT_SIZE + 2*FPU_REG_FULL_SIZE)
# define FORK_FS3_OFFSET (FORK_INT_SIZE + 3*FPU_REG_FULL_SIZE)
# define FORK_FS4_OFFSET (FORK_INT_SIZE + 4*FPU_REG_FULL_SIZE)
# define FORK_FS5_OFFSET (FORK_INT_SIZE + 5*FPU_REG_FULL_SIZE)
# define FORK_FS6_OFFSET (FORK_INT_SIZE + 6*FPU_REG_FULL_SIZE)
# define FORK_FS7_OFFSET (FORK_INT_SIZE + 7*FPU_REG_FULL_SIZE)
# define FORK_FS8_OFFSET (FORK_INT_SIZE + 8*FPU_REG_FULL_SIZE)
# define FORK_FS9_OFFSET (FORK_INT_SIZE + 9*FPU_REG_FULL_SIZE)
# define FORK_FS10_OFFSET (FORK_INT_SIZE + 10*FPU_REG_FULL_SIZE)
# define FORK_FS11_OFFSET (FORK_INT_SIZE + 11*FPU_REG_FULL_SIZE)
# define FORK_FPU_SIZE (12*FPU_REG_FULL_SIZE)
#else
# define VFORK_FPU_SIZE (0)
# define FORK_FPU_SIZE (0)
#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
****************************************************************************/
#ifndef __ASSEMBLY__
struct vfork_s
struct fork_s
{
/* CPU registers */
@ -159,4 +159,4 @@ struct vfork_s
};
#endif
#endif /* __ARCH_RISCV_SRC_COMMON_RISCV_VFORK_H */
#endif /* __ARCH_RISCV_SRC_COMMON_RISCV_FORK_H */

View file

@ -46,16 +46,16 @@ endif
ifeq ($(CONFIG_HOST_X86_64),y)
ifeq ($(CONFIG_SIM_M32),y)
ASRCS += sim_vfork_x86.S
ASRCS += sim_fork_x86.S
else
ASRCS += sim_vfork_x86_64.S
ASRCS += sim_fork_x86_64.S
endif
else ifeq ($(CONFIG_HOST_X86),y)
ASRCS += sim_vfork_x86.S
ASRCS += sim_fork_x86.S
else ifeq ($(CONFIG_HOST_ARM),y)
ASRCS += sim_vfork_arm.S
ASRCS += sim_fork_arm.S
else ifeq ($(CONFIG_HOST_ARM64),y)
ASRCS += sim_vfork_arm64.S
ASRCS += sim_fork_arm64.S
endif
AOBJS = $(ASRCS:.S=$(OBJEXT))
@ -70,10 +70,8 @@ ifeq ($(CONFIG_SCHED_BACKTRACE),y)
CSRCS += sim_backtrace.c
endif
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
ifeq ($(CONFIG_SCHED_WAITPID),y)
CSRCS += sim_vfork.c
endif
ifeq ($(CONFIG_ARCH_HAVE_FORK),y)
CSRCS += sim_fork.c
endif
VPATH = :sim

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -43,22 +43,22 @@
****************************************************************************/
/****************************************************************************
* Name: up_vfork
* Name: up_fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -66,17 +66,17 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 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.
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
@ -86,7 +86,7 @@
#ifdef CONFIG_SIM_ASAN
nosanitize_address
#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 task_tcb_s *child;
@ -98,16 +98,16 @@ pid_t up_vfork(const xcpt_reg_t *context)
xcpt_reg_t stacktop;
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",
context[JB_FP], context[JB_SP], context[JB_PC]);
/* 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)
{
serr("ERROR: nxtask_setup_vfork failed\n");
serr("ERROR: nxtask_setup_fork failed\n");
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
* feeble because the stack surely contains invalid pointers and other
* content that will not work in the child context. However, if the
* user follows all of the caveats of vfork() usage, even this feeble
* user follows all of the caveats of fork() usage, even this feeble
* 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_SP] = newsp; /* Stack pointer */
/* And, finally, start the child task. On a failure, nxtask_start_vfork()
* will discard the TCB by calling nxtask_abort_vfork().
/* And, finally, start the child task. On a failure, nxtask_start_fork()
* will discard the TCB by calling nxtask_abort_fork().
*/
return nxtask_start_vfork(child);
return nxtask_start_fork(child);
}

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -33,30 +33,30 @@
* Public Symbols
************************************************************************************/
.file "vfork.S"
.globl up_vfork
.file "fork.S"
.globl up_fork
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* The fork() function has the same effect as posix fork(), except that the 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 value from fork(), or returns
* 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.
*
* 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:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -64,17 +64,17 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
@ -82,18 +82,18 @@
************************************************************************************/
.text
.globl vfork
.type vfork, @function
vfork:
.globl fork
.type fork, @function
fork:
sub sp, sp, #XCPTCONTEXT_SIZE
mov r0, sp
bl setjmp
subs r0, #1
jz child
bl up_vfork
bl up_fork
child:
add sp, sp, #XCPTCONTEXT_SIZE
ret
.size vfork, . - vfork
.size fork, . - fork
.end

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -41,8 +41,8 @@
* Public Symbols
***************************************************************************/
.file "up_vfork_arm64.S"
.globl SYMBOL(up_vfork)
.file "up_fork_arm64.S"
.globl SYMBOL(up_fork)
.globl SYMBOL(setjmp)
/****************************************************************************
@ -50,23 +50,23 @@
***************************************************************************/
/****************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* or one of the exec family of functions.
*
* This thin layer implements vfork by simply calling up_vfork() with the
* vfork() context as an argument. The overall sequence is:
* This thin layer implements fork by simply calling up_fork() with the
* fork() context as an argument. The overall sequence is:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -74,17 +74,17 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* and errno is set to indicate the error.
@ -92,10 +92,10 @@
***************************************************************************/
.text
.globl SYMBOL(vfork)
.globl SYMBOL(fork)
.align 4
SYMBOL(vfork):
SYMBOL(fork):
stp x29, x30, [sp] /* save FP/LR register */
sub sp, sp, #XCPTCONTEXT_SIZE /* area from stack for setjmp() */
@ -106,8 +106,8 @@ SYMBOL(vfork):
subs x0, x0, #1 /* 0: parent / 1: child */
cbz x0, 1f /* child --> return */
mov x0, sp /* pass stack area to up_vfork() */
bl SYMBOL(up_vfork) /* further process task creation */
mov x0, sp /* pass stack area to up_fork() */
bl SYMBOL(up_fork) /* further process task creation */
1:
add sp, sp, #XCPTCONTEXT_SIZE /* release area from stack */

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -41,30 +41,30 @@
* Public Symbols
************************************************************************************/
.file "vfork.S"
.globl up_vfork
.file "fork.S"
.globl up_fork
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* The fork() function has the same effect as posix fork(), except that the 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 value from fork(), or returns
* 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.
*
* 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:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -72,17 +72,17 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
@ -90,22 +90,22 @@
************************************************************************************/
.text
.globl SYMBOL(vfork)
.globl SYMBOL(fork)
#ifdef __ELF__
.type SYMBOL(vfork), @function
.type SYMBOL(fork), @function
#endif
SYMBOL(vfork):
SYMBOL(fork):
sub $XCPTCONTEXT_SIZE, %esp
push %esp
call SYMBOL(setjmp)
sub $1, %eax
jz child
call SYMBOL(up_vfork)
call SYMBOL(up_fork)
child:
add $XCPTCONTEXT_SIZE+4, %esp
ret
#ifdef __ELF__
.size SYMBOL(vfork), . - SYMBOL(vfork)
.size SYMBOL(fork), . - SYMBOL(fork)
#endif

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -41,30 +41,30 @@
* Public Symbols
************************************************************************************/
.file "vfork.S"
.globl up_vfork
.file "fork.S"
.globl up_fork
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: vfork
* Name: fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the behavior is
* undefined if the process created by vfork() either modifies any data other than
* a variable of type pid_t used to store the return value from vfork(), or returns
* from the function in which vfork() was called, or calls any other function before
* The fork() function has the same effect as posix fork(), except that the 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 value from fork(), or returns
* 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.
*
* 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:
*
* 1) User code calls vfork(). vfork() collects context information and
* transfers control up up_vfork().
* 2) up_vfork() and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB. This
* consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -72,17 +72,17 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* None
*
* 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
* returned to the parent, no child process is created, and errno is set to
* indicate the error.
@ -90,12 +90,12 @@
************************************************************************************/
.text
.globl SYMBOL(vfork)
.globl SYMBOL(fork)
#ifdef __ELF__
.type SYMBOL(vfork), @function
.type SYMBOL(fork), @function
#endif
SYMBOL(vfork):
SYMBOL(fork):
sub $XCPTCONTEXT_SIZE, %rsp
#ifdef CONFIG_SIM_X8664_MICROSOFT
mov %rsp, %rcx
@ -106,10 +106,11 @@ SYMBOL(vfork):
sub $1, %eax
jz child
call SYMBOL(up_vfork)
call SYMBOL(up_fork)
child:
add $XCPTCONTEXT_SIZE, %rsp
ret
#ifdef __ELF__
.size SYMBOL(vfork), . - SYMBOL(vfork)
.size SYMBOL(fork), . - SYMBOL(fork)
#endif

View file

@ -1078,12 +1078,12 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]);
#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.
* 2) vfork()and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 2) fork()and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - 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
* - Setup the input parameters for the task.
* - 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
* already configured by up_initial_state()
* 5) vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) fork() then calls nxtask_start_fork()
* 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.
*
****************************************************************************/
FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr);
pid_t nxtask_start_vfork(FAR struct task_tcb_s *child);
void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode);
FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr);
pid_t nxtask_start_fork(FAR struct task_tcb_s *child);
void nxtask_abort_fork(FAR struct task_tcb_s *child, int errcode);
/****************************************************************************
* Name: group_argvstr

View file

@ -114,8 +114,8 @@ SYSCALL_LOOKUP(task_setcancelstate, 2)
/* The following can be individually enabled */
#if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_ARCH_HAVE_VFORK)
SYSCALL_LOOKUP(vfork, 0)
#ifdef CONFIG_ARCH_HAVE_FORK
SYSCALL_LOOKUP(fork, 0)
#endif
#ifdef CONFIG_SCHED_WAITPID

View file

@ -307,6 +307,7 @@ extern "C"
/* Task Control Interfaces */
pid_t fork(void);
pid_t vfork(void);
pid_t getpid(void);
pid_t getpgrp(void);

View file

@ -48,6 +48,12 @@ ifneq ($(CONFIG_DISABLE_MOUNTPOINTS),y)
CSRCS += lib_truncate.c lib_posix_fallocate.c
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
DEPPATH += --dep-path unistd

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 */

View file

@ -29,10 +29,8 @@ ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
CSRCS += task_getppid.c task_reparent.c
endif
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
ifeq ($(CONFIG_SCHED_WAITPID),y)
CSRCS += task_vfork.c
endif
ifeq ($(CONFIG_ARCH_HAVE_FORK),y)
CSRCS += task_fork.c
endif
ifneq ($(CONFIG_BUILD_KERNEL),y)

View file

@ -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
* contributor license agreements. See the NOTICE file distributed with
@ -40,33 +40,33 @@
#include "task/task.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
****************************************************************************/
/****************************************************************************
* Name: nxtask_setup_vfork
* Name: nxtask_setup_fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as posix fork(), except that the
* 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
* 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()
* 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
* is:
*
* 1) User code calls vfork(). vfork() is provided in
* 1) User code calls fork(). fork() is provided in
* architecture-specific code.
* 2) vfork()and calls nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 2) fork()and calls nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -74,24 +74,24 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_vfork() provides any additional operating context. up_vfork must:
* 4) up_fork() provides any additional operating context. up_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) up_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* retaddr - Return address
* argsize - Location to return the argument size
*
* 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
* 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 *parent;
@ -226,24 +226,24 @@ errout:
}
/****************************************************************************
* Name: nxtask_start_vfork
* Name: nxtask_start_fork
*
* Description:
* The vfork() function has the same effect as fork(), except that the
* behavior is undefined if the process created by vfork() either modifies
* The fork() function has the same effect as fork(), except that the
* 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
* 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()
* 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
* sequence is:
*
* 1) User code calls vfork()
* 2) Architecture-specific code provides vfork()and calls
* nxtask_setup_vfork().
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB.
* 1) User code calls fork()
* 2) Architecture-specific code provides fork()and calls
* nxtask_setup_fork().
* 3) nxtask_setup_fork() allocates and configures the child task's TCB.
* This consists of:
* - Allocation of the child task's TCB.
* - Initialization of file descriptors and streams
@ -251,29 +251,28 @@ errout:
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - 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
* already configured by up_initial_state()
* 5) vfork() then calls nxtask_start_vfork()
* 6) nxtask_start_vfork() then executes the child thread.
* 5) fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
* retaddr - The return address from vfork() where the child task
* will be started.
* child - The task_tcb_s struct instance that created by
* nxtask_setup_fork() method
* wait_child - whether need to wait until the child is running finished
*
* 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.
* Otherwise, -1 is returned to the parent, no child process is created,
* 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;
int rc = 0;
int ret;
sinfo("Starting Child TCB=%p\n", 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);
/* 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();
return pid;
}
/****************************************************************************
* Name: nxtask_abort_vfork
* Name: nxtask_abort_fork
*
* Description:
* Recover from any errors after nxtask_setup_vfork() was called.
* Recover from any errors after nxtask_setup_fork() was called.
*
* Returned Value:
* 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() */
@ -345,4 +321,4 @@ void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode)
set_errno(errcode);
}
#endif /* CONFIG_ARCH_HAVE_VFORK && CONFIG_SCHED_WAITPID */
#endif /* CONFIG_ARCH_HAVE_FORK */

View file

@ -29,6 +29,7 @@
"fchmod","sys/stat.h","","int","int","mode_t"
"fchown","unistd.h","","int","int","uid_t","gid_t"
"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 **"
"fstat","sys/stat.h","","int","int","FAR struct stat *"
"fstatfs","sys/statfs.h","","int","int","FAR struct statfs *"
@ -204,7 +205,6 @@
"unlink","unistd.h","!defined(CONFIG_DISABLE_MOUNTPOINT)","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 *"
"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 *"
"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"

Can't render this file because it has a wrong number of fields in line 2.