From 2846b17d7e34f1bdcac579ea1e0fbcb251aff1cb Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 26 Sep 2022 09:31:29 +0200 Subject: config: Changeable size for IDLE stack allocator 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 /** - * @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 ); } -- cgit v1.2.3