libc: Move pthread_exit to userspace
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
parent
bb9b58bdde
commit
54eef9f639
@ -149,6 +149,41 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
|
|||||||
FAR const pthread_attr_t *attr,
|
FAR const pthread_attr_t *attr,
|
||||||
pthread_startroutine_t entry, pthread_addr_t arg);
|
pthread_startroutine_t entry, pthread_addr_t arg);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nx_pthread_exit
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Terminate execution of a thread started with pthread_create.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* exit_valie
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void nx_pthread_exit(FAR void *exit_value) noreturn_function;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pthread_cleanup_poplist
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The pthread_cleanup_poplist() is function that will pop all clean-up
|
||||||
|
* functions. This function is only called from within the pthread_exit()
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cleanup - The array of struct pthread_cleanup_s to fetch callbacks
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The index to the next available entry at the top of the stack
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pthread_cleanup_poplist(FAR struct pthread_cleanup_s *cleanup);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ SYSCALL_LOOKUP(telldir, 1)
|
|||||||
SYSCALL_LOOKUP(pthread_cond_wait, 2)
|
SYSCALL_LOOKUP(pthread_cond_wait, 2)
|
||||||
SYSCALL_LOOKUP(nx_pthread_create, 5)
|
SYSCALL_LOOKUP(nx_pthread_create, 5)
|
||||||
SYSCALL_LOOKUP(pthread_detach, 1)
|
SYSCALL_LOOKUP(pthread_detach, 1)
|
||||||
SYSCALL_LOOKUP(pthread_exit, 1)
|
SYSCALL_LOOKUP(nx_pthread_exit, 1)
|
||||||
SYSCALL_LOOKUP(pthread_getschedparam, 3)
|
SYSCALL_LOOKUP(pthread_getschedparam, 3)
|
||||||
SYSCALL_LOOKUP(pthread_join, 2)
|
SYSCALL_LOOKUP(pthread_join, 2)
|
||||||
SYSCALL_LOOKUP(pthread_mutex_destroy, 1)
|
SYSCALL_LOOKUP(pthread_mutex_destroy, 1)
|
||||||
@ -330,6 +330,7 @@ SYSCALL_LOOKUP(telldir, 1)
|
|||||||
#ifdef CONFIG_PTHREAD_CLEANUP
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
SYSCALL_LOOKUP(pthread_cleanup_push, 2)
|
SYSCALL_LOOKUP(pthread_cleanup_push, 2)
|
||||||
SYSCALL_LOOKUP(pthread_cleanup_pop, 1)
|
SYSCALL_LOOKUP(pthread_cleanup_pop, 1)
|
||||||
|
SYSCALL_LOOKUP(pthread_cleanup_poplist, 1)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ CSRCS += pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwait.c
|
|||||||
CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c
|
CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c
|
||||||
CSRCS += pthread_condattr_setclock.c pthread_condattr_getclock.c
|
CSRCS += pthread_condattr_setclock.c pthread_condattr_getclock.c
|
||||||
CSRCS += pthread_condinit.c pthread_conddestroy.c pthread_condtimedwait.c
|
CSRCS += pthread_condinit.c pthread_conddestroy.c pthread_condtimedwait.c
|
||||||
CSRCS += pthread_create.c
|
CSRCS += pthread_create.c pthread_exit.c
|
||||||
CSRCS += pthread_get_stackaddr_np.c pthread_get_stacksize_np.c
|
CSRCS += pthread_get_stackaddr_np.c pthread_get_stacksize_np.c
|
||||||
CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c
|
CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c
|
||||||
CSRCS += pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c
|
CSRCS += pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c
|
||||||
|
72
libs/libc/pthread/pthread_exit.c
Normal file
72
libs/libc/pthread/pthread_exit.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* libs/libc/pthread/pthread_exit.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 <debug.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pthread_exit
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Terminate execution of a thread started with pthread_create.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* exit_valie
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void pthread_exit(FAR void *exit_value)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
|
int cnt;
|
||||||
|
struct pthread_cleanup_s cleanup[CONFIG_PTHREAD_CLEANUP_STACKSIZE];
|
||||||
|
cnt = pthread_cleanup_poplist(cleanup);
|
||||||
|
|
||||||
|
sched_lock();
|
||||||
|
while (cnt-- > 0)
|
||||||
|
{
|
||||||
|
struct pthread_cleanup_s cp = cleanup[cnt];
|
||||||
|
if (cp.pc_cleaner)
|
||||||
|
cp.pc_cleaner(cp.pc_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
sched_unlock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nx_pthread_exit(exit_value);
|
||||||
|
PANIC();
|
||||||
|
}
|
@ -208,4 +208,57 @@ void pthread_cleanup_popall(FAR struct tcb_s *tcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: pthread_cleanup_poplist
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The pthread_cleanup_poplist() is function that will pop all clean-up
|
||||||
|
* functions. This function is only called from within the pthread_exit()
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* cleanup - The array of struct pthread_cleanup_s to fetch callbacks
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The index to the next available entry at the top of the stack
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int pthread_cleanup_poplist(FAR struct pthread_cleanup_s *cleanup)
|
||||||
|
{
|
||||||
|
uint8_t tos = 0;
|
||||||
|
uint8_t ndx = 0;
|
||||||
|
FAR struct tcb_s *tcb = this_task();
|
||||||
|
|
||||||
|
DEBUGASSERT(cleanup != NULL);
|
||||||
|
DEBUGASSERT(tcb != NULL);
|
||||||
|
DEBUGASSERT(tcb->tos < CONFIG_PTHREAD_CLEANUP_STACKSIZE);
|
||||||
|
|
||||||
|
tos = tcb->tos;
|
||||||
|
|
||||||
|
/* Kernel threads do not support pthread APIs */
|
||||||
|
|
||||||
|
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
|
||||||
|
{
|
||||||
|
/* Pop cleanup routine list
|
||||||
|
*
|
||||||
|
* sched_lock() should provide sufficient protection. We only need to
|
||||||
|
* have this TCB stationary; the pthread cleanup stack should never be
|
||||||
|
* modified by interrupt level logic.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sched_lock();
|
||||||
|
while (tcb->tos > 0)
|
||||||
|
{
|
||||||
|
ndx = tcb->tos - 1;
|
||||||
|
DEBUGASSERT(ndx >= 0 && ndx < CONFIG_PTHREAD_CLEANUP_STACKSIZE);
|
||||||
|
cleanup[ndx] = tcb->stack[ndx];
|
||||||
|
tcb->tos = ndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
sched_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tos;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PTHREAD_CLEANUP */
|
#endif /* CONFIG_PTHREAD_CLEANUP */
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void pthread_exit(FAR void *exit_value)
|
void nx_pthread_exit(FAR void *exit_value)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *tcb = this_task();
|
FAR struct tcb_s *tcb = this_task();
|
||||||
sigset_t set = ALL_SIGNAL_SET;
|
sigset_t set = ALL_SIGNAL_SET;
|
||||||
@ -87,12 +87,6 @@ void pthread_exit(FAR void *exit_value)
|
|||||||
tcb->cpcount = 0;
|
tcb->cpcount = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PTHREAD_CLEANUP
|
|
||||||
/* Perform any stack pthread clean-up callbacks */
|
|
||||||
|
|
||||||
pthread_cleanup_popall(tcb);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Complete pending join operations */
|
/* Complete pending join operations */
|
||||||
|
|
||||||
status = pthread_completejoin(getpid(), exit_value);
|
status = pthread_completejoin(getpid(), exit_value);
|
||||||
|
@ -84,13 +84,14 @@
|
|||||||
"pselect","sys/select.h","","int","int","FAR fd_set *","FAR fd_set *","FAR fd_set *","FAR const struct timespec *","FAR const sigset_t *"
|
"pselect","sys/select.h","","int","int","FAR fd_set *","FAR fd_set *","FAR fd_set *","FAR const struct timespec *","FAR const sigset_t *"
|
||||||
"pthread_cancel","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t"
|
"pthread_cancel","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t"
|
||||||
"pthread_cleanup_pop","pthread.h","defined(CONFIG_PTHREAD_CLEANUP)","void","int"
|
"pthread_cleanup_pop","pthread.h","defined(CONFIG_PTHREAD_CLEANUP)","void","int"
|
||||||
|
"pthread_cleanup_poplist","nuttx/pthread.h","defined(CONFIG_PTHREAD_CLEANUP)","int","struct pthread_cleanup_s *"
|
||||||
"pthread_cleanup_push","pthread.h","defined(CONFIG_PTHREAD_CLEANUP)","void","pthread_cleanup_t","FAR void *"
|
"pthread_cleanup_push","pthread.h","defined(CONFIG_PTHREAD_CLEANUP)","void","pthread_cleanup_t","FAR void *"
|
||||||
"pthread_cond_broadcast","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *"
|
"pthread_cond_broadcast","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *"
|
||||||
"pthread_cond_clockwait","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *","FAR pthread_mutex_t *","clockid_t","FAR const struct timespec *"
|
"pthread_cond_clockwait","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *","FAR pthread_mutex_t *","clockid_t","FAR const struct timespec *"
|
||||||
"pthread_cond_signal","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *"
|
"pthread_cond_signal","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *"
|
||||||
"pthread_cond_wait","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *","FAR pthread_mutex_t *"
|
"pthread_cond_wait","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *","FAR pthread_mutex_t *"
|
||||||
"pthread_detach","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t"
|
"pthread_detach","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t"
|
||||||
"pthread_exit","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","noreturn","pthread_addr_t"
|
"nx_pthread_exit","nuttx/pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","noreturn","pthread_addr_t"
|
||||||
"pthread_getaffinity_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_SMP)","int","pthread_t","size_t","FAR cpu_set_t*"
|
"pthread_getaffinity_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_SMP)","int","pthread_t","size_t","FAR cpu_set_t*"
|
||||||
"pthread_getschedparam","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","FAR int *","FAR struct sched_param *"
|
"pthread_getschedparam","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","FAR int *","FAR struct sched_param *"
|
||||||
"pthread_join","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","FAR pthread_addr_t *"
|
"pthread_join","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t","FAR pthread_addr_t *"
|
||||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
Loading…
Reference in New Issue
Block a user