From 45ee958552ca35b6834985718ecd59b27fc52f86 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 30 Sep 2022 08:06:18 +0200 Subject: config: Add CONFIGURE_IDLE_TASK_STORAGE_SIZE By default, allocate the IDLE task storage areas from the RTEMS Workspace. This avoids having to estimate the thread-local storage size in the default configuration. Add the application configuration option CONFIGURE_IDLE_TASK_STORAGE_SIZE to request a static allocation of the task storage area for IDLE tasks. Update #3835. Update #4524. --- cpukit/include/rtems/confdefs/percpu.h | 14 -------- cpukit/include/rtems/confdefs/threads.h | 4 +++ cpukit/include/rtems/confdefs/wkspace.h | 50 ++++++++++++++++++++++++---- cpukit/include/rtems/score/interr.h | 3 +- cpukit/include/rtems/score/stack.h | 58 +++++++++++++++++++++++++++++++-- cpukit/include/rtems/score/thread.h | 7 ---- 6 files changed, 104 insertions(+), 32 deletions(-) (limited to 'cpukit/include') diff --git a/cpukit/include/rtems/confdefs/percpu.h b/cpukit/include/rtems/confdefs/percpu.h index b91590bfd9..a6b35e0eaf 100644 --- a/cpukit/include/rtems/confdefs/percpu.h +++ b/cpukit/include/rtems/confdefs/percpu.h @@ -136,20 +136,6 @@ RTEMS_DEFINE_GLOBAL_SYMBOL( const size_t _Thread_Idle_stack_size = CONFIGURE_IDLE_TASK_STACK_SIZE; -/* - * 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. - */ -#ifndef CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE - 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" ); -#endif - #if defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION) && \ !defined(CONFIGURE_IDLE_TASK_BODY) #error "If you define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION, then you must define CONFIGURE_IDLE_TASK_BODY as well" diff --git a/cpukit/include/rtems/confdefs/threads.h b/cpukit/include/rtems/confdefs/threads.h index 4040bcb50a..5ccfffaf6e 100644 --- a/cpukit/include/rtems/confdefs/threads.h +++ b/cpukit/include/rtems/confdefs/threads.h @@ -235,6 +235,10 @@ const size_t _Thread_Control_add_on_count = #endif const size_t _Thread_Initial_thread_count = +#if !defined(CONFIGURE_IDLE_TASK_STORAGE_SIZE) && \ + !defined(CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE) + _CONFIGURE_MAXIMUM_PROCESSORS + +#endif rtems_resource_maximum_per_allocation( _CONFIGURE_TASKS ) + rtems_resource_maximum_per_allocation( CONFIGURE_MAXIMUM_POSIX_THREADS ); diff --git a/cpukit/include/rtems/confdefs/wkspace.h b/cpukit/include/rtems/confdefs/wkspace.h index 82de8633bf..da766fd8af 100644 --- a/cpukit/include/rtems/confdefs/wkspace.h +++ b/cpukit/include/rtems/confdefs/wkspace.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -111,8 +112,18 @@ + 1024 * CONFIGURE_MEMORY_OVERHEAD \ + _CONFIGURE_HEAP_HANDLER_OVERHEAD ) +#if defined(CONFIGURE_IDLE_TASK_STORAGE_SIZE) || \ + defined(CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE) + #define _CONFIGURE_IDLE_TASK_STACKS 0 +#else + #define _CONFIGURE_IDLE_TASK_STACKS \ + ( _CONFIGURE_MAXIMUM_PROCESSORS * \ + _Configure_From_stackspace( CONFIGURE_IDLE_TASK_STACK_SIZE ) ) +#endif + #define _CONFIGURE_STACK_SPACE_SIZE \ ( _CONFIGURE_INIT_TASK_STACK_EXTRA \ + + _CONFIGURE_IDLE_TASK_STACKS \ + _CONFIGURE_POSIX_INIT_THREAD_STACK_EXTRA \ + _CONFIGURE_LIBBLOCK_TASKS_STACK_EXTRA \ + CONFIGURE_EXTRA_TASK_STACKS \ @@ -212,15 +223,40 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE; #error "CONFIGURE_TASK_STACK_ALLOCATOR and CONFIGURE_TASK_STACK_DEALLOCATOR must be both defined or both undefined" #endif -/* - * Custom IDLE thread stacks allocator. If this is provided, it is assumed - * that the allocator is providing its own memory for these 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; +#ifdef CONFIGURE_IDLE_TASK_STORAGE_SIZE + #ifdef CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE + #error "CONFIGURE_IDLE_TASK_STORAGE_SIZE and CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE are mutually exclusive" + #endif + + #define _CONFIGURE_IDLE_TASK_STORAGE_SIZE \ + RTEMS_ALIGN_UP( \ + RTEMS_TASK_STORAGE_SIZE( \ + CONFIGURE_IDLE_TASK_STORAGE_SIZE, \ + RTEMS_DEFAULT_ATTRIBUTES \ + ), \ + CPU_INTERRUPT_STACK_ALIGNMENT \ + ) + + const size_t _Stack_Allocator_allocate_for_idle_storage_size = + _CONFIGURE_IDLE_TASK_STORAGE_SIZE; + + char _Stack_Allocator_allocate_for_idle_storage_areas[ + _CONFIGURE_MAXIMUM_PROCESSORS * _CONFIGURE_IDLE_TASK_STORAGE_SIZE + ] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT ) + RTEMS_SECTION( ".rtemsstack.idle" ); + + #define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE \ + _Stack_Allocator_allocate_for_idle_static #endif +#ifndef CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE + #define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE \ + _Stack_Allocator_allocate_for_idle_workspace +#endif + +const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle = + CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE; + #ifdef CONFIGURE_DIRTY_MEMORY RTEMS_SYSINIT_ITEM( _Memory_Dirty_free_areas, diff --git a/cpukit/include/rtems/score/interr.h b/cpukit/include/rtems/score/interr.h index d0ecf0f5c8..f21e8d58a1 100644 --- a/cpukit/include/rtems/score/interr.h +++ b/cpukit/include/rtems/score/interr.h @@ -229,7 +229,8 @@ typedef enum { INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA = 40, INTERNAL_ERROR_TOO_LARGE_TLS_SIZE = 41, INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED = 42, - INTERNAL_ERROR_IDLE_THREAD_CREATE_FAILED = 43 + INTERNAL_ERROR_IDLE_THREAD_CREATE_FAILED = 43, + INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STORAGE = 44 } Internal_errors_Core_list; typedef CPU_Uint32ptr Internal_errors_t; diff --git a/cpukit/include/rtems/score/stack.h b/cpukit/include/rtems/score/stack.h index 7577ca0474..9326480373 100644 --- a/cpukit/include/rtems/score/stack.h +++ b/cpukit/include/rtems/score/stack.h @@ -11,8 +11,8 @@ */ /* - * COPYRIGHT (c) 1989-2006. - * On-Line Applications Research Corporation (OAR). + * Copyright (C) 2022 embedded brains GmbH + * Copyright (C) 1989, 2021 On-Line Applications Research Corporation (OAR) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -172,7 +172,57 @@ extern const Stack_Allocator_free _Stack_Allocator_free; */ void _Stack_Allocator_do_initialize( void ); -/** @} */ +/** + * @brief Allocates the IDLE thread storage area from the workspace. + * + * If the thread storage area cannot be allocated, then the + * ::INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STACK fatal error will occur. + * + * @param unused is an unused parameter. + * + * @param stack_size[in] is pointer to a size_t object. On function entry, the + * object contains the size of the task storage area to allocate in bytes. + * + * @return Returns a pointer to the begin of the allocated task storage area. + */ +void *_Stack_Allocator_allocate_for_idle_workspace( + uint32_t unused, + size_t *storage_size +); + +/** + * @brief The size in bytes of the idle thread storage area used by + * _Stack_Allocator_allocate_for_idle_static(). + * + * Application provided via . + */ +extern const size_t _Stack_Allocator_allocate_for_idle_storage_size; + +/** + * @brief The thread storage areas used by + * _Stack_Allocator_allocate_for_idle_static(). + * + * Application provided via . + */ +extern char _Stack_Allocator_allocate_for_idle_storage_areas[]; + +/** + * @brief Allocates the IDLE thread storage from the memory statically + * allocated by . + * + * @param cpu_index is the index of the CPU for the IDLE thread using this stack. + * + * @param stack_size[out] is pointer to a size_t object. On function return, the + * object value is set to the value of + * ::_Stack_Allocator_allocate_for_idle_storage_size. + * + * @return Returns a pointer to the begin of the allocated task storage area. + */ +void *_Stack_Allocator_allocate_for_idle_static( + uint32_t cpu_index, + size_t *storage_size +); + /** * @brief The stack allocator allocate stack for idle thread handler. * @@ -181,6 +231,8 @@ void _Stack_Allocator_do_initialize( void ); extern const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle; +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h index f82d4b954c..2b4d6823f0 100644 --- a/cpukit/include/rtems/score/thread.h +++ b/cpukit/include/rtems/score/thread.h @@ -1186,13 +1186,6 @@ Thread_Information name##_Information = { \ } \ } -/** - * @brief The idle thread stacks. - * - * Provided by the application via . - */ -extern char _Thread_Idle_stacks[]; - #if defined(RTEMS_MULTIPROCESSING) /** * @brief The configured thread control block. -- cgit v1.2.3