Explorar o código

[smart/syscall] fix exit(2) and add exit_group(2) (#8005)

Signed-off-by: shell <smokewood@qq.com>
Signed-off-by: shell <wangxiaoyao@rt-thread.com>
Signed-off-by: Shell <smokewood@qq.com>
Shell hai 1 ano
pai
achega
47b183a297

+ 2 - 2
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;

+ 2 - 2
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;

+ 2 - 2
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;

+ 1 - 1
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);
         }
 
         /**

+ 44 - 7
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;
 

+ 1 - 0
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);

+ 1 - 2
libcpu/aarch64/common/trap.c

@@ -34,7 +34,6 @@ extern long list_thread(void);
 #include <lwp_core_dump.h>
 #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);
     }
 }
 

+ 1 - 2
libcpu/arm/cortex-a/trap.c

@@ -28,7 +28,6 @@ extern long list_thread(void);
 #include <lwp_core_dump.h>
 #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);
     }
 }
 

+ 1 - 1
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

+ 1 - 1
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
 

+ 1 - 1
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

+ 1 - 1
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