[PATCH 03/13] score: Change thread action locking

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Feb 17 19:30:18 UTC 2021


Require that the corresponding lock is acquired before the action
handler returns.  This helps to avoid recursion in the signal
processing.

Update #4244.
---
 cpukit/include/rtems/score/thread.h     | 19 +++++++++++--------
 cpukit/posix/src/psignalunblockthread.c |  2 ++
 cpukit/rtems/src/signalcatch.c          |  6 ++++--
 cpukit/score/src/threaddispatch.c       |  3 ---
 4 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h
index 0920a44177..e23261701a 100644
--- a/cpukit/include/rtems/score/thread.h
+++ b/cpukit/include/rtems/score/thread.h
@@ -594,20 +594,23 @@ typedef enum {
 typedef struct Thread_Action Thread_Action;
 
 /**
- * @brief Thread action handler.
+ * @brief This type defines the prototype of thread action handlers.
  *
  * The thread action handler will be called with interrupts disabled and a
- * corresponding lock acquired, e.g. _Thread_State_acquire().  The handler must
- * release the corresponding lock, e.g. _Thread_State_release().  So, the
- * corresponding lock may be used to protect private data used by the
- * particular action.
+ * corresponding lock acquired, e.g. _Thread_State_acquire().  The handler may
+ * release the corresponding lock, e.g. _Thread_State_release().  If the lock
+ * is released, it shall be acquired before the handler returns using the lock
+ * context.  The lock may be used to protect private data used by the action.
  *
  * Since the action is passed to the handler additional data may be accessed
  * via RTEMS_CONTAINER_OF().
  *
- * @param[in] the_thread The thread performing the action.
- * @param[in] action The thread action.
- * @param[in] lock_context The lock context to use for the lock release.
+ * @param[in, out] the_thread is the thread performing the action.
+ *
+ * @param[in, out] action is the thread action.
+ *
+ * @param[in, out] lock_context is the lock context to use for the optional
+ *   lock release and acquire.
  */
 typedef void ( *Thread_Action_handler )(
   Thread_Control   *the_thread,
diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c
index 80a0f33a09..63ed823ab3 100644
--- a/cpukit/posix/src/psignalunblockthread.c
+++ b/cpukit/posix/src/psignalunblockthread.c
@@ -159,6 +159,8 @@ static void _POSIX_signals_Action_handler(
   }
 
   executing->Wait.return_code = hold_errno;
+
+  _Thread_State_acquire( executing, lock_context );
 }
 
 static bool _POSIX_signals_Unblock_thread_done(
diff --git a/cpukit/rtems/src/signalcatch.c b/cpukit/rtems/src/signalcatch.c
index c59e132ad3..2fd7c13374 100644
--- a/cpukit/rtems/src/signalcatch.c
+++ b/cpukit/rtems/src/signalcatch.c
@@ -51,12 +51,12 @@ void _Signal_Action_handler(
   asr = &api->Signal;
   signal_set = _ASR_Get_posted_signals( asr );
 
-  _Thread_State_release( executing, lock_context );
-
   if ( signal_set == 0 ) {
     return;
   }
 
+  _Thread_State_release( executing, lock_context );
+
   asr->nest_level += 1;
   rtems_task_mode( asr->mode_set, RTEMS_ALL_MODE_MASKS, &prev_mode );
 
@@ -64,6 +64,8 @@ void _Signal_Action_handler(
 
   asr->nest_level -= 1;
   rtems_task_mode( prev_mode, RTEMS_ALL_MODE_MASKS, &prev_mode );
+
+  _Thread_State_acquire( executing, lock_context );
 }
 
 rtems_status_code rtems_signal_catch(
diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c
index c4dadc0ff1..bae2902bda 100644
--- a/cpukit/score/src/threaddispatch.c
+++ b/cpukit/score/src/threaddispatch.c
@@ -249,10 +249,7 @@ static void _Thread_Run_post_switch_actions( Thread_Control *executing )
 
   while ( action != NULL ) {
     _Chain_Set_off_chain( &action->Node );
-
     ( *action->handler )( executing, action, &lock_context );
-
-    _Thread_State_acquire( executing, &lock_context );
     action = _Thread_Get_post_switch_action( executing );
   }
 
-- 
2.26.2



More information about the devel mailing list