vfork: support sim vfork
N/A Change-Id: I15920bcbacfc5ea519cfe12c39cb64dfe6365838 Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
6fd80289f9
commit
f6cfd1c87b
8 changed files with 543 additions and 2 deletions
|
@ -73,6 +73,7 @@ config ARCH_SIM
|
|||
select ARCH_HAVE_TICKLESS
|
||||
select ARCH_HAVE_POWEROFF
|
||||
select ARCH_HAVE_TESTSET
|
||||
select ARCH_HAVE_VFORK
|
||||
select ALARM_ARCH
|
||||
select ONESHOT
|
||||
select SERIAL_CONSOLE
|
||||
|
|
|
@ -52,12 +52,15 @@
|
|||
/* Storage order: %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15, %rip */
|
||||
|
||||
# define XCPTCONTEXT_REGS 8
|
||||
# define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS)
|
||||
#elif defined(CONFIG_HOST_X86) || defined(CONFIG_SIM_M32)
|
||||
/* Storage order: %ebx, %esi, %edi, %ebp, sp, and return PC */
|
||||
|
||||
# define XCPTCONTEXT_REGS 6
|
||||
# define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
|
||||
#elif defined(CONFIG_HOST_ARM)
|
||||
# define XCPTCONTEXT_REGS 16
|
||||
# define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -58,13 +58,17 @@ REQUIREDOBJS = $(LINKOBJS)
|
|||
ifeq ($(CONFIG_HOST_X86_64),y)
|
||||
ifeq ($(CONFIG_SIM_M32),y)
|
||||
ASRCS += up_setjmp32.S
|
||||
ASRCS += up_vfork32.S
|
||||
else
|
||||
ASRCS += up_setjmp64.S
|
||||
ASRCS += up_vfork64.S
|
||||
endif
|
||||
else ifeq ($(CONFIG_HOST_X86),y)
|
||||
ASRCS += up_setjmp32.S
|
||||
ASRCS += up_vfork32.S
|
||||
else ifeq ($(CONFIG_HOST_ARM),y)
|
||||
ASRCS += up_setjmp_arm.S
|
||||
ASRCS += up_vfork_arm.S
|
||||
endif
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
|
@ -76,6 +80,12 @@ CSRCS += up_reprioritizertr.c up_exit.c up_schedulesigaction.c
|
|||
CSRCS += up_allocateheap.c up_uart.c
|
||||
CSRCS += up_copyfullstate.c
|
||||
|
||||
ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
|
||||
ifeq ($(CONFIG_SCHED_WAITPID),y)
|
||||
CSRCS += up_vfork.c
|
||||
endif
|
||||
endif
|
||||
|
||||
VPATH = sim
|
||||
DEPPATH = $(patsubst %,--dep-path %,$(subst :, ,$(VPATH)))
|
||||
|
||||
|
|
|
@ -94,8 +94,9 @@
|
|||
|
||||
/* Compatibility definitions */
|
||||
|
||||
# define JB_SP JB_RSP
|
||||
# define JB_PC JB_RSI
|
||||
# define JB_FP JB_RBP
|
||||
# define JB_SP JB_RSP
|
||||
# define JB_PC JB_RSI
|
||||
|
||||
#elif defined(CONFIG_HOST_X86) || defined(CONFIG_SIM_M32)
|
||||
/* Storage order: %ebx, $esi, %edi, %ebp, sp, and return PC */
|
||||
|
@ -117,7 +118,13 @@
|
|||
# define JB_PC (5)
|
||||
|
||||
# endif /* __ASSEMBLY__ */
|
||||
|
||||
/* Compatibility definitions */
|
||||
|
||||
# define JB_FP JB_EBP
|
||||
|
||||
#elif defined(CONFIG_HOST_ARM)
|
||||
# define JB_FP 7
|
||||
# define JB_SP 8
|
||||
# define JB_PC 9
|
||||
#endif
|
||||
|
|
193
arch/sim/src/sim/up_vfork.c
Normal file
193
arch/sim/src/sim/up_vfork.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/****************************************************************************
|
||||
* arch/sim/src/sim/up_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 <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_vfork
|
||||
*
|
||||
* Description:
|
||||
* The vfork() function has the same effect as fork(), except that the
|
||||
* behavior is undefined if the process created by vfork() either modifies
|
||||
* any data other than a variable of type pid_t used to store the return
|
||||
* value from vfork(), or returns from the function in which vfork() was
|
||||
* called, or calls any other function before successfully calling _exit()
|
||||
* or one of the exec family of functions.
|
||||
*
|
||||
* The overall sequence is:
|
||||
*
|
||||
* 1) User code calls vfork(). vfork() collects context information and
|
||||
* transfers control up up_vfork().
|
||||
* 2) up_vfork()and calls nxtask_setup_vfork().
|
||||
* 3) nxtask_setup_vfork() 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:
|
||||
* - 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_start_vfork()
|
||||
* 6) nxtask_start_vfork() then executes the child thread.
|
||||
*
|
||||
* nxtask_abort_vfork() 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
|
||||
* 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 xcpt_reg_t *context)
|
||||
{
|
||||
struct tcb_s *parent = this_task();
|
||||
struct task_tcb_s *child;
|
||||
size_t stacksize;
|
||||
xcpt_reg_t newsp;
|
||||
xcpt_reg_t newfp;
|
||||
xcpt_reg_t stackutil;
|
||||
size_t argsize;
|
||||
void *argv;
|
||||
int ret;
|
||||
|
||||
sinfo("vfork context [%p]:\n", context);
|
||||
sinfo(" frame pointer:%08" PRIxPTR " sp:%08" PRIxPTR " pc:%08" PRIxPTR ""
|
||||
"\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]), &argsize);
|
||||
if (!child)
|
||||
{
|
||||
serr("ERROR: nxtask_setup_vfork failed\n");
|
||||
return (pid_t)ERROR;
|
||||
}
|
||||
|
||||
sinfo("TCBs: Parent=%p Child=%p\n", parent, child);
|
||||
|
||||
/* Get the size of the parent task's stack. */
|
||||
|
||||
stacksize = parent->adj_stack_size;
|
||||
|
||||
/* Allocate the stack for the TCB */
|
||||
|
||||
ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
|
||||
parent->flags & TCB_FLAG_TTYPE_MASK);
|
||||
if (ret != OK)
|
||||
{
|
||||
serr("ERROR: up_create_stack failed: %d\n", ret);
|
||||
nxtask_abort_vfork(child, -ret);
|
||||
return (pid_t)ERROR;
|
||||
}
|
||||
|
||||
/* Allocate the memory and copy argument from parent task */
|
||||
|
||||
argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
|
||||
|
||||
memcpy(argv, parent->adj_stack_ptr, argsize);
|
||||
|
||||
/* How much of the parent's stack was utilized? The ARM uses
|
||||
* a push-down stack so that the current stack pointer should
|
||||
* be lower than the initial, adjusted stack pointer. The
|
||||
* stack usage should be the difference between those two.
|
||||
*/
|
||||
|
||||
DEBUGASSERT((xcpt_reg_t)parent->adj_stack_ptr > context[JB_SP]);
|
||||
stackutil = (xcpt_reg_t)parent->adj_stack_ptr - context[JB_SP];
|
||||
|
||||
sinfo("Parent: stacksize:%zu stackutil:%" PRIdPTR "\n",
|
||||
stacksize, stackutil);
|
||||
|
||||
/* 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
|
||||
* effort is overkill.
|
||||
*/
|
||||
|
||||
newsp = (xcpt_reg_t)child->cmn.adj_stack_ptr - stackutil;
|
||||
memcpy((void *)newsp, (const void *)context[JB_SP], stackutil);
|
||||
|
||||
/* Was there a frame pointer in place before? */
|
||||
|
||||
if (context[JB_FP] <= (xcpt_reg_t)parent->adj_stack_ptr &&
|
||||
context[JB_FP] >= (xcpt_reg_t)parent->adj_stack_ptr -
|
||||
stacksize)
|
||||
{
|
||||
xcpt_reg_t frameutil = (xcpt_reg_t)parent->adj_stack_ptr -
|
||||
context[JB_FP];
|
||||
newfp = (xcpt_reg_t)child->cmn.adj_stack_ptr - frameutil;
|
||||
}
|
||||
else
|
||||
{
|
||||
newfp = context[JB_FP];
|
||||
}
|
||||
|
||||
sinfo("Parent: stack base:%p SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
|
||||
parent->adj_stack_ptr, context[JB_SP], context[JB_FP]);
|
||||
sinfo("Child: stack base:%p SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
|
||||
child->cmn.adj_stack_ptr, newsp, newfp);
|
||||
|
||||
/* Update the stack pointer, frame pointer, and volatile registers. When
|
||||
* the child TCB was initialized, all of the values were set to zero.
|
||||
* up_initial_state() altered a few values, but the return value in R0
|
||||
* should be cleared to zero, providing the indication to the newly started
|
||||
* child thread.
|
||||
*/
|
||||
|
||||
memcpy(child->cmn.xcp.regs, context, sizeof(xcpt_reg_t) *
|
||||
XCPTCONTEXT_REGS);
|
||||
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().
|
||||
*/
|
||||
|
||||
return nxtask_start_vfork(child);
|
||||
}
|
112
arch/sim/src/sim/up_vfork32.S
Normal file
112
arch/sim/src/sim/up_vfork32.S
Normal file
|
@ -0,0 +1,112 @@
|
|||
/************************************************************************************
|
||||
* arch/sim/src/sim/up_vfork32.S
|
||||
*
|
||||
* 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 "up_internal.h"
|
||||
#include <arch/irq.h>
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# define SYMBOL(s) _##s
|
||||
#elif defined(__ELF__)
|
||||
# define SYMBOL(s) s
|
||||
#else
|
||||
# define SYMBOL(s) _##s
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************/
|
||||
|
||||
.file "vfork.S"
|
||||
.globl up_vfork
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: vfork
|
||||
*
|
||||
* Description:
|
||||
* The vfork() function has the same effect as fork(), except that the behavior is
|
||||
* undefined if the process created by vfork() either modifies any data other than
|
||||
* a variable of type pid_t used to store the return value from vfork(), or returns
|
||||
* from the function in which vfork() was called, or calls any other function before
|
||||
* successfully calling _exit() or one of the exec family of functions.
|
||||
*
|
||||
* This thin layer implements vfork by simply calling up_vfork() with the vfork()
|
||||
* context as an argument. The overall sequence is:
|
||||
*
|
||||
* 1) User code calls vfork(). vfork() collects context information and
|
||||
* transfers control up up_vfork().
|
||||
* 2) up_vfork()and calls nxtask_setup_vfork().
|
||||
* 3) nxtask_setup_vfork() 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:
|
||||
* - 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_start_vfork()
|
||||
* 6) nxtask_start_vfork() then executes the child thread.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl SYMBOL(vfork)
|
||||
#ifdef __ELF__
|
||||
.type SYMBOL(vfork), @function
|
||||
#endif
|
||||
|
||||
SYMBOL(vfork):
|
||||
sub $XCPTCONTEXT_SIZE, %esp
|
||||
push %esp
|
||||
call SYMBOL(up_setjmp)
|
||||
|
||||
sub $1, %eax
|
||||
jz child
|
||||
call SYMBOL(up_vfork)
|
||||
child:
|
||||
add $XCPTCONTEXT_SIZE+4, %esp
|
||||
ret
|
||||
#ifdef __ELF__
|
||||
.size SYMBOL(vfork), . - SYMBOL(vfork)
|
||||
#endif
|
116
arch/sim/src/sim/up_vfork64.S
Normal file
116
arch/sim/src/sim/up_vfork64.S
Normal file
|
@ -0,0 +1,116 @@
|
|||
/************************************************************************************
|
||||
* arch/sim/src/sim/up_vfork64.S
|
||||
*
|
||||
* 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 "up_internal.h"
|
||||
#include <arch/irq.h>
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# define SYMBOL(s) _##s
|
||||
#elif defined(__ELF__)
|
||||
# define SYMBOL(s) s
|
||||
#else
|
||||
# define SYMBOL(s) _##s
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************/
|
||||
|
||||
.file "vfork.S"
|
||||
.globl up_vfork
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: vfork
|
||||
*
|
||||
* Description:
|
||||
* The vfork() function has the same effect as fork(), except that the behavior is
|
||||
* undefined if the process created by vfork() either modifies any data other than
|
||||
* a variable of type pid_t used to store the return value from vfork(), or returns
|
||||
* from the function in which vfork() was called, or calls any other function before
|
||||
* successfully calling _exit() or one of the exec family of functions.
|
||||
*
|
||||
* This thin layer implements vfork by simply calling up_vfork() with the vfork()
|
||||
* context as an argument. The overall sequence is:
|
||||
*
|
||||
* 1) User code calls vfork(). vfork() collects context information and
|
||||
* transfers control up up_vfork().
|
||||
* 2) up_vfork()and calls nxtask_setup_vfork().
|
||||
* 3) nxtask_setup_vfork() 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:
|
||||
* - 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_start_vfork()
|
||||
* 6) nxtask_start_vfork() then executes the child thread.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl SYMBOL(vfork)
|
||||
#ifdef __ELF__
|
||||
.type SYMBOL(vfork), @function
|
||||
#endif
|
||||
|
||||
SYMBOL(vfork):
|
||||
sub $XCPTCONTEXT_SIZE, %rsp
|
||||
#ifdef CONFIG_SIM_X8664_MICROSOFT
|
||||
mov %rsp, %rcx
|
||||
#else /* if defined(CONFIG_SIM_X8664_SYSTEMV) */
|
||||
mov %rsp, %rdi
|
||||
#endif
|
||||
call SYMBOL(up_setjmp)
|
||||
|
||||
sub $1, %eax
|
||||
jz child
|
||||
call SYMBOL(up_vfork)
|
||||
child:
|
||||
add $XCPTCONTEXT_SIZE, %rsp
|
||||
ret
|
||||
#ifdef __ELF__
|
||||
.size SYMBOL(vfork), . - SYMBOL(vfork)
|
||||
#endif
|
99
arch/sim/src/sim/up_vfork_arm.S
Normal file
99
arch/sim/src/sim/up_vfork_arm.S
Normal file
|
@ -0,0 +1,99 @@
|
|||
/************************************************************************************
|
||||
* arch/sim/src/sim/up_vfork_arm.S
|
||||
*
|
||||
* 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 "up_internal.h"
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************/
|
||||
|
||||
.file "vfork.S"
|
||||
.globl up_vfork
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: vfork
|
||||
*
|
||||
* Description:
|
||||
* The vfork() function has the same effect as fork(), except that the behavior is
|
||||
* undefined if the process created by vfork() either modifies any data other than
|
||||
* a variable of type pid_t used to store the return value from vfork(), or returns
|
||||
* from the function in which vfork() was called, or calls any other function before
|
||||
* successfully calling _exit() or one of the exec family of functions.
|
||||
*
|
||||
* This thin layer implements vfork by simply calling up_vfork() with the vfork()
|
||||
* context as an argument. The overall sequence is:
|
||||
*
|
||||
* 1) User code calls vfork(). vfork() collects context information and
|
||||
* transfers control up up_vfork().
|
||||
* 2) up_vfork()and calls nxtask_setup_vfork().
|
||||
* 3) nxtask_setup_vfork() 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:
|
||||
* - 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_start_vfork()
|
||||
* 6) nxtask_start_vfork() then executes the child thread.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl vfork
|
||||
.type vfork, @function
|
||||
vfork:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
mov r0, sp
|
||||
bl up_setjmp
|
||||
|
||||
subs r0, #1
|
||||
jz child
|
||||
bl up_vfork
|
||||
child:
|
||||
add sp, sp, #XCPTCONTEXT_SIZE
|
||||
ret
|
||||
.size vfork, . - vfork
|
||||
.end
|
Loading…
Reference in a new issue