diff options
Diffstat (limited to '')
-rw-r--r-- | cpukit/include/rtems/confdefs/percpu.h | 18 | ||||
-rw-r--r-- | cpukit/include/rtems/confdefs/wkspace.h | 16 | ||||
-rw-r--r-- | cpukit/include/rtems/config.h | 12 | ||||
-rw-r--r-- | cpukit/include/rtems/score/stack.h | 24 | ||||
-rw-r--r-- | cpukit/score/src/stackallocatorforidle.c | 59 | ||||
-rw-r--r-- | cpukit/score/src/threadcreateidle.c | 12 | ||||
-rw-r--r-- | spec/build/cpukit/librtemscpu.yml | 1 | ||||
-rw-r--r-- | spec/build/testsuites/sptests/grp.yml | 4 | ||||
-rw-r--r-- | spec/build/testsuites/sptests/spstkalloc03.yml | 19 | ||||
-rw-r--r-- | spec/build/testsuites/sptests/spstkalloc04.yml | 19 | ||||
-rw-r--r-- | testsuites/sptests/spstkalloc03/init.c | 103 | ||||
-rw-r--r-- | testsuites/sptests/spstkalloc03/spstkalloc03.doc | 19 | ||||
-rw-r--r-- | testsuites/sptests/spstkalloc03/spstkalloc03.scn | 2 | ||||
-rw-r--r-- | testsuites/sptests/spstkalloc04/init.c | 82 | ||||
-rw-r--r-- | testsuites/sptests/spstkalloc04/spstkalloc04.doc | 20 | ||||
-rw-r--r-- | testsuites/sptests/spstkalloc04/spstkalloc04.scn | 2 |
16 files changed, 404 insertions, 8 deletions
diff --git a/cpukit/include/rtems/confdefs/percpu.h b/cpukit/include/rtems/confdefs/percpu.h index badb616988..3bea8340cb 100644 --- a/cpukit/include/rtems/confdefs/percpu.h +++ b/cpukit/include/rtems/confdefs/percpu.h @@ -134,11 +134,19 @@ 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. + */ +#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) diff --git a/cpukit/include/rtems/confdefs/wkspace.h b/cpukit/include/rtems/confdefs/wkspace.h index 1db4f2d09d..82de8633bf 100644 --- a/cpukit/include/rtems/confdefs/wkspace.h +++ b/cpukit/include/rtems/confdefs/wkspace.h @@ -167,12 +167,14 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE; #pragma GCC diagnostic ignored "-Wpragmas" #pragma GCC diagnostic ignored "-Wtautological-pointer-compare" + /* 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_ASSERT_NOT_NULL( @@ -187,6 +189,7 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE; ); #endif + /* Custom allocator must include allocate and free */ const Stack_Allocator_allocate _Stack_Allocator_allocate = _CONFIGURE_ASSERT_NOT_NULL( Stack_Allocator_allocate, @@ -200,11 +203,24 @@ const uintptr_t _Stack_Space_size = _CONFIGURE_STACK_SPACE_SIZE; ); #pragma GCC diagnostic pop + +/* + * Must provide both a custom stack allocator and deallocator + */ #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" #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; +#endif + #ifdef CONFIGURE_DIRTY_MEMORY RTEMS_SYSINIT_ITEM( _Memory_Dirty_free_areas, diff --git a/cpukit/include/rtems/config.h b/cpukit/include/rtems/config.h index afcee4381b..7b15bc34a2 100644 --- a/cpukit/include/rtems/config.h +++ b/cpukit/include/rtems/config.h @@ -368,6 +368,18 @@ uint32_t rtems_configuration_get_maximum_extensions( void ); */ #define rtems_configuration_get_stack_free_hook() _Stack_Allocator_free +/** + * @ingroup RTEMSAPIConfig + * + * @brief Gets the IDLE thread stack allocator hook configured for this + * application. + * + * @return Returns the IDLE thread stack allocator hook configured for this + * application. + */ +#define rtems_configuration_get_stack_allocate_for_idle_hook() \ + (_Stack_Allocator_allocate_for_idle) + /* Generated from spec:/rtems/config/if/get-stack-space-size */ /** diff --git a/cpukit/include/rtems/score/stack.h b/cpukit/include/rtems/score/stack.h index 23421cf7ae..ffa6368ba5 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 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. * * Application provided via <rtems/confdefs.h>. @@ -130,6 +147,13 @@ extern const Stack_Allocator_free _Stack_Allocator_free; void _Stack_Allocator_do_initialize( void ); /** @} */ +/** + * @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/stackallocatorforidle.c b/cpukit/score/src/stackallocatorforidle.c new file mode 100644 index 0000000000..7c4fd10c7d --- /dev/null +++ b/cpukit/score/src/stackallocatorforidle.c @@ -0,0 +1,59 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2021 OAR Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/score/stack.h> +#include <rtems/score/thread.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. + * + * The default allocator for IDLE thread stacks gets the memory from a + * statically allocated area provided via confdefs.h. + * + * @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. + * + * @retval NULL Not enough memory (never returned). + * @retval other Pointer to begin of stack area. + */ +static void *_Stack_Allocator_allocate_for_idle_default( + uint32_t cpu, + size_t stack_size +) +{ + return &_Thread_Idle_stacks[ cpu * stack_size ]; +} + +const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle = + _Stack_Allocator_allocate_for_idle_default; diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c index f5ffc9bad8..86e117e70f 100644 --- a/cpukit/score/src/threadcreateidle.c +++ b/cpukit/score/src/threadcreateidle.c @@ -49,9 +49,15 @@ 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 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)( + _Per_CPU_Get_index( cpu ), + config.stack_size + ); /* * The entire workspace is zeroed during its initialization. Thus, all diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index c0f8f6d670..68f3d448cc 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -1527,6 +1527,7 @@ source: - cpukit/score/src/semaphore.c - cpukit/score/src/smpbarrierwait.c - cpukit/score/src/stackallocator.c +- cpukit/score/src/stackallocatorforidle.c - cpukit/score/src/stackallocatorfree.c - cpukit/score/src/stackallocatorinit.c - cpukit/score/src/thread.c diff --git a/spec/build/testsuites/sptests/grp.yml b/spec/build/testsuites/sptests/grp.yml index d3cd53fb4a..6b16c115ba 100644 --- a/spec/build/testsuites/sptests/grp.yml +++ b/spec/build/testsuites/sptests/grp.yml @@ -396,6 +396,10 @@ links: - role: build-dependency uid: spstkalloc02 - role: build-dependency + uid: spstkalloc03 +- role: build-dependency + uid: spstkalloc04 +- role: build-dependency uid: spsysinit01 - role: build-dependency uid: spsyslock01 diff --git a/spec/build/testsuites/sptests/spstkalloc03.yml b/spec/build/testsuites/sptests/spstkalloc03.yml new file mode 100644 index 0000000000..fbdb91bd6f --- /dev/null +++ b/spec/build/testsuites/sptests/spstkalloc03.yml @@ -0,0 +1,19 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2030 embedded brains GmbH (http://www.embedded-brains.de) +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/sptests/spstkalloc03/init.c +stlib: [] +target: testsuites/sptests/spstkalloc03.exe +type: build +use-after: [] +use-before: [] diff --git a/spec/build/testsuites/sptests/spstkalloc04.yml b/spec/build/testsuites/sptests/spstkalloc04.yml new file mode 100644 index 0000000000..64340ed8f7 --- /dev/null +++ b/spec/build/testsuites/sptests/spstkalloc04.yml @@ -0,0 +1,19 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2040 embedded brains GmbH (http://www.embedded-brains.de) +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/sptests/spstkalloc04/init.c +stlib: [] +target: testsuites/sptests/spstkalloc04.exe +type: build +use-after: [] +use-before: [] diff --git a/testsuites/sptests/spstkalloc03/init.c b/testsuites/sptests/spstkalloc03/init.c new file mode 100644 index 0000000000..348afe7328 --- /dev/null +++ b/testsuites/sptests/spstkalloc03/init.c @@ -0,0 +1,103 @@ +/* + * COPYRIGHT (c) 2021. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <tmacros.h> + +#include <rtems/score/percpu.h> + +const char rtems_test_name[] = "SPSTKALLOC 3"; + +static int thread_stacks_count = 0xff; + +static rtems_task Init( + rtems_task_argument ignored +) +{ + rtems_print_printer_fprintf_putc(&rtems_test_printer); + TEST_BEGIN(); + rtems_test_assert(thread_stacks_count == 2); + TEST_END(); + rtems_test_exit( 0 ); +} + +static uint8_t stack_memory[RTEMS_MINIMUM_STACK_SIZE * 4]; + +static int stack_offset_next; + +static void *allocate_helper(size_t size) +{ + size_t next; + void *alloc; + + next = stack_offset_next + size; + rtems_test_assert( next < sizeof(stack_memory) ); + + alloc = &stack_memory[stack_offset_next]; + stack_offset_next = next; + return alloc; +} + +static void thread_stacks_initialize(size_t stack_space_size) +{ + rtems_test_assert(thread_stacks_count == 0xff); + thread_stacks_count = 0; +} + +static void *thread_stacks_allocate(size_t stack_size) +{ + rtems_test_assert(thread_stacks_count == 1); + thread_stacks_count++; + return allocate_helper(stack_size); +} + +static void thread_stacks_free(void *addr) +{ + rtems_test_assert(false); +} + +static void *thread_stacks_allocate_for_idle( + uint32_t cpu, + size_t stack_size +) +{ + rtems_test_assert(thread_stacks_count == 0); + thread_stacks_count++; + return allocate_helper(stack_size); +} + +/* + * Configure the thread stack allocators to not use the workspace. This should + * eliminate all uses of the Workspace for most BSPs. + */ +#define CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE +#define CONFIGURE_TASK_STACK_ALLOCATOR_INIT thread_stacks_initialize +#define CONFIGURE_TASK_STACK_ALLOCATOR thread_stacks_allocate +#define CONFIGURE_TASK_STACK_DEALLOCATOR thread_stacks_free +#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE thread_stacks_allocate_for_idle + + +/* NOTICE: the clock driver is explicitly disabled */ +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 1 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> diff --git a/testsuites/sptests/spstkalloc03/spstkalloc03.doc b/testsuites/sptests/spstkalloc03/spstkalloc03.doc new file mode 100644 index 0000000000..797716b623 --- /dev/null +++ b/testsuites/sptests/spstkalloc03/spstkalloc03.doc @@ -0,0 +1,19 @@ +# COPYRIGHT (c) 2021. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.org/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: spstkalloc03 + +directives: + +concepts: + ++ Ensure that the task stack allocator including IDLE thread + stack allocator works. + diff --git a/testsuites/sptests/spstkalloc03/spstkalloc03.scn b/testsuites/sptests/spstkalloc03/spstkalloc03.scn new file mode 100644 index 0000000000..45c67ef1fb --- /dev/null +++ b/testsuites/sptests/spstkalloc03/spstkalloc03.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST SPSTKALLOC 3 *** +*** END OF TEST SPSTKALLOC 3 *** diff --git a/testsuites/sptests/spstkalloc04/init.c b/testsuites/sptests/spstkalloc04/init.c new file mode 100644 index 0000000000..16f4ec65ca --- /dev/null +++ b/testsuites/sptests/spstkalloc04/init.c @@ -0,0 +1,82 @@ +/* + * COPYRIGHT (c) 2021. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <tmacros.h> + +#include <rtems/score/percpu.h> + +const char rtems_test_name[] = "SPSTKALLOC 4"; + +static int thread_stacks_count = 0; + +static rtems_task Init( + rtems_task_argument ignored +) +{ + rtems_print_printer_fprintf_putc(&rtems_test_printer); + TEST_BEGIN(); + rtems_test_assert(thread_stacks_count == 1); + TEST_END(); + rtems_test_exit( 0 ); +} + +static uint8_t stack_memory[RTEMS_MINIMUM_STACK_SIZE * 4]; + +static int stack_offset_next; + +static void *allocate_helper(size_t size) +{ + size_t next; + void *alloc; + + next = stack_offset_next + size; + rtems_test_assert( next < sizeof(stack_memory) ); + + alloc = &stack_memory[stack_offset_next]; + stack_offset_next = next; + return alloc; +} + +static void *thread_stacks_allocate_for_idle( + uint32_t cpu, + size_t stack_size +) +{ + rtems_test_assert(thread_stacks_count == 0); + thread_stacks_count++; + return allocate_helper(stack_size); +} + +/* + * Configure the IDLE thread stack allocators. This is a special + * case where there is an IDLE thread stack allocator but no custom + * allocator set for other threads. + */ +#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE thread_stacks_allocate_for_idle + + +/* NOTICE: the clock driver is explicitly disabled */ +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 1 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_INIT +#include <rtems/confdefs.h> diff --git a/testsuites/sptests/spstkalloc04/spstkalloc04.doc b/testsuites/sptests/spstkalloc04/spstkalloc04.doc new file mode 100644 index 0000000000..a1ed5b22cb --- /dev/null +++ b/testsuites/sptests/spstkalloc04/spstkalloc04.doc @@ -0,0 +1,20 @@ +# COPYRIGHT (c) 2021. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.org/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: spstkalloc04 + +directives: + +concepts: + ++ Ensure that the task stack allocator including IDLE thread + stack allocator works when a custom allocator is NOT provided + for other threads. + diff --git a/testsuites/sptests/spstkalloc04/spstkalloc04.scn b/testsuites/sptests/spstkalloc04/spstkalloc04.scn new file mode 100644 index 0000000000..f0919ec2d4 --- /dev/null +++ b/testsuites/sptests/spstkalloc04/spstkalloc04.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST SPSTKALLOC 4 *** +*** END OF TEST SPSTKALLOC 4 *** |