* @brief Terminates a lightweight process and cleans up its resources * * @param[in,out] lwp The lightweight process to terminate * @param[in] status The exit status to set for the process * * @note This function handles both MMU and non-MMU architectures differently. * For MMU architectures, it clears child TID, sets exit status, and terminates. * For non-MMU, it terminates the
| 853 | * For non-MMU, it terminates the main thread and all subthreads. |
| 854 | */ |
| 855 | void lwp_exit(rt_lwp_t lwp, lwp_status_t status) |
| 856 | { |
| 857 | rt_thread_t thread; |
| 858 | |
| 859 | if (!lwp) |
| 860 | { |
| 861 | LOG_W("%s: lwp should not be null", __func__); |
| 862 | return ; |
| 863 | } |
| 864 | |
| 865 | thread = rt_thread_self(); |
| 866 | RT_ASSERT((struct rt_lwp *)thread->lwp == lwp); |
| 867 | LOG_D("process(lwp.pid=%d) exit", lwp->pid); |
| 868 | |
| 869 | #ifdef ARCH_MM_MMU |
| 870 | _clear_child_tid(thread); |
| 871 | |
| 872 | LWP_LOCK(lwp); |
| 873 | /** |
| 874 | * Brief: only one thread should calls exit_group(), |
| 875 | * but we can not ensured that during run-time |
| 876 | */ |
| 877 | lwp->lwp_status = status; |
| 878 | LWP_UNLOCK(lwp); |
| 879 | |
| 880 | lwp_terminate(lwp); |
| 881 | #else |
| 882 | main_thread = rt_list_entry(lwp->t_grp.prev, struct rt_thread, sibling); |
| 883 | if (main_thread == tid) |
| 884 | { |
| 885 | rt_thread_t sub_thread; |
| 886 | rt_list_t *list; |
| 887 | |
| 888 | lwp_terminate(lwp); |
| 889 | |
| 890 | /* delete all subthread */ |
| 891 | while ((list = tid->sibling.prev) != &lwp->t_grp) |
| 892 | { |
| 893 | sub_thread = rt_list_entry(list, struct rt_thread, sibling); |
| 894 | rt_list_remove(&sub_thread->sibling); |
| 895 | rt_thread_delete(sub_thread); |
| 896 | } |
| 897 | lwp->lwp_ret = value; |
| 898 | } |
| 899 | #endif /* ARCH_MM_MMU */ |
| 900 | |
| 901 | _thread_exit(lwp, thread); |
| 902 | } |
| 903 | |
| 904 | /** |
| 905 | * @brief Handles thread exit for a lightweight process |
no test coverage detected