[RTEMS 5] Add support for IDLE Thread stack allocator
Sebastian Huber
sebastian.huber at embedded-brains.de
Mon Oct 4 17:35:50 UTC 2021
On 04/10/2021 18:11, Joel Sherrill wrote:
> Add a stack allocator hook specifically for allocation of IDLE thread stacks.
> This allows the user to decide if IDLE thread stacks are statically allocated
> or handled by the same custom allocator mechanism as other thread stacks.
>
> Closes #4520.
> ---
> cpukit/include/rtems/confdefs/percpu.h | 20 +++-
> cpukit/include/rtems/confdefs/wkspace.h | 13 +++
> cpukit/include/rtems/config.h | 3 +
> cpukit/include/rtems/score/stack.h | 24 +++++
> cpukit/score/src/stackallocator.c | 3 +
> cpukit/score/src/threadcreateidle.c | 18 +++-
> testsuites/sptests/spstkalloc03/init.c | 98 +++++++++++++++++++
> .../sptests/spstkalloc03/spstkalloc03.doc | 19 ++++
> .../sptests/spstkalloc03/spstkalloc03.scn | 2 +
> 9 files changed, 192 insertions(+), 8 deletions(-)
> create mode 100644 testsuites/sptests/spstkalloc03/init.c
> create mode 100644 testsuites/sptests/spstkalloc03/spstkalloc03.doc
> create mode 100644 testsuites/sptests/spstkalloc03/spstkalloc03.scn
>
> diff --git a/cpukit/include/rtems/confdefs/percpu.h b/cpukit/include/rtems/confdefs/percpu.h
> index f3a9a4f3e7..a6ba4fece0 100644
> --- a/cpukit/include/rtems/confdefs/percpu.h
> +++ b/cpukit/include/rtems/confdefs/percpu.h
> @@ -133,11 +133,21 @@ RTEMS_DEFINE_GLOBAL_SYMBOL(
>
> const size_t _Thread_Idle_stack_size = CONFIGURE_IDLE_TASK_STACK_SIZE;
>
> -char _Thread_Idle_stacks[
> - _CONFIGURE_MAXIMUM_PROCESSORS
> - * ( CONFIGURE_IDLE_TASK_STACK_SIZE + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE )
> -] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
> -RTEMS_SECTION( ".rtemsstack.idle" );
> +/*
> + * If the user provides a custom idle stack allocator, then we do not need
> + * memory reserved for the stacks but the symbol is still referenced in
> + * threadcreateidle.c. The code path just never uses it. Make it minimal
> + * size to proceed.
> + */
> + char _Thread_Idle_stacks[
> +#ifdef CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE
Maybe name the option CONFIGURE_IDLE_TASK_STACK_ALLOCATOR similar to
CONFIGURE_IDLE_TASK_STACK_SIZE, CONFIGURE_IDLE_TASK_BODY, and
CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION.
> + 1
You don't need this, see below.
> +#else
> + _CONFIGURE_MAXIMUM_PROCESSORS
> + * ( CONFIGURE_IDLE_TASK_STACK_SIZE + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE )
> +#endif
> + ] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
> + RTEMS_SECTION( ".rtemsstack.idle" );
>
> #if defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION) && \
> !defined(CONFIGURE_IDLE_TASK_BODY)
> diff --git a/cpukit/include/rtems/confdefs/wkspace.h b/cpukit/include/rtems/confdefs/wkspace.h
> index 484dde20ea..abe4cd50af 100644
> --- a/cpukit/include/rtems/confdefs/wkspace.h
> +++ b/cpukit/include/rtems/confdefs/wkspace.h
> @@ -132,12 +132,14 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE;
>
> #if defined(CONFIGURE_TASK_STACK_ALLOCATOR) \
> && defined(CONFIGURE_TASK_STACK_DEALLOCATOR)
> + /* Custom allocator may or may not use the work space. */
> #ifdef CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE
> const bool _Stack_Allocator_avoids_workspace = true;
> #else
> const bool _Stack_Allocator_avoids_workspace = false;
> #endif
>
> + /* Custom allocator may or may not need initialization. */
> #ifdef CONFIGURE_TASK_STACK_ALLOCATOR_INIT
> const Stack_Allocator_initialize _Stack_Allocator_initialize =
> CONFIGURE_TASK_STACK_ALLOCATOR_INIT;
> @@ -145,11 +147,22 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE;
> const Stack_Allocator_initialize _Stack_Allocator_initialize = NULL;
> #endif
>
> + /* Custom allocator must include allocate and free */
> const Stack_Allocator_allocate _Stack_Allocator_allocate =
> CONFIGURE_TASK_STACK_ALLOCATOR;
>
> const Stack_Allocator_free _Stack_Allocator_free =
> CONFIGURE_TASK_STACK_DEALLOCATOR;
> +
> + /* Custom allocator MAY include allocate IDLE thread stacks */
> + #ifdef CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE
> + const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle =
> + CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE;
> + #else
> + const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle =
> + NULL;
Use _Stack_Allocator_allocate_for_idle_default instead of NULL
> + #endif
> +
> #elif defined(CONFIGURE_TASK_STACK_ALLOCATOR) \
> || defined(CONFIGURE_TASK_STACK_DEALLOCATOR)
> #error "CONFIGURE_TASK_STACK_ALLOCATOR and CONFIGURE_TASK_STACK_DEALLOCATOR must be both defined or both undefined"
> diff --git a/cpukit/include/rtems/config.h b/cpukit/include/rtems/config.h
> index e82c7abf11..a826581658 100644
> --- a/cpukit/include/rtems/config.h
> +++ b/cpukit/include/rtems/config.h
> @@ -129,6 +129,9 @@ uint32_t rtems_configuration_get_maximum_extensions( void );
> #define rtems_configuration_get_stack_free_hook() \
> (_Stack_Allocator_free)
>
> +#define rtems_configuration_get_stack_allocate_for_idle_hook() \
> + (_Stack_Allocator_allocate_for_idle)
> +
> /**
> * This macro assists in accessing the field which indicates whether
> * RTEMS is responsible for zeroing the Executive Workspace.
> diff --git a/cpukit/include/rtems/score/stack.h b/cpukit/include/rtems/score/stack.h
> index df1df74867..9c60b4f15e 100644
> --- a/cpukit/include/rtems/score/stack.h
> +++ b/cpukit/include/rtems/score/stack.h
> @@ -81,6 +81,23 @@ typedef void *( *Stack_Allocator_allocate )( size_t stack_size );
> */
> typedef void ( *Stack_Allocator_free )( void *addr );
>
> +/**
> + * @brief Stack allocator allocate for idle handler.
> + *
> + * The allocate for idle handler is optional even when the user thread stack
> + * allocator and deallocator are configured.
> + *
> + * @param cpu The index of the CPU for the IDLE thread using this stack
> + * @param stack_size The size of the stack area to allocate in bytes.
> + *
> + * @retval NULL Not enough memory.
> + * @retval other Pointer to begin of stack area.
> + */
> +typedef void *( *Stack_Allocator_allocate_for_idle )(
> + uint32_t cpu,
> + size_t stack_size
> +);
> +
> /**
> * @brief The minimum stack size.
> *
> @@ -124,6 +141,13 @@ extern const Stack_Allocator_allocate _Stack_Allocator_allocate;
> extern const Stack_Allocator_free _Stack_Allocator_free;
>
> /** @} */
> +/**
> + * @brief The stack allocator allocate stack for idle thread handler.
> + *
> + * Application provided via <rtems/confdefs.h>.
> + */
> +extern const Stack_Allocator_allocate_for_idle
> + _Stack_Allocator_allocate_for_idle;
>
> #ifdef __cplusplus
> }
> diff --git a/cpukit/score/src/stackallocator.c b/cpukit/score/src/stackallocator.c
> index 404b98fa1c..fd06d382a2 100644
> --- a/cpukit/score/src/stackallocator.c
> +++ b/cpukit/score/src/stackallocator.c
> @@ -39,3 +39,6 @@ const Stack_Allocator_initialize _Stack_Allocator_initialize = NULL;
> const Stack_Allocator_allocate _Stack_Allocator_allocate = _Workspace_Allocate;
>
> const Stack_Allocator_free _Stack_Allocator_free = _Workspace_Free;
> +
> +const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle =
> + NULL;
> diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
> index 1e18ad07cc..440f67f69b 100644
> --- a/cpukit/score/src/threadcreateidle.c
> +++ b/cpukit/score/src/threadcreateidle.c
> @@ -53,9 +53,21 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
> config.is_preemptible = true;
> config.stack_size = _Thread_Idle_stack_size
> + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE;
> - config.stack_area = &_Thread_Idle_stacks[
> - _Per_CPU_Get_index( cpu ) * config.stack_size
> - ];
> +
> + /*
> + * The IDLE thread stacks mau be statically allocated or there may be a
> + * custom allocator provided just as with user threads.
> + */
> + if ( _Stack_Allocator_allocate_for_idle == NULL ) {
Please remove this if, and replace it with a default implementation
_Stack_Allocator_allocate_for_idle_default() which just contains the
code block below.
> + config.stack_area = &_Thread_Idle_stacks[
> + _Per_CPU_Get_index( cpu ) * config.stack_size
> + ];
> + } else {
> + config.stack_area = (*_Stack_Allocator_allocate_for_idle)(
> + _Per_CPU_Get_index( cpu ),
> + config.stack_size
> + );
> + }
>
> /*
> * The entire workspace is zeroed during its initialization. Thus, all
[...]
--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber at embedded-brains.de
phone: +49-89-18 94 741 - 16
fax: +49-89-18 94 741 - 08
Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
More information about the devel
mailing list