diff options
-rw-r--r-- | cpukit/Makefile.am | 1 | ||||
-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 | 3 | ||||
-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-- | testsuites/sptests/Makefile.am | 18 | ||||
-rw-r--r-- | testsuites/sptests/configure.ac | 2 | ||||
-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 |
15 files changed, 373 insertions, 8 deletions
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am index 18eda95543..202cf3c346 100644 --- a/cpukit/Makefile.am +++ b/cpukit/Makefile.am @@ -930,6 +930,7 @@ librtemscpu_a_SOURCES += score/src/schedulercbssetparameters.c librtemscpu_a_SOURCES += score/src/schedulercbsreleasejob.c librtemscpu_a_SOURCES += score/src/schedulercbsunblock.c librtemscpu_a_SOURCES += score/src/stackallocator.c +librtemscpu_a_SOURCES += score/src/stackallocatorforidle.c librtemscpu_a_SOURCES += score/src/pheapallocate.c librtemscpu_a_SOURCES += score/src/pheapextend.c librtemscpu_a_SOURCES += score/src/pheapfree.c diff --git a/cpukit/include/rtems/confdefs/percpu.h b/cpukit/include/rtems/confdefs/percpu.h index f3a9a4f3e7..b7baebea05 100644 --- a/cpukit/include/rtems/confdefs/percpu.h +++ b/cpukit/include/rtems/confdefs/percpu.h @@ -133,11 +133,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 484dde20ea..9ef9d90b85 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,16 +147,30 @@ 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; + +/* + * 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 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..bad89e66fc 100644 --- a/cpukit/include/rtems/score/stack.h +++ b/cpukit/include/rtems/score/stack.h @@ -82,6 +82,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>. @@ -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/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 1e18ad07cc..e888aa111f 100644 --- a/cpukit/score/src/threadcreateidle.c +++ b/cpukit/score/src/threadcreateidle.c @@ -53,9 +53,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/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am index 62bb1aa685..1ea2501bd7 100644 --- a/testsuites/sptests/Makefile.am +++ b/testsuites/sptests/Makefile.am @@ -1783,6 +1783,24 @@ spstkalloc02_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_spstkalloc02) \ $(support_includes) endif +if TEST_spstkalloc03 +sp_tests += spstkalloc03 +sp_screens += spstkalloc03/spstkalloc03.scn +sp_docs += spstkalloc03/spstkalloc03.doc +spstkalloc03_SOURCES = spstkalloc03/init.c +spstkalloc03_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_spstkalloc03) \ + $(support_includes) +endif + +if TEST_spstkalloc04 +sp_tests += spstkalloc04 +sp_screens += spstkalloc04/spstkalloc04.scn +sp_docs += spstkalloc04/spstkalloc04.doc +spstkalloc04_SOURCES = spstkalloc04/init.c +spstkalloc04_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_spstkalloc04) \ + $(support_includes) +endif + if TEST_spsysinit01 sp_tests += spsysinit01 sp_screens += spsysinit01/spsysinit01.scn diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac index 9476e3b0d7..24ff0383e6 100644 --- a/testsuites/sptests/configure.ac +++ b/testsuites/sptests/configure.ac @@ -228,6 +228,8 @@ RTEMS_TEST_CHECK([spsize]) RTEMS_TEST_CHECK([spstdthreads01]) RTEMS_TEST_CHECK([spstkalloc]) RTEMS_TEST_CHECK([spstkalloc02]) +RTEMS_TEST_CHECK([spstkalloc03]) +RTEMS_TEST_CHECK([spstkalloc04]) RTEMS_TEST_CHECK([spsysinit01]) RTEMS_TEST_CHECK([spsyslock01]) RTEMS_TEST_CHECK([sptask_err01]) 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 *** |