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,
|
||||
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
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ SYSCALL_LOOKUP(telldir, 1)
|
||||
SYSCALL_LOOKUP(pthread_cond_wait, 2)
|
||||
SYSCALL_LOOKUP(nx_pthread_create, 5)
|
||||
SYSCALL_LOOKUP(pthread_detach, 1)
|
||||
SYSCALL_LOOKUP(pthread_exit, 1)
|
||||
SYSCALL_LOOKUP(nx_pthread_exit, 1)
|
||||
SYSCALL_LOOKUP(pthread_getschedparam, 3)
|
||||
SYSCALL_LOOKUP(pthread_join, 2)
|
||||
SYSCALL_LOOKUP(pthread_mutex_destroy, 1)
|
||||
@ -330,6 +330,7 @@ SYSCALL_LOOKUP(telldir, 1)
|
||||
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||
SYSCALL_LOOKUP(pthread_cleanup_push, 2)
|
||||
SYSCALL_LOOKUP(pthread_cleanup_pop, 1)
|
||||
SYSCALL_LOOKUP(pthread_cleanup_poplist, 1)
|
||||
#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_setclock.c pthread_condattr_getclock.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_mutexattr_init.c pthread_mutexattr_destroy.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 */
|
||||
|
@ -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();
|
||||
sigset_t set = ALL_SIGNAL_SET;
|
||||
@ -87,12 +87,6 @@ void pthread_exit(FAR void *exit_value)
|
||||
tcb->cpcount = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||
/* Perform any stack pthread clean-up callbacks */
|
||||
|
||||
pthread_cleanup_popall(tcb);
|
||||
#endif
|
||||
|
||||
/* Complete pending join operations */
|
||||
|
||||
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 *"
|
||||
"pthread_cancel","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t"
|
||||
"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_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_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_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_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 *"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
Loading…
Reference in New Issue
Block a user