[PATCH 2/3] score: Simplify calling _Thread_Exit()

Sebastian Huber sebastian.huber at embedded-brains.de
Mon May 17 13:06:54 UTC 2021


Move common code into _Thread_Exit().  This enables a tail call
optimization in most cases.
---
 cpukit/include/rtems/score/threadimpl.h | 13 ++++++-------
 cpukit/posix/src/cancel.c               | 12 ++++++------
 cpukit/posix/src/pthreadexit.c          | 11 +----------
 cpukit/rtems/src/taskdelete.c           | 12 +-----------
 cpukit/rtems/src/taskexit.c             | 15 +--------------
 cpukit/score/src/threadrestart.c        | 15 +++++++++++----
 6 files changed, 26 insertions(+), 52 deletions(-)

diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h
index 1a5e391677..ecc8eee058 100644
--- a/cpukit/include/rtems/score/threadimpl.h
+++ b/cpukit/include/rtems/score/threadimpl.h
@@ -339,14 +339,13 @@ void _Thread_Kill_zombies( void );
 /**
  * @brief Exits the currently executing thread.
  *
- * @param[in, out] executing The currently executing thread.
- * @param life_states_to_set The states to set.
- * @param[out] exit_value Contains the exit value of the thread.
+ * @param exit_value is the exit value of the thread.
+ *
+ * @param life_states_to_set are the thread life states to set.
  */
-void _Thread_Exit(
-  Thread_Control    *executing,
-  Thread_Life_state  life_states_to_set,
-  void              *exit_value
+RTEMS_NO_RETURN void _Thread_Exit(
+  void              *exit_value,
+  Thread_Life_state  life_states_to_set
 );
 
 /**
diff --git a/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c
index 4756f10389..f2636e6a97 100644
--- a/cpukit/posix/src/cancel.c
+++ b/cpukit/posix/src/cancel.c
@@ -52,17 +52,17 @@ int pthread_cancel( pthread_t thread )
     return ESRCH;
   }
 
-  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
-  _ISR_lock_ISR_enable( &lock_context );
-
+  cpu_self = _Per_CPU_Get();
   executing = _Per_CPU_Get_executing( cpu_self );
 
   if ( the_thread == executing ) {
-    _Thread_Exit( executing, THREAD_LIFE_TERMINATING, PTHREAD_CANCELED );
+    _ISR_lock_ISR_enable( &lock_context );
+    _Thread_Exit( PTHREAD_CANCELED, THREAD_LIFE_TERMINATING );
   } else {
+    _Thread_Dispatch_disable_with_CPU( cpu_self, &lock_context );
+    _ISR_lock_ISR_enable( &lock_context );
     _Thread_Cancel( the_thread, executing, PTHREAD_CANCELED );
+    _Thread_Dispatch_enable( cpu_self );
   }
-
-  _Thread_Dispatch_enable( cpu_self );
   return 0;
 }
diff --git a/cpukit/posix/src/pthreadexit.c b/cpukit/posix/src/pthreadexit.c
index 657497010b..d5b53bb45f 100644
--- a/cpukit/posix/src/pthreadexit.c
+++ b/cpukit/posix/src/pthreadexit.c
@@ -27,14 +27,5 @@
 
 void pthread_exit( void *value_ptr )
 {
-  Thread_Control  *executing;
-  Per_CPU_Control *cpu_self;
-
-  cpu_self = _Thread_Dispatch_disable();
-  executing = _Per_CPU_Get_executing( cpu_self );
-
-  _Thread_Exit( executing, THREAD_LIFE_TERMINATING, value_ptr );
-
-  _Thread_Dispatch_direct_no_return( cpu_self );
-  RTEMS_UNREACHABLE();
+  _Thread_Exit( value_ptr, THREAD_LIFE_TERMINATING );
 }
diff --git a/cpukit/rtems/src/taskdelete.c b/cpukit/rtems/src/taskdelete.c
index 0a8d59a3a8..05321934ff 100644
--- a/cpukit/rtems/src/taskdelete.c
+++ b/cpukit/rtems/src/taskdelete.c
@@ -55,23 +55,13 @@ rtems_status_code rtems_task_delete(
   executing = _Per_CPU_Get_executing( cpu_self );
 
   if ( the_thread == executing ) {
-    _Thread_Dispatch_disable_with_CPU(
-      cpu_self,
-      &context.Base.Lock_context.Lock_context
-    );
     _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context );
 
     /*
      * The Classic tasks are neither detached nor joinable.  In case of
      * self deletion, they are detached, otherwise joinable by default.
      */
-    _Thread_Exit(
-      executing,
-      THREAD_LIFE_TERMINATING | THREAD_LIFE_DETACHED,
-      NULL
-    );
-    _Thread_Dispatch_direct_no_return( cpu_self );
-    RTEMS_UNREACHABLE();
+    _Thread_Exit( NULL, THREAD_LIFE_TERMINATING | THREAD_LIFE_DETACHED );
   } else {
     _Thread_Close( the_thread, executing, &context );
   }
diff --git a/cpukit/rtems/src/taskexit.c b/cpukit/rtems/src/taskexit.c
index 4c8420d255..178e668581 100644
--- a/cpukit/rtems/src/taskexit.c
+++ b/cpukit/rtems/src/taskexit.c
@@ -30,18 +30,5 @@
 
 void rtems_task_exit( void )
 {
-  Thread_Control  *executing;
-  Per_CPU_Control *cpu_self;
-
-  cpu_self = _Thread_Dispatch_disable();
-  executing = _Per_CPU_Get_executing( cpu_self );
-
-  _Thread_Exit(
-    executing,
-    THREAD_LIFE_TERMINATING | THREAD_LIFE_DETACHED,
-    NULL
-  );
-
-  _Thread_Dispatch_direct_no_return( cpu_self );
-  RTEMS_UNREACHABLE();
+  _Thread_Exit( NULL, THREAD_LIFE_TERMINATING | THREAD_LIFE_DETACHED );
 }
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index c8f7f7b6b1..933faee61b 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -489,14 +489,18 @@ void _Thread_Close(
   );
 }
 
-void _Thread_Exit(
-  Thread_Control    *executing,
-  Thread_Life_state  life_states_to_set,
-  void              *exit_value
+RTEMS_NO_RETURN void _Thread_Exit(
+  void              *exit_value,
+  Thread_Life_state  life_states_to_set
 )
 {
+  Per_CPU_Control *cpu_self;
+  Thread_Control  *executing;
   ISR_lock_Context lock_context;
 
+  cpu_self = _Thread_Dispatch_disable();
+  executing = _Per_CPU_Get_executing( cpu_self );
+
   _Assert(
     _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE
   );
@@ -514,6 +518,9 @@ void _Thread_Exit(
     THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED
   );
   _Thread_State_release( executing, &lock_context );
+
+  _Thread_Dispatch_direct_no_return( cpu_self );
+  RTEMS_UNREACHABLE();
 }
 
 Status_Control _Thread_Restart(
-- 
2.26.2



More information about the devel mailing list