* @brief Terminates the calling thread and optionally returns a value. * * The `pthread_exit` function terminates the calling thread. It can optionally provide an exit status that can be * retrieved by other threads that join the calling thread using `pthread_join`. If the thread is detached, the * exit status is ignored and the system automatically reclaims resources once the thread terminate
| 945 | * @see pthread_join, pthread_create |
| 946 | */ |
| 947 | void pthread_exit(void *value) |
| 948 | { |
| 949 | _pthread_data_t *ptd; |
| 950 | _pthread_cleanup_t *cleanup; |
| 951 | rt_thread_t tid; |
| 952 | |
| 953 | if (rt_thread_self() == RT_NULL) |
| 954 | { |
| 955 | return; |
| 956 | } |
| 957 | |
| 958 | /* get pthread data from pthread_data of thread */ |
| 959 | ptd = (_pthread_data_t *)rt_thread_self()->pthread_data; |
| 960 | |
| 961 | rt_enter_critical(); |
| 962 | /* disable cancel */ |
| 963 | ptd->cancelstate = PTHREAD_CANCEL_DISABLE; |
| 964 | /* set return value */ |
| 965 | ptd->return_value = value; |
| 966 | rt_exit_critical(); |
| 967 | |
| 968 | /* |
| 969 | * When use pthread_exit to exit. |
| 970 | * invoke pushed cleanup |
| 971 | */ |
| 972 | while (ptd->cleanup != RT_NULL) |
| 973 | { |
| 974 | cleanup = ptd->cleanup; |
| 975 | ptd->cleanup = cleanup->next; |
| 976 | |
| 977 | cleanup->cleanup_func(cleanup->parameter); |
| 978 | /* release this cleanup function */ |
| 979 | rt_free(cleanup); |
| 980 | } |
| 981 | |
| 982 | /* get the info aboult "tid" early */ |
| 983 | tid = ptd->tid; |
| 984 | |
| 985 | /* According to "detachstate" to whether or not to recycle resource immediately */ |
| 986 | if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE) |
| 987 | { |
| 988 | /* set value */ |
| 989 | rt_sem_release(ptd->joinable_sem); |
| 990 | } |
| 991 | else |
| 992 | { |
| 993 | /* release pthread resource */ |
| 994 | _pthread_data_destroy(ptd); |
| 995 | } |
| 996 | |
| 997 | /* |
| 998 | * second: detach thread. |
| 999 | * this thread will be removed from scheduler list |
| 1000 | * and because there is a cleanup function in the |
| 1001 | * thread (pthread_cleanup), it will move to defunct |
| 1002 | * thread list and wait for handling in idle thread. |
| 1003 | */ |
| 1004 | rt_thread_detach(tid); |