[PATCH 10/21] score: Move thread stack allocation

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Dec 16 14:28:15 UTC 2019


Move thread stack allocation to caller side of _Thread_Initialize().

Update #3835.
---
 cpukit/include/rtems/score/thread.h     |  2 --
 cpukit/include/rtems/score/threadimpl.h |  9 ++++--
 cpukit/posix/src/pthreadcreate.c        | 20 +++++++++----
 cpukit/rtems/src/taskcreate.c           | 16 ++++++++--
 cpukit/score/src/mpci.c                 | 20 +++++++++----
 cpukit/score/src/threadcreateidle.c     | 17 ++++++++---
 cpukit/score/src/threadinitialize.c     | 53 ++++++++++++---------------------
 7 files changed, 83 insertions(+), 54 deletions(-)

diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h
index 336be281bd..c70624f64a 100644
--- a/cpukit/include/rtems/score/thread.h
+++ b/cpukit/include/rtems/score/thread.h
@@ -83,8 +83,6 @@ extern "C" {
  */
 #define RTEMS_SCORE_THREAD_ENABLE_SCHEDULER_CALLOUT
 
-#define RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API
-
 #if defined(RTEMS_DEBUG)
 #define RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT
 #endif
diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h
index 2cde5d4fe0..b007055eeb 100644
--- a/cpukit/include/rtems/score/threadimpl.h
+++ b/cpukit/include/rtems/score/threadimpl.h
@@ -140,15 +140,20 @@ typedef struct {
   const struct _Scheduler_Control *scheduler;
 
   /**
-   * @brief The starting address of the thread area.
+   * @brief The starting address of the stack area.
    */
   void *stack_area;
 
   /**
-   * @brief The size of the thread area in bytes.
+   * @brief The size of the stack area in bytes.
    */
   size_t stack_size;
 
+  /**
+   * @brief The address of the allocated stack area or NULL.
+   */
+  void *allocated_stack;
+
   /**
    * @brief The new thread's priority.
    */
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index 2a418c4b68..1960a4478b 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -120,6 +120,7 @@ int pthread_create(
     config.stack_size = _POSIX_Threads_Ensure_minimum_stack(
       the_attr->stacksize
     );
+    config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp );
   }
 
   #if 0
@@ -215,14 +216,23 @@ int pthread_create(
     return EAGAIN;
   }
 
+  if ( config.stack_area == NULL ) {
+    config.stack_area = _Stack_Allocate( config.stack_size );
+    config.allocated_stack = config.stack_area;
+  }
+
+  status = ( config.stack_area != NULL );
+
   /*
    *  Initialize the core thread for this task.
    */
-  status = _Thread_Initialize(
-    &_POSIX_Threads_Information,
-    the_thread,
-    &config
-  );
+  if ( status ) {
+    status = _Thread_Initialize(
+      &_POSIX_Threads_Information,
+      the_thread,
+      &config
+    );
+  }
   if ( !status ) {
     _POSIX_Threads_Free( the_thread );
     _Objects_Allocator_unlock();
diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c
index 9ca0047aa7..019da6588f 100644
--- a/cpukit/rtems/src/taskcreate.c
+++ b/cpukit/rtems/src/taskcreate.c
@@ -25,6 +25,7 @@
 #include <rtems/rtems/support.h>
 #include <rtems/score/apimutex.h>
 #include <rtems/score/schedulerimpl.h>
+#include <rtems/score/stackimpl.h>
 #include <rtems/score/sysstate.h>
 #include <rtems/score/threadimpl.h>
 #include <rtems/score/userextimpl.h>
@@ -78,7 +79,6 @@ rtems_status_code rtems_task_create(
     _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );
 
   memset( &config, 0, sizeof( config ) );
-  config.stack_size = stack_size;
   config.budget_algorithm = _Modes_Is_timeslice( initial_modes ) ?
     THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE
       : THREAD_CPU_BUDGET_ALGORITHM_NONE,
@@ -86,6 +86,8 @@ rtems_status_code rtems_task_create(
   config.name.name_u32 = name;
   config.is_fp = _Attributes_Is_floating_point( the_attribute_set );
   config.is_preemptible = _Modes_Is_preempt( initial_modes );
+  config.stack_size = _Stack_Ensure_minimum( stack_size );
+  config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp );
 
   /*
    *  Validate the RTEMS API priority and convert it to the core priority range.
@@ -148,11 +150,21 @@ rtems_status_code rtems_task_create(
   }
 #endif
 
+  config.stack_area = _Stack_Allocate( config.stack_size );
+  config.allocated_stack = config.stack_area;
+  status = ( config.stack_area != NULL );
+
   /*
    *  Initialize the core thread for this task.
    */
 
-  status = _Thread_Initialize( &_RTEMS_tasks_Information, the_thread, &config );
+  if ( status ) {
+    status = _Thread_Initialize(
+      &_RTEMS_tasks_Information,
+      the_thread,
+      &config
+    );
+  }
 
   if ( !status ) {
 #if defined(RTEMS_MULTIPROCESSING)
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
index 32489ac0cf..1f9b838796 100644
--- a/cpukit/score/src/mpci.c
+++ b/cpukit/score/src/mpci.c
@@ -114,6 +114,7 @@ static void _MPCI_Create_server( void )
     }
   };
   Thread_Configuration config;
+  bool                 ok;
   ISR_lock_Context     lock_context;
 
 
@@ -129,15 +130,24 @@ static void _MPCI_Create_server( void )
 
   memset( &config, 0, sizeof( config ) );
   config.scheduler = &_Scheduler_Table[ 0 ];
-  config.stack_size = _Stack_Minimum()
-    + CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK
-    + _MPCI_Configuration.extra_mpci_receive_server_stack;
   config.name.name_u32 = _Objects_Build_name( 'M', 'P', 'C', 'I' );
   config.priority = PRIORITY_PSEUDO_ISR;
   config.budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
   config.is_fp = CPU_ALL_TASKS_ARE_FP;
-
-  _Thread_Initialize( &_Thread_Information, _MPCI_Receive_server_tcb, &config );
+  config.stack_size = _Stack_Minimum()
+    + CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK
+    + _MPCI_Configuration.extra_mpci_receive_server_stack;
+  config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp );
+  config.stack_area = _Stack_Allocate( config.stack_size );
+  _Assert( config.stack_area != NULL );
+
+  ok = _Thread_Initialize(
+    &_Thread_Information,
+    _MPCI_Receive_server_tcb,
+    &config
+  );
+  _Assert( ok );
+  (void) ok;
 
   _ISR_lock_ISR_disable( &lock_context );
   _Thread_Start( _MPCI_Receive_server_tcb, &entry, &lock_context );
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
index e7243ae09c..c06f211a6b 100644
--- a/cpukit/score/src/threadcreateidle.c
+++ b/cpukit/score/src/threadcreateidle.c
@@ -21,6 +21,7 @@
 #include <rtems/score/threadimpl.h>
 #include <rtems/score/assert.h>
 #include <rtems/score/schedulerimpl.h>
+#include <rtems/score/stackimpl.h>
 #include <rtems/score/sysstate.h>
 #include <rtems/score/userextimpl.h>
 #include <rtems/config.h>
@@ -29,8 +30,9 @@
 
 static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
 {
-  Thread_Configuration     config;
-  Thread_Control          *idle;
+  Thread_Configuration  config;
+  Thread_Control       *idle;
+  bool                  ok;
 
   memset( &config, 0, sizeof( config ) );
   config.scheduler = _Scheduler_Get_by_CPU( cpu );
@@ -41,7 +43,6 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
   }
 #endif
 
-  config.stack_size = rtems_configuration_get_idle_task_stack_size();
   config.priority = _Scheduler_Map_priority(
     config.scheduler,
     config.scheduler->maximum_priority
@@ -50,6 +51,12 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
   config.name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' );
   config.is_fp = CPU_IDLE_TASK_IS_FP;
   config.is_preemptible = true;
+  config.stack_size = _Stack_Ensure_minimum(
+    rtems_configuration_get_idle_task_stack_size()
+  );
+  config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp );
+  config.stack_area = _Stack_Allocate( config.stack_size );
+  _Assert( config.stack_area != NULL );
 
   /*
    *  The entire workspace is zeroed during its initialization.  Thus, all
@@ -59,7 +66,9 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
   idle = _Thread_Internal_allocate();
   _Assert( idle != NULL );
 
-  _Thread_Initialize( &_Thread_Information, idle, &config );
+  ok = _Thread_Initialize( &_Thread_Information, idle, &config );
+  _Assert( ok );
+  (void) ok;
 
   /*
    *  WARNING!!! This is necessary to "kick" start the system and
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index a2bb09425d..6b9b6bef21 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -46,23 +46,6 @@ bool _Thread_Initialize(
   size_t                   scheduler_index;
   Per_CPU_Control         *cpu = _Per_CPU_Get_by_index( 0 );
 
-#if defined(RTEMS_SMP)
-  if ( !config->is_preemptible && rtems_configuration_is_smp_enabled() ) {
-    return false;
-  }
-#endif
-
-#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
-  if (
-    config->isr_level != 0
-#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
-      && rtems_configuration_is_smp_enabled()
-#endif
-  ) {
-    return false;
-  }
-#endif
-
   memset(
     &the_thread->Join_queue,
     0,
@@ -76,26 +59,30 @@ bool _Thread_Initialize(
       (char *) the_thread + add_on->source_offset;
   }
 
-  /* Allocate the stack for this thread */
-#if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API)
-  if ( config->stack_area == NULL ) {
-#endif
-    stack_size = _Stack_Ensure_minimum( config->stack_size );
-    stack_size = _Stack_Extend_size( stack_size, config->is_fp );
-    stack_area = _Stack_Allocate( stack_size );
+  /* Set everything to perform the error case clean up */
+  scheduler_index = 0;
+  the_thread->Start.allocated_stack = config->allocated_stack;
 
-    if ( stack_area == NULL ) {
-      return false;
-    }
+#if defined(RTEMS_SMP)
+  if ( !config->is_preemptible && rtems_configuration_is_smp_enabled() ) {
+    goto failed;
+  }
+#endif
 
-    the_thread->Start.allocated_stack = stack_area;
-#if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API)
-  } else {
-    stack_area = config->stack_area;
-    stack_size = config->stack_size;
+#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+  if (
+    config->isr_level != 0
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
+      && rtems_configuration_is_smp_enabled()
+#endif
+  ) {
+    goto failed;
   }
 #endif
 
+  stack_area = config->stack_area;
+  stack_size = config->stack_size;
+
   /* Allocate floating-point context in stack area */
 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
   if ( config->is_fp ) {
@@ -125,8 +112,6 @@ bool _Thread_Initialize(
      stack_size
   );
 
-  scheduler_index = 0;
-
   /*
    *  Get thread queue heads
    */
-- 
2.16.4



More information about the devel mailing list