diff --git a/components/lwp/arch/aarch64/cortex-a/lwp_arch.c b/components/lwp/arch/aarch64/cortex-a/lwp_arch.c index d4a4f7e64d..593c19d8ee 100644 --- a/components/lwp/arch/aarch64/cortex-a/lwp_arch.c +++ b/components/lwp/arch/aarch64/cortex-a/lwp_arch.c @@ -122,7 +122,7 @@ void *arch_signal_ucontext_restore(rt_base_t user_sp) else { LOG_I("User frame corrupted during signal handling\nexiting..."); - sys_exit(EXIT_FAILURE); + sys_exit_group(EXIT_FAILURE); } return (char *)&new_sp->frame + sizeof(struct rt_hw_exp_stack); @@ -158,7 +158,7 @@ void *arch_signal_ucontext_save(rt_base_t user_sp, siginfo_t *psiginfo, else { LOG_I("%s: User stack overflow", __func__); - sys_exit(EXIT_FAILURE); + sys_exit_group(EXIT_FAILURE); } return new_sp; diff --git a/components/lwp/arch/arm/cortex-a/lwp_arch.c b/components/lwp/arch/arm/cortex-a/lwp_arch.c index 97fdf1b8b9..0c97d6831a 100644 --- a/components/lwp/arch/arm/cortex-a/lwp_arch.c +++ b/components/lwp/arch/arm/cortex-a/lwp_arch.c @@ -152,7 +152,7 @@ void *arch_signal_ucontext_restore(rt_base_t user_sp) else { LOG_I("User frame corrupted during signal handling\nexiting..."); - sys_exit(EXIT_FAILURE); + sys_exit_group(EXIT_FAILURE); } return (void *)&new_sp->frame; @@ -191,7 +191,7 @@ void *arch_signal_ucontext_save(rt_base_t lr, siginfo_t *psiginfo, else { LOG_I("%s: User stack overflow", __func__); - sys_exit(EXIT_FAILURE); + sys_exit_group(EXIT_FAILURE); } return new_sp; diff --git a/components/lwp/arch/risc-v/rv64/lwp_arch.c b/components/lwp/arch/risc-v/rv64/lwp_arch.c index 217839a95a..04d56a47e1 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_arch.c +++ b/components/lwp/arch/risc-v/rv64/lwp_arch.c @@ -272,7 +272,7 @@ void *arch_signal_ucontext_restore(rt_base_t user_sp) else { LOG_I("User frame corrupted during signal handling\nexiting..."); - sys_exit(EXIT_FAILURE); + sys_exit_group(EXIT_FAILURE); } return (void *)&new_sp->frame; @@ -314,7 +314,7 @@ void *arch_signal_ucontext_save(int signo, siginfo_t *psiginfo, else { LOG_I("%s: User stack overflow", __func__); - sys_exit(EXIT_FAILURE); + sys_exit_group(EXIT_FAILURE); } return new_sp; diff --git a/components/lwp/lwp_signal.c b/components/lwp/lwp_signal.c index 5ac08589e9..43a36ee2e8 100644 --- a/components/lwp/lwp_signal.c +++ b/components/lwp/lwp_signal.c @@ -538,7 +538,7 @@ void lwp_thread_signal_catch(void *exp_frame) if (handler == LWP_SIG_ACT_DFL) { LOG_D("%s: default handler; and exit", __func__); - sys_exit(0); + sys_exit_group(0); } /** diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index a8bab891f4..ad84dd2d9b 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -318,14 +318,14 @@ static void _crt_thread_entry(void *parameter) #endif /* ARCH_MM_MMU */ } -/* thread/process */ -void sys_exit(int value) +/* exit group */ +sysret_t sys_exit_group(int value) { rt_base_t level; rt_thread_t tid, main_thread; struct rt_lwp *lwp; - LOG_D("thread/process exit."); + LOG_D("process exit"); tid = rt_thread_self(); lwp = (struct rt_lwp *)tid->lwp; @@ -370,15 +370,51 @@ void sys_exit(int value) #endif /* ARCH_MM_MMU */ rt_thread_delete(tid); - rt_schedule(); rt_hw_interrupt_enable(level); + rt_schedule(); - return; + /* never reach here */ + return 0; } -/* exit group */ -void sys_exit_group(int status) +/* thread exit */ +void sys_exit(int status) { + rt_base_t level; + rt_thread_t tid, main_thread; + struct rt_lwp *lwp; + + LOG_D("thread exit"); + + tid = rt_thread_self(); + lwp = (struct rt_lwp *)tid->lwp; + + level = rt_hw_interrupt_disable(); + +#ifdef ARCH_MM_MMU + if (tid->clear_child_tid) + { + int t = 0; + int *clear_child_tid = tid->clear_child_tid; + + tid->clear_child_tid = RT_NULL; + lwp_put_to_user(clear_child_tid, &t, sizeof t); + sys_futex(clear_child_tid, FUTEX_WAKE, 1, RT_NULL, RT_NULL, 0); + } + + main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling); + if (main_thread == tid && tid->sibling.prev == &lwp->t_grp) + { + lwp_terminate(lwp); + lwp_wait_subthread_exit(); + lwp->lwp_ret = status; + } +#endif /* ARCH_MM_MMU */ + + rt_thread_delete(tid); + rt_hw_interrupt_enable(level); + rt_schedule(); + return; } @@ -1842,6 +1878,7 @@ sysret_t _sys_fork(void) thread->user_stack_size = self_thread->user_stack_size; thread->signal.sigset_mask = self_thread->signal.sigset_mask; thread->thread_idr = self_thread->thread_idr; + thread->clear_child_tid = self_thread->clear_child_tid; thread->lwp = (void *)lwp; thread->tid = tid; diff --git a/components/lwp/lwp_syscall.h b/components/lwp/lwp_syscall.h index d7b684c3ad..e3899736f8 100644 --- a/components/lwp/lwp_syscall.h +++ b/components/lwp/lwp_syscall.h @@ -45,6 +45,7 @@ const char *lwp_get_syscall_name(rt_uint32_t number); const void *lwp_get_sys_api(rt_uint32_t number); void sys_exit(int value); +sysret_t sys_exit_group(int status); ssize_t sys_read(int fd, void *buf, size_t nbyte); ssize_t sys_write(int fd, const void *buf, size_t nbyte); off_t sys_lseek(int fd, off_t offset, int whence); diff --git a/libcpu/aarch64/common/trap.c b/libcpu/aarch64/common/trap.c index 6faa740531..9af71d3001 100644 --- a/libcpu/aarch64/common/trap.c +++ b/libcpu/aarch64/common/trap.c @@ -34,7 +34,6 @@ extern long list_thread(void); #include #endif -void sys_exit(int value); void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info) { uint32_t mode = regs->cpsr; @@ -46,7 +45,7 @@ void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info) lwp_core_dump(regs, pc_adj); #endif backtrace((unsigned long)regs->pc, (unsigned long)regs->x30, (unsigned long)regs->x29); - sys_exit(-1); + sys_exit_group(-1); } } diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c index 02a6e5c316..800e145b64 100644 --- a/libcpu/arm/cortex-a/trap.c +++ b/libcpu/arm/cortex-a/trap.c @@ -28,7 +28,6 @@ extern long list_thread(void); #include #endif -void sys_exit(int value); void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info) { uint32_t mode = regs->cpsr; @@ -39,7 +38,7 @@ void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info) #ifdef LWP_USING_CORE_DUMP lwp_core_dump(regs, pc_adj); #endif - sys_exit(-1); + sys_exit_group(-1); } } diff --git a/libcpu/risc-v/t-head/c906/syscall_c.c b/libcpu/risc-v/t-head/c906/syscall_c.c index 8bda3e6278..2abe1d065b 100644 --- a/libcpu/risc-v/t-head/c906/syscall_c.c +++ b/libcpu/risc-v/t-head/c906/syscall_c.c @@ -45,7 +45,7 @@ void syscall_handler(struct rt_hw_stack_frame *regs) if (syscallfunc == RT_NULL) { LOG_E("unsupported syscall!\n"); - sys_exit(-1); + sys_exit_group(-1); } #if DBG_LVL >= DBG_INFO diff --git a/libcpu/risc-v/t-head/c906/trap.c b/libcpu/risc-v/t-head/c906/trap.c index 35d8255a97..b0470dc6e8 100644 --- a/libcpu/risc-v/t-head/c906/trap.c +++ b/libcpu/risc-v/t-head/c906/trap.c @@ -225,7 +225,7 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw LOG_E("User Fault, killing thread: %s", rt_thread_self()->parent.name); EXIT_TRAP; - sys_exit(-1); + sys_exit_group(-1); } #endif diff --git a/libcpu/risc-v/virt64/syscall_c.c b/libcpu/risc-v/virt64/syscall_c.c index 8bda3e6278..2abe1d065b 100644 --- a/libcpu/risc-v/virt64/syscall_c.c +++ b/libcpu/risc-v/virt64/syscall_c.c @@ -45,7 +45,7 @@ void syscall_handler(struct rt_hw_stack_frame *regs) if (syscallfunc == RT_NULL) { LOG_E("unsupported syscall!\n"); - sys_exit(-1); + sys_exit_group(-1); } #if DBG_LVL >= DBG_INFO diff --git a/libcpu/risc-v/virt64/trap.c b/libcpu/risc-v/virt64/trap.c index 3839c03110..51531d9ad0 100644 --- a/libcpu/risc-v/virt64/trap.c +++ b/libcpu/risc-v/virt64/trap.c @@ -222,7 +222,7 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw LOG_E("User Fault, killing thread: %s", rt_thread_self()->parent.name); EXIT_TRAP; - sys_exit(-1); + sys_exit_group(-1); } #endif