libs/libc/fork: add lib_fork implementation

1. add lib_fork api in libs/libc, we need a fork() api to implement the
fork relative method, such as pthread_atfork
2. rename the assembly fork entry function name to up_fork(), and rename
the up_fork() to arch specific name, such as
sim_fork()/arm_fork()/mips_fork() etc.

Signed-off-by: guoshichao <guoshichao@xiaomi.com>
This commit is contained in:
guoshichao 2023-07-16 11:34:17 +08:00 committed by Alin Jerpelea
parent 46b25b3849
commit 3524f4b9ce
23 changed files with 265 additions and 156 deletions

View File

@ -44,7 +44,7 @@
****************************************************************************/
/****************************************************************************
* Name: up_fork
* Name: arm_fork
*
* Description:
* The fork() function has the same effect as posix fork(), except that the
@ -57,8 +57,8 @@
* The overall sequence is:
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* transfers control up arm_fork().
* 2) arm_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.
@ -67,10 +67,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) arm_fork() provides any additional operating context. arm_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) arm_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* nxtask_abort_fork() may be called if an error occurs between steps 3 and
@ -87,7 +87,7 @@
*
****************************************************************************/
pid_t up_fork(const struct fork_s *context)
pid_t arm_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;

View File

@ -34,9 +34,11 @@
****************************************************************************/
/****************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -49,7 +51,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 2) arm_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.
@ -58,10 +60,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) arm_fork() provides any additional operating context. arm_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) arm_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -75,10 +77,10 @@
*
****************************************************************************/
.globl fork
.type fork, function
.globl up_fork
.type up_fork, function
fork:
up_fork:
/* Create a stack frame */
mov r0, sp /* Save the value of the stack on entry */
@ -97,12 +99,12 @@ fork:
mov r5, lr /* Copy lr to a low register */
stmia r1!, {r0,r5} /* Save sp and lr in the structure */
/* Then, call up_fork(), passing it a pointer to the stack structure */
/* Then, call arm_fork(), passing it a pointer to the stack structure */
mov r0, sp
bl up_fork
bl arm_fork
/* Recover r4-r7 that were destroyed before up_fork was called */
/* Recover r4-r7 that were destroyed before arm_fork was called */
mov r1, sp
ldmia r1!, {r4-r7}
@ -114,5 +116,5 @@ fork:
add sp, sp, #FORK_SIZEOF
bx lr
.size fork, .-fork
.size up_fork, .-up_fork
.end

View File

@ -26,7 +26,7 @@
#include "arm_fork.h"
MODULE fork
MODULE up_fork
SECTION .text:CODE:NOROOT(2)
/****************************************************************************
@ -37,17 +37,19 @@
* Public Symbols
****************************************************************************/
PUBLIC fork
EXTERN up_fork
PUBLIC up_fork
EXTERN arm_fork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -60,7 +62,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 2) arm_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.
@ -69,10 +71,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) arm_fork() provides any additional operating context. arm_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) arm_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -88,7 +90,7 @@
THUMB
fork:
up_fork:
/* Create a stack frame */
mov r0, sp /* Save the value of the stack on entry */
@ -113,12 +115,12 @@ fork:
/* Floating point registers (not yet) */
/* Then, call up_fork(), passing it a pointer to the stack structure */
/* Then, call arm_fork(), passing it a pointer to the stack structure */
mov r0, sp
bl up_fork
bl arm_fork
/* Release the stack data and return the value returned by up_fork */
/* Release the stack data and return the value returned by arm_fork */
ldr lr, [sp, #FORK_LR_OFFSET]
add sp, sp, #FORK_SIZEOF

View File

@ -88,8 +88,8 @@ void arm64_fork_fpureg_save(struct fork_s *context)
* The overall sequence is:
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* transfers control up arm64_fork().
* 2) arm64_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.
@ -98,10 +98,11 @@ void arm64_fork_fpureg_save(struct fork_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_fork() provides any additional operating context. up_fork must:
* 4) arm64_fork() provides any additional operating context. arm64_fork
* must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) arm64_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* nxtask_abort_fork() may be called if an error occurs between steps 3 and
@ -118,7 +119,7 @@ void arm64_fork_fpureg_save(struct fork_s *context)
*
****************************************************************************/
pid_t up_fork(const struct fork_s *context)
pid_t arm64_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;

View File

@ -42,6 +42,8 @@
* Name: fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -54,7 +56,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 2) arm64_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.
@ -63,10 +65,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) arm64_fork() provides any additional operating context. arm64_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) arm64_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -80,8 +82,8 @@
*
****************************************************************************/
GTEXT(fork)
SECTION_FUNC(text, fork)
GTEXT(up_fork)
SECTION_FUNC(text, up_fork)
/* Create a stack frame */
mov x0, sp /* Save the value of the stack on entry */
@ -118,13 +120,13 @@ SECTION_FUNC(text, fork)
ldp x0, x30, [sp], #16
#endif
/* Then, call up_fork(), passing it a pointer to the stack structure */
/* Then, call arm64_fork(), passing it a pointer to the stack structure */
mov x0, sp
mov x1, #0
bl up_fork
bl arm64_fork
/* Release the stack data and return the value returned by up_fork */
/* Release the stack data and return the value returned by arm64_fork */
add sp, sp, #8 * FORK_REGS_SIZE
ldp x29, x30, [sp]

View File

@ -38,7 +38,7 @@
****************************************************************************/
/****************************************************************************
* Name: up_fork
* Name: ceva_fork
*
* Description:
* The fork() function has the same effect as posix fork(), except that the
@ -51,8 +51,8 @@
* The overall sequence is:
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork()and calls nxtask_forksetup().
* transfers control up ceva_fork().
* 2) ceva_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.
@ -60,11 +60,12 @@
* - Configuration of environment variables
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) ceva_fork() provides any additional operating context. ceva_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_fork() then calls nxtask_start_fork()
* 5) ceva_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* nxtask_abort_fork() may be called if an error occurs between steps 3 & 6.
@ -80,7 +81,7 @@
*
****************************************************************************/
pid_t up_fork(const uint32_t *regs)
pid_t ceva_fork(const uint32_t *regs)
{
#ifdef CONFIG_SCHED_WAITPID
struct tcb_s *parent = this_task();

View File

@ -32,16 +32,18 @@
****************************************************************************/
.file "fork.S"
.extern _up_fork
.extern ceva_fork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -53,7 +55,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork()and calls nxtask_forksetup().
* 2) ceva_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.
@ -61,11 +63,11 @@
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) ceva_fork() provides any additional operating context. ceva_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_fork() then calls nxtask_forkstart()
* 5) ceva_fork() then calls nxtask_forkstart()
* 6) nxtask_forkstart() then executes the child thread.
*
* Input Paremeters:
@ -80,10 +82,10 @@
****************************************************************************/
.text
.public _fork
.func_start 3 _fork
.public up_fork
.func_start 3 up_fork
_fork:
up_fork:
/* Create a stack frame */
subs sp, #XCPTCONTEXT_SIZE, sp
@ -94,19 +96,19 @@ _fork:
mov sp, a1
trap
/* Then, call up_fork(), passing it a pointer to the stack structure */
/* Then, call ceva_fork(), passing it a pointer to the stack structure */
mov sp, a0
nop
push {dw} retreg
callr {t} _up_fork
callr {t} ceva_fork
pop {dw} retreg
nop
/* Release the stack data and return the value returned by up_fork */
/* Release the stack data and return the value returned by ceva_fork */
adds sp, #XCPTCONTEXT_SIZE, sp
ret
.func_end 3 _fork
.func_end 3 up_fork

View File

@ -42,16 +42,18 @@
****************************************************************************/
.file "fork.S"
.extern _up_fork
.extern up_fork
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -63,7 +65,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork()and calls nxtask_forksetup().
* 2) ceva_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.
@ -71,11 +73,11 @@
* - Configuration of environment variables
* - Setup the intput parameters for the task.
* - Initialization of the TCB (including call to up_initial_state()
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) ceva_fork() provides any additional operating context. ceva_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_fork() then calls nxtask_forkstart()
* 5) ceva_fork() then calls nxtask_forkstart()
* 6) nxtask_forkstart() then executes the child thread.
*
* Input Paremeters:
@ -90,10 +92,10 @@
****************************************************************************/
.text
.public _fork
.func_start 3 _fork
.public up_fork
.func_start 3 up_fork
_fork:
up_fork:
/* Create a stack frame */
modr (sp.ui).ui +#-XCPTCONTEXT_SIZE /* Allocate the structure on the stack */
@ -104,18 +106,18 @@ _fork:
mov sp.ui, r1.ui
trap {t0}
/* Then, call up_fork(), passing it a pointer to the stack structure */
/* Then, call ceva_fork(), passing it a pointer to the stack structure */
mov sp.ui, r0.ui
nop
push retreg.ui
callr #_up_fork, ?prx.b
callr #ceva_fork, ?prx.b
pop retreg.ui
nop
/* Release the stack data and return the value returned by up_fork */
/* Release the stack data and return the value returned by ceva_fork */
modr (sp.ui).ui +#XCPTCONTEXT_SIZE
ret ?prx.b
.func_end 3 _fork
.func_end 3 up_fork

View File

@ -35,16 +35,18 @@
************************************************************************************/
.file "fork.S"
.globl up_fork
.globl mips_fork
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -56,7 +58,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 2) mips_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.
@ -65,10 +67,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) mips_fork() provides any additional operating context. mips_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) mips_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -84,15 +86,15 @@
.text
.align 2
.globl fork
.type fork, function
.globl up_fork
.type up_fork, function
.set nomips16
#ifdef CONFIG_MIPS_MICROMIPS
.set micromips
#endif
.ent fork
.ent up_fork
fork:
up_fork:
/* Create a stack frame */
move $t0, $sp /* Save the value of the stack on entry */
@ -126,17 +128,17 @@ fork:
/* Floating point registers (not yet) */
/* Then, call up_fork(), passing it a pointer to the stack structure */
/* Then, call mips_fork(), passing it a pointer to the stack structure */
move $a0, $sp
jal up_fork
jal mips_fork
nop
/* Release the stack data and return the value returned by up_fork */
/* Release the stack data and return the value returned by mips_fork */
lw $ra, FORK_RA_OFFSET($sp)
addiu $sp, $sp, FORK_SIZEOF
j $ra
.end fork
.size fork, .-fork
.end up_fork
.size up_fork, .-up_fork

View File

@ -43,7 +43,7 @@
****************************************************************************/
/****************************************************************************
* Name: up_fork
* Name: mips_fork
*
* Description:
* The fork() function has the same effect as posix fork(), except that the
@ -56,8 +56,8 @@
* The overall sequence is:
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* transfers control up mips_fork().
* 2) mips_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.
@ -66,10 +66,11 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) mips_fork() provides any additional operating context. mips_fork
* must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) mips_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* nxtask_abort_fork() may be called if an error occurs between steps 3
@ -86,7 +87,7 @@
*
****************************************************************************/
pid_t up_fork(const struct fork_s *context)
pid_t mips_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;

View File

@ -36,8 +36,8 @@
****************************************************************************/
.file "fork.S"
.globl riscv_fork
.globl up_fork
.globl fork
/****************************************************************************
* Public Functions
@ -47,6 +47,8 @@
* Name: fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -59,7 +61,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 2) riscv_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.
@ -68,10 +70,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) riscv_fork() provides any additional operating context. riscv_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) riscv_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -85,9 +87,9 @@
*
****************************************************************************/
.type fork, function
.type up_fork, function
fork:
up_fork:
/* Create a stack frame */
addi sp, sp, -FORK_SIZEOF
@ -136,16 +138,16 @@ fork:
FSTORE fs11, FORK_FS11_OFFSET(sp)
#endif
/* Then, call up_fork(), passing it a pointer to the stack frame */
/* Then, call riscv_fork(), passing it a pointer to the stack frame */
mv a0, sp
call up_fork
call riscv_fork
/* Release the stack frame and return the value returned by up_fork */
/* Release the stack frame and return the value returned by riscv_fork */
REGLOAD x1, FORK_RA_OFFSET(sp)
addi sp, sp, FORK_SIZEOF
ret
.size fork, .-fork
.size up_fork, .-up_fork
.end

View File

@ -52,7 +52,7 @@
****************************************************************************/
/****************************************************************************
* Name: up_fork
* Name: riscv_fork
*
* Description:
* The fork() function has the same effect as posix fork(), except that the
@ -65,8 +65,8 @@
* The overall sequence is:
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* transfers control up riscv_fork().
* 2) riscv_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.
@ -75,10 +75,11 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) riscv_fork() provides any additional operating context. riscv_fork
* must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) riscv_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* nxtask_abort_fork() may be called if an error occurs between steps 3
@ -97,7 +98,7 @@
#ifdef CONFIG_ARCH_HAVE_FORK
pid_t up_fork(const struct fork_s *context)
pid_t riscv_fork(const struct fork_s *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;

View File

@ -43,7 +43,7 @@
****************************************************************************/
/****************************************************************************
* Name: up_fork
* Name: sim_fork
*
* Description:
* The fork() function has the same effect as posix fork(), except that the
@ -56,8 +56,8 @@
* The overall sequence is:
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* transfers control up sim_fork().
* 2) sim_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.
@ -66,10 +66,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) sim_fork() provides any additional operating context. sim_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) sim_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* nxtask_abort_fork() may be called if an error occurs between steps 3 and
@ -86,7 +86,7 @@
#ifdef CONFIG_SIM_ASAN
nosanitize_address
#endif
pid_t up_fork(const xcpt_reg_t *context)
pid_t sim_fork(const xcpt_reg_t *context)
{
struct tcb_s *parent = this_task();
struct task_tcb_s *child;

View File

@ -34,16 +34,18 @@
************************************************************************************/
.file "fork.S"
.globl up_fork
.globl sim_fork
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -54,8 +56,8 @@
* context as an argument. The overall sequence is:
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* transfers control up sim_fork().
* 2) sim_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.
@ -64,10 +66,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) sim_fork() provides any additional operating context. sim_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) sim_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -82,18 +84,18 @@
************************************************************************************/
.text
.globl fork
.type fork, @function
fork:
.globl up_fork
.type up_fork, @function
up_fork:
sub sp, sp, #XCPTCONTEXT_SIZE
mov r0, sp
bl setjmp
subs r0, #1
jz child
bl up_fork
bl sim_fork
child:
add sp, sp, #XCPTCONTEXT_SIZE
ret
.size fork, . - fork
.size up_fork, . - up_fork
.end

View File

@ -42,7 +42,7 @@
***************************************************************************/
.file "up_fork_arm64.S"
.globl SYMBOL(up_fork)
.globl SYMBOL(sim_fork)
.globl SYMBOL(setjmp)
/****************************************************************************
@ -50,9 +50,11 @@
***************************************************************************/
/****************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -60,12 +62,12 @@
* called, or calls any other function before successfully calling _exit()
* or one of the exec family of functions.
*
* This thin layer implements fork by simply calling up_fork() with the
* This thin layer implements fork by simply calling sim_fork() with the
* fork() context as an argument. The overall sequence is:
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* transfers control up sim_fork().
* 2) sim_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.
@ -74,10 +76,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) sim_fork() provides any additional operating context. sim_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) sim_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -92,10 +94,10 @@
***************************************************************************/
.text
.globl SYMBOL(fork)
.globl SYMBOL(up_fork)
.align 4
SYMBOL(fork):
SYMBOL(up_fork):
stp x29, x30, [sp] /* save FP/LR register */
sub sp, sp, #XCPTCONTEXT_SIZE /* area from stack for setjmp() */
@ -106,8 +108,8 @@ SYMBOL(fork):
subs x0, x0, #1 /* 0: parent / 1: child */
cbz x0, 1f /* child --> return */
mov x0, sp /* pass stack area to up_fork() */
bl SYMBOL(up_fork) /* further process task creation */
mov x0, sp /* pass stack area to sim_fork() */
bl SYMBOL(sim_fork) /* further process task creation */
1:
add sp, sp, #XCPTCONTEXT_SIZE /* release area from stack */

View File

@ -49,9 +49,11 @@
************************************************************************************/
/************************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -63,7 +65,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 2) sim_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.
@ -72,10 +74,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) sim_fork() provides any additional operating context. sim_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) sim_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -90,22 +92,22 @@
************************************************************************************/
.text
.globl SYMBOL(fork)
.globl SYMBOL(up_fork)
#ifdef __ELF__
.type SYMBOL(fork), @function
.type SYMBOL(up_fork), @function
#endif
SYMBOL(fork):
SYMBOL(up_fork):
sub $XCPTCONTEXT_SIZE, %esp
push %esp
call SYMBOL(setjmp)
sub $1, %eax
jz child
call SYMBOL(up_fork)
call SYMBOL(sim_fork)
child:
add $XCPTCONTEXT_SIZE+4, %esp
ret
#ifdef __ELF__
.size SYMBOL(fork), . - SYMBOL(fork)
.size SYMBOL(up_fork), . - SYMBOL(up_fork)
#endif

View File

@ -42,16 +42,18 @@
************************************************************************************/
.file "fork.S"
.globl up_fork
.globl sim_fork
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: fork
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
* 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
@ -63,7 +65,7 @@
*
* 1) User code calls fork(). fork() collects context information and
* transfers control up up_fork().
* 2) up_fork() and calls nxtask_setup_fork().
* 2) sim_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.
@ -72,10 +74,10 @@
* - Allocate and initialize the stack
* - Setup the input parameters for the task.
* - Initialization of the TCB (including call to up_initial_state())
* 4) up_fork() provides any additional operating context. up_fork must:
* 4) sim_fork() provides any additional operating context. sim_fork must:
* - Initialize special values in any CPU registers that were not
* already configured by up_initial_state()
* 5) up_fork() then calls nxtask_start_fork()
* 5) sim_fork() then calls nxtask_start_fork()
* 6) nxtask_start_fork() then executes the child thread.
*
* Input Parameters:
@ -90,12 +92,12 @@
************************************************************************************/
.text
.globl SYMBOL(fork)
.globl SYMBOL(up_fork)
#ifdef __ELF__
.type SYMBOL(fork), @function
.type SYMBOL(up_fork), @function
#endif
SYMBOL(fork):
SYMBOL(up_fork):
sub $XCPTCONTEXT_SIZE, %rsp
#ifdef CONFIG_SIM_X8664_MICROSOFT
mov %rsp, %rcx
@ -107,10 +109,10 @@ SYMBOL(fork):
sub $1, %eax
jz child
call SYMBOL(up_fork)
call SYMBOL(sim_fork)
child:
add $XCPTCONTEXT_SIZE, %rsp
ret
#ifdef __ELF__
.size SYMBOL(fork), . - SYMBOL(fork)
.size SYMBOL(up_fork), . - SYMBOL(up_fork)
#endif

View File

@ -168,6 +168,23 @@ extern initializer_t _einit[];
* logic from architecture-specific code.
****************************************************************************/
/****************************************************************************
* Name: up_fork
*
* Description:
* The up_fork() function is the base of fork() function that provided in
* libc, and fork() is implemented as a wrapper of up_fork() function.
*
* Returned Value:
* Upon successful completion, up_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_fork(void);
/****************************************************************************
* Name: up_initialize
*

View File

@ -115,7 +115,7 @@ SYSCALL_LOOKUP(task_setcancelstate, 2)
/* The following can be individually enabled */
#ifdef CONFIG_ARCH_HAVE_FORK
SYSCALL_LOOKUP(fork, 0)
SYSCALL_LOOKUP(up_fork, 0)
#endif
#ifdef CONFIG_SCHED_WAITPID

View File

@ -80,4 +80,11 @@ if(NOT CONFIG_DISABLE_MOUNTPOINTS)
list(APPEND SRCS lib_truncate.c lib_posix_fallocate.c)
endif()
if(CONFIG_ARCH_HAVE_FORK)
list(APPEND SRCS lib_fork.c)
if(CONFIG_SCHED_WAITPID)
list(APPEND SRCS lib_vfork.c)
endif()
endif()
target_sources(c PRIVATE ${SRCS})

View File

@ -49,6 +49,7 @@ CSRCS += lib_truncate.c lib_posix_fallocate.c
endif
ifeq ($(CONFIG_ARCH_HAVE_FORK),y)
CSRCS += lib_fork.c
ifeq ($(CONFIG_SCHED_WAITPID),y)
CSRCS += lib_vfork.c
endif

View File

@ -0,0 +1,58 @@
/****************************************************************************
* libs/libc/unistd/lib_fork.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 <nuttx/arch.h>
#include <unistd.h>
#if defined(CONFIG_ARCH_HAVE_FORK)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: fork
*
* Description:
* The fork() function is a wrapper of up_fork() syscall
*
* Returned Value:
* 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 fork(void)
{
pid_t pid;
pid = up_fork();
return pid;
}
#endif /* CONFIG_ARCH_HAVE_FORK */

View File

@ -29,7 +29,6 @@
"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,6 +203,7 @@
"umount2","sys/mount.h","!defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char *","unsigned int"
"unlink","unistd.h","!defined(CONFIG_DISABLE_MOUNTPOINT)","int","FAR const char *"
"unsetenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","FAR const char *"
"up_fork","nuttx/arch.h","defined(CONFIG_ARCH_HAVE_FORK)","pid_t"
"utimens","sys/stat.h","","int","FAR const char *","const struct timespec [2]|FAR const struct timespec *"
"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"

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