[PATCH v2 05/13] config: Changeable size for IDLE stack allocator

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Oct 6 08:23:24 UTC 2022


Allow the IDLE stack allocator to change the stack size.  This can be
used by applications with a very dynamic thread-local storage size to
adjust the thread storage area of the IDLE tasks dynamically.

Update #4524.
---
 cpukit/doxygen/appl-config.h             |  2 +-
 cpukit/include/rtems/score/stack.h       | 17 ++++++++++++-----
 cpukit/score/src/stackallocatorforidle.c | 19 +++++++++----------
 cpukit/score/src/threadcreateidle.c      |  4 ++--
 testsuites/sptests/spstkalloc03/init.c   |  4 ++--
 testsuites/sptests/spstkalloc04/init.c   |  4 ++--
 testsuites/validation/ts-config.h        |  2 +-
 testsuites/validation/ts-default.h       |  4 ++--
 8 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/cpukit/doxygen/appl-config.h b/cpukit/doxygen/appl-config.h
index 1df7f335e6..d53947c71a 100644
--- a/cpukit/doxygen/appl-config.h
+++ b/cpukit/doxygen/appl-config.h
@@ -4836,7 +4836,7 @@
  *
  * @par Value Constraints
  * The value of this configuration option shall be defined to a valid function
- * pointer of the type ``void *( *allocate )( uint32_t, size_t )``.
+ * pointer of the type ``void *( *allocate )( uint32_t, size_t * )``.
  *
  * @par Notes
  * This configuration option is independent of the other thread stack allocator
diff --git a/cpukit/include/rtems/score/stack.h b/cpukit/include/rtems/score/stack.h
index 360e4d61f6..7577ca0474 100644
--- a/cpukit/include/rtems/score/stack.h
+++ b/cpukit/include/rtems/score/stack.h
@@ -105,15 +105,22 @@ typedef void ( *Stack_Allocator_free )( void *addr );
  * The allocate for idle handler is optional even when the user thread stack
  * allocator and deallocator are configured.
  *
- * @param cpu Index of the CPU for the IDLE thread using this stack
- * @param stack_size The size of the stack area to allocate in bytes.
+ * @param cpu is the index of the CPU for the IDLE thread using this stack.
  *
- * @retval NULL Not enough memory.
- * @retval other Pointer to begin of stack area.
+ * @param stack_size[in, out] is pointer to a size_t object.  On function
+ *   entry, the object contains the proposed size of the stack area to allocate
+ *   in bytes.  The proposed size does not take the actual thread-local storage
+ *   size of the application into account.  The stack allocator can modify the
+ *   size to ensure that there is enough space available in the stack area for
+ *   the thread-local storage.
+ *
+ * @retval NULL There was not enough memory available to allocate a stack area.
+ *
+ * @return Returns the pointer to begin of the allocated stack area.
  */
 typedef void *( *Stack_Allocator_allocate_for_idle )(
   uint32_t  cpu,
-  size_t    stack_size
+  size_t   *stack_size
 );
 
 /**
diff --git a/cpukit/score/src/stackallocatorforidle.c b/cpukit/score/src/stackallocatorforidle.c
index 76b6ace1f4..c97dde030f 100644
--- a/cpukit/score/src/stackallocatorforidle.c
+++ b/cpukit/score/src/stackallocatorforidle.c
@@ -34,27 +34,26 @@
 #include <rtems/score/assert.h>
 
 /**
- * @brief Default stack allocator allocate for idle handler.
- *
- * The allocate for idle handler is optional even when the user thread stack
- * allocator and deallocator are configured.
+ * @brief Default stack allocator allocate for IDLE threads.
  *
  * The default allocator for IDLE thread stacks gets the memory from a
  * statically allocated area provided via confdefs.h.
  *
- * @param cpu_index Index of the CPU for the IDLE thread using this stack
- * @param stack_size The size of the stack area to allocate in bytes.
+ * @param cpu is the index of the CPU for the IDLE thread using this stack.
+ *
+ * @param stack_size[in] is pointer to a size_t object.  On function
+ *   entry, the object contains the size of the stack area to allocate in
+ *   bytes.
  *
- * @retval NULL Not enough memory (never returned).
- * @retval other Pointer to begin of stack area.
+ * @return Returns the pointer to begin of the allocated stack area.
  */
 static void *_Stack_Allocator_allocate_for_idle_default(
   uint32_t  cpu_index,
-  size_t    stack_size
+  size_t   *stack_size
 )
 {
 #if defined(RTEMS_SMP)
-  return &_Thread_Idle_stacks[ cpu_index * stack_size ];
+  return &_Thread_Idle_stacks[ cpu_index * ( *stack_size ) ];
 #else
   _Assert( cpu_index == 0 );
   return &_Thread_Idle_stacks[ 0 ];
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
index b5e0cfdc9b..3e3c7cfc83 100644
--- a/cpukit/score/src/threadcreateidle.c
+++ b/cpukit/score/src/threadcreateidle.c
@@ -73,9 +73,9 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
    * The IDLE thread stacks may be statically allocated or there may be a
    * custom allocator provided just as with user threads.
    */
-  config.stack_area = (*_Stack_Allocator_allocate_for_idle)(
+  config.stack_area = ( *_Stack_Allocator_allocate_for_idle )(
     _Per_CPU_Get_index( cpu ),
-    config.stack_size
+    &config.stack_size
   );
 
   /*
diff --git a/testsuites/sptests/spstkalloc03/init.c b/testsuites/sptests/spstkalloc03/init.c
index 6d6817bccb..5ee7de26ec 100644
--- a/testsuites/sptests/spstkalloc03/init.c
+++ b/testsuites/sptests/spstkalloc03/init.c
@@ -87,12 +87,12 @@ static void thread_stacks_free(void *addr)
 
 static void *thread_stacks_allocate_for_idle(
   uint32_t  cpu,
-  size_t    stack_size
+  size_t   *stack_size
 )
 {
   rtems_test_assert(thread_stacks_count == 0);
   thread_stacks_count++;
-  return allocate_helper(stack_size);
+  return allocate_helper(*stack_size);
 }
 
 /*
diff --git a/testsuites/sptests/spstkalloc04/init.c b/testsuites/sptests/spstkalloc04/init.c
index c5d2614f64..9678f6e00c 100644
--- a/testsuites/sptests/spstkalloc04/init.c
+++ b/testsuites/sptests/spstkalloc04/init.c
@@ -69,12 +69,12 @@ static void *allocate_helper(size_t size)
 
 static void *thread_stacks_allocate_for_idle(
   uint32_t  cpu,
-  size_t    stack_size
+  size_t   *stack_size
 )
 {
   rtems_test_assert(thread_stacks_count == 0);
   thread_stacks_count++;
-  return allocate_helper(stack_size);
+  return allocate_helper(*stack_size);
 }
 
 /*
diff --git a/testsuites/validation/ts-config.h b/testsuites/validation/ts-config.h
index 7685fee278..fbd62ac6b5 100644
--- a/testsuites/validation/ts-config.h
+++ b/testsuites/validation/ts-config.h
@@ -109,7 +109,7 @@ void *test_task_stack_allocate( size_t size );
 
 void test_task_stack_deallocate( void *stack );
 
-void *test_idle_task_stack_allocate( uint32_t cpu_index, size_t size );
+void *test_idle_task_stack_allocate( uint32_t cpu_index, size_t *size );
 
 extern rtems_task_argument test_runner_argument;
 
diff --git a/testsuites/validation/ts-default.h b/testsuites/validation/ts-default.h
index 435fccdc51..6e77496b90 100644
--- a/testsuites/validation/ts-default.h
+++ b/testsuites/validation/ts-default.h
@@ -322,9 +322,9 @@ static char test_idle_stacks[ CONFIGURE_MAXIMUM_PROCESSORS ][
 RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
 RTEMS_SECTION( ".rtemsstack.idle" );
 
-void *test_idle_task_stack_allocate( uint32_t cpu_index, size_t size )
+void *test_idle_task_stack_allocate( uint32_t cpu_index, size_t *size )
 {
-  if ( size > sizeof( test_idle_stacks[ 0 ] ) ) {
+  if ( *size > sizeof( test_idle_stacks[ 0 ] ) ) {
     rtems_fatal( RTEMS_FATAL_SOURCE_APPLICATION, 0xABAD1DEA );
   }
 
-- 
2.35.3



More information about the devel mailing list