From 309dda3ef8954ceaaad43dd1ce1ee3a6d3c599b5 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Thu, 4 Jun 2020 02:11:04 +0800 Subject: [PATCH] sched: pthread_cleanup_[push|pop] should be callable from main thread Signed-off-by: Xiang Xiao Change-Id: Ifefccda6cb7e2335e11976dcec74e308d64c7f5e --- include/nuttx/sched.h | 22 +++++++++++----------- sched/pthread/pthread.h | 2 +- sched/pthread/pthread_cancel.c | 2 +- sched/pthread/pthread_cleanup.c | 32 +++++++++++--------------------- sched/pthread/pthread_exit.c | 5 +++-- sched/task/exit.c | 7 +++++++ 6 files changed, 34 insertions(+), 36 deletions(-) diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 8650a6d85f..0bc3d1efa1 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -714,6 +714,17 @@ struct tcb_s FAR struct mqueue_inode_s *msgwaitq; /* Waiting for this message queue */ #endif + /* Clean-up stack *************************************************************/ + +#ifdef CONFIG_PTHREAD_CLEANUP + /* tos - The index to the next available entry at the top of the stack. + * stack - The pre-allocated clean-up stack memory. + */ + + uint8_t tos; + struct pthread_cleanup_s stack[CONFIG_PTHREAD_CLEANUP_STACKSIZE]; +#endif + /* Pre-emption monitor support ************************************************/ #ifdef CONFIG_SCHED_CRITMONITOR @@ -791,17 +802,6 @@ struct pthread_tcb_s #ifndef CONFIG_PTHREAD_MUTEX_UNSAFE FAR struct pthread_mutex_s *mhead; /* List of mutexes held by thread */ #endif - - /* Clean-up stack *************************************************************/ - -#ifdef CONFIG_PTHREAD_CLEANUP - /* tos - The index to the next available entry at the top of the stack. - * stack - The pre-allocated clean-up stack memory. - */ - - uint8_t tos; - struct pthread_cleanup_s stack[CONFIG_PTHREAD_CLEANUP_STACKSIZE]; -#endif }; #endif /* !CONFIG_DISABLE_PTHREAD */ diff --git a/sched/pthread/pthread.h b/sched/pthread/pthread.h index 3a157142f2..82c9bd8a61 100644 --- a/sched/pthread/pthread.h +++ b/sched/pthread/pthread.h @@ -99,7 +99,7 @@ int pthread_setup_scheduler(FAR struct pthread_tcb_s *tcb, int priority, start_t start, pthread_startroutine_t entry); #ifdef CONFIG_PTHREAD_CLEANUP -void pthread_cleanup_popall(FAR struct pthread_tcb_s *tcb); +void pthread_cleanup_popall(FAR struct tcb_s *tcb); #endif int pthread_completejoin(pid_t pid, FAR void *exit_value); diff --git a/sched/pthread/pthread_cancel.c b/sched/pthread/pthread_cancel.c index b2e947d170..ab64a4e77e 100644 --- a/sched/pthread/pthread_cancel.c +++ b/sched/pthread/pthread_cancel.c @@ -141,7 +141,7 @@ int pthread_cancel(pthread_t thread) * function will be unable to unlock its own mutexes. */ - pthread_cleanup_popall(tcb); + pthread_cleanup_popall((FAR struct tcb_s *)tcb); #endif /* Complete pending join operations */ diff --git a/sched/pthread/pthread_cleanup.c b/sched/pthread/pthread_cleanup.c index cbfc2558be..c22e67c1a3 100644 --- a/sched/pthread/pthread_cleanup.c +++ b/sched/pthread/pthread_cleanup.c @@ -57,8 +57,8 @@ * Name: pthread_cleanup_pop_tcb * * Description: - * The pthread_cleanup_pop_tcb() function will remove the routine at the top - * of the calling thread's cancellation cleanup stack and optionally + * The pthread_cleanup_pop_tcb() function will remove the routine at the + * top of the calling thread's cancellation cleanup stack and optionally * invoke it (if 'execute' is non-zero). * * Input Parameters: @@ -72,7 +72,7 @@ * ****************************************************************************/ -static void pthread_cleanup_pop_tcb(FAR struct pthread_tcb_s *tcb, int execute) +static void pthread_cleanup_pop_tcb(FAR struct tcb_s *tcb, int execute) { if (tcb->tos > 0) { @@ -124,7 +124,7 @@ static void pthread_cleanup_pop_tcb(FAR struct pthread_tcb_s *tcb, int execute) * * - The thread exits (that is, calls pthread_exit()). * - The thread acts upon a cancellation request. - * - The thread calls pthread_cleanup_pop() with a non-zero execute argument. + * - The thread calls pthread_cleanup_pop() with non-zero execute argument. * * Input Parameters: * routine - The cleanup routine to be pushed on the cleanup stack. @@ -138,9 +138,7 @@ static void pthread_cleanup_pop_tcb(FAR struct pthread_tcb_s *tcb, int execute) void pthread_cleanup_pop(int execute) { - FAR struct pthread_tcb_s *tcb = (FAR struct pthread_tcb_s *)this_task(); - - /* We don't assert if called from a non-pthread; we just don't do anything */ + FAR struct tcb_s *tcb = this_task(); DEBUGASSERT(tcb != NULL); @@ -150,19 +148,13 @@ void pthread_cleanup_pop(int execute) */ sched_lock(); - if ((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) - { - pthread_cleanup_pop_tcb(tcb, execute); - } - + pthread_cleanup_pop_tcb(tcb, execute); sched_unlock(); } void pthread_cleanup_push(pthread_cleanup_t routine, FAR void *arg) { - FAR struct pthread_tcb_s *tcb = (FAR struct pthread_tcb_s *)this_task(); - - /* We don't assert if called from a non-pthread; we just don't do anything */ + FAR struct tcb_s *tcb = this_task(); DEBUGASSERT(tcb != NULL); DEBUGASSERT(tcb->tos < CONFIG_PTHREAD_CLEANUP_STACKSIZE); @@ -173,8 +165,7 @@ void pthread_cleanup_push(pthread_cleanup_t routine, FAR void *arg) */ sched_lock(); - if ((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD && - tcb->tos < CONFIG_PTHREAD_CLEANUP_STACKSIZE) + if (tcb->tos < CONFIG_PTHREAD_CLEANUP_STACKSIZE) { unsigned int ndx = tcb->tos; @@ -191,8 +182,8 @@ void pthread_cleanup_push(pthread_cleanup_t routine, FAR void *arg) * * Description: * The pthread_cleanup_popall() is an internal function that will pop and - * execute all clean-up functions. This function is only called from within - * the pthread_exit() and pthread_cancellation() logic + * execute all clean-up functions. This function is only called from + * within the pthread_exit() and pthread_cancellation() logic * * Input Parameters: * tcb - The TCB of the pthread that is exiting or being canceled. @@ -202,10 +193,9 @@ void pthread_cleanup_push(pthread_cleanup_t routine, FAR void *arg) * ****************************************************************************/ -void pthread_cleanup_popall(FAR struct pthread_tcb_s *tcb) +void pthread_cleanup_popall(FAR struct tcb_s *tcb) { DEBUGASSERT(tcb != NULL); - DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD); /* Pop and execute each cleanup routine/ * diff --git a/sched/pthread/pthread_exit.c b/sched/pthread/pthread_exit.c index 87f4052d88..740bec88ad 100644 --- a/sched/pthread/pthread_exit.c +++ b/sched/pthread/pthread_exit.c @@ -1,7 +1,8 @@ /**************************************************************************** * sched/pthread/pthread_exit.c * - * Copyright (C) 2007, 2009, 2011-2013, 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011-2013, 2017 Gregory Nutt. + * All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -105,7 +106,7 @@ void pthread_exit(FAR void *exit_value) #ifdef CONFIG_PTHREAD_CLEANUP /* Perform any stack pthread clean-up callbacks */ - pthread_cleanup_popall((FAR struct pthread_tcb_s *)tcb); + pthread_cleanup_popall(tcb); #endif /* Complete pending join operations */ diff --git a/sched/task/exit.c b/sched/task/exit.c index 3d9f5ecf5e..5bb9b1c4a0 100644 --- a/sched/task/exit.c +++ b/sched/task/exit.c @@ -34,6 +34,7 @@ #include "task/task.h" #include "group/group.h" #include "sched/sched.h" +#include "pthread/pthread.h" /**************************************************************************** * Public Functions @@ -86,6 +87,12 @@ void exit(int status) group_kill_children(tcb); #endif +#ifdef CONFIG_PTHREAD_CLEANUP + /* Perform any stack pthread clean-up callbacks */ + + pthread_cleanup_popall(tcb); +#endif + /* Perform common task termination logic. This will get called again later * through logic kicked off by _exit(). However, we need to call it before * calling _exit() in order to handle atexit() and on_exit() callbacks and