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.
This commit is contained in:
Sebastian Huber
2022-09-30 08:06:18 +02:00
parent 6a8208533d
commit 45ee958552
26 changed files with 419 additions and 80 deletions

View File

@@ -3431,6 +3431,59 @@
*/
#define CONFIGURE_IDLE_TASK_STACK_SIZE
/* Generated from spec:/acfg/if/idle-task-storage-size */
/**
* @brief This configuration option is an integer define.
*
* If this configuration option is specified, then the task storage areas for
* the IDLE tasks are statically allocated by <rtems/confdefs.h>. The value of
* this configuration option defines the size in bytes of the task storage area
* of each IDLE task in the system.
*
* @par Default Value
* This configuration option has no default value. If it is not specified,
* then the task storage area for each IDLE task will allocated from the RTEMS
* Workspace or through a custom IDLE task stack allocator.
*
* @par Constraints
* The value of the configuration option shall be greater than or equal to
* #CONFIGURE_IDLE_TASK_STACK_SIZE.
*
* @par Notes
* @parblock
* By default, the IDLE task storage areas are allocated from the RTEMS
* Workspace. Applications which do not want to use a heap allocator can use
* this configuration option to use statically allocated memory for the IDLE
* task storage areas. The task storage area contains the task stack, the
* thread-local storage, and the floating-point context on architectures with a
* separate floating-point context. The size of the thread-local storage area
* is defined at link time or by the
* #CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE configuration option. You have
* to estimate the actual thread-local storage size if you want to use this
* configuration option. If the IDLE task stack size would be less than the
* value defined by the #CONFIGURE_IDLE_TASK_STACK_SIZE configuration option,
* for example because the thread-local storage size is larger than expected,
* then the system terminates with the INTERNAL_ERROR_CORE fatal source and the
* INTERNAL_ERROR_IDLE_THREAD_STACK_TOO_SMALL fatal code during system
* initialization.
*
* The value of this configuration option is passed to
* RTEMS_TASK_STORAGE_SIZE() by <rtems/confdefs.h> to determine the actual size
* of the statically allocated area to take architecture-specific overheads
* into account.
*
* The
*
* * ``CONFIGURE_IDLE_TASK_STORAGE_SIZE``, and
*
* * #CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE
*
* configuration options are mutually exclusive.
* @endparblock
*/
#define CONFIGURE_IDLE_TASK_STORAGE_SIZE
/** @} */
/* Generated from spec:/acfg/if/group-mpci */
@@ -4826,23 +4879,45 @@
* @brief This configuration option is an initializer define.
*
* The value of this configuration option is the address for the stack
* allocator allocate handler used to allocate the task stack of each IDLE
* task.
* allocator allocate handler used to allocate the task storage area of each
* IDLE task.
*
* @par Default Value
* The default value is ``_Stack_Allocator_allocate_for_idle_default``, which
* indicates that IDLE task stacks will be allocated from an area statically
* allocated by ``<rtems/confdefs.h>``.
* By default, the IDLE task storage area will be allocated from the RTEMS
* Workspace.
*
* @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 * )``.
* @parblock
* The following constraints apply to this configuration option:
*
* * The value of the configuration option shall be defined to a valid function
* pointer of the type ``void *( *allocate )( uint32_t, size_t * )``.
*
* * The IDLE task stack allocator shall return a pointer to the allocated
* memory area or terminate the system with a fatal error if the allocation
* request cannot be satisfied.
*
* * The IDLE task stack allocator may increase the size of the allocated
* memory area.
* @endparblock
*
* @par Notes
* @parblock
* This configuration option is independent of the other thread stack allocator
* configuration options. It is assumed that any memory allocated for the
* stack of an IDLE task will not be from the RTEMS Workspace or the memory
* statically allocated by default.
* configuration options. It is assumed that any memory allocated for the task
* storage area of an IDLE task will not be from the RTEMS Workspace.
*
* The IDLE task stack allocator may increase the size of the allocated memory
* area to account for the actually allocated memory area.
*
* The
*
* * #CONFIGURE_IDLE_TASK_STORAGE_SIZE, and
*
* * ``CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE``
*
* configuration options are mutually exclusive.
* @endparblock
*/
#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE

View File

@@ -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"

View File

@@ -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 );

View File

@@ -47,6 +47,7 @@
#include <rtems/confdefs/inittask.h>
#include <rtems/confdefs/initthread.h>
#include <rtems/confdefs/objectsposix.h>
#include <rtems/confdefs/percpu.h>
#include <rtems/confdefs/threads.h>
#include <rtems/confdefs/wkspacesupport.h>
#include <rtems/score/coremsg.h>
@@ -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,

View File

@@ -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;

View File

@@ -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 <rtems/confdefs.h>.
*/
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 <rtems/confdefs.h>.
*/
extern char _Stack_Allocator_allocate_for_idle_storage_areas[];
/**
* @brief Allocates the IDLE thread storage from the memory statically
* allocated by <rtems/confdefs.h>.
*
* @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

View File

@@ -1186,13 +1186,6 @@ Thread_Information name##_Information = { \
} \
}
/**
* @brief The idle thread stacks.
*
* Provided by the application via <rtems/confdefs.h>.
*/
extern char _Thread_Idle_stacks[];
#if defined(RTEMS_MULTIPROCESSING)
/**
* @brief The configured thread control block.

View File

@@ -84,7 +84,8 @@ static const char *const internal_error_text[] = {
"INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA",
"INTERNAL_ERROR_TOO_LARGE_TLS_SIZE",
"INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED",
"INTERNAL_ERROR_IDLE_THREAD_CREATE_FAILED"
"INTERNAL_ERROR_IDLE_THREAD_CREATE_FAILED",
"INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STORAGE"
};
const char *rtems_internal_error_text( rtems_fatal_code error )

View File

@@ -1,6 +1,15 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSScoreStack
*
* @brief This source file contains the implementation of
* _Stack_Allocator_allocate_for_idle_static().
*/
/*
* Copyright (C) 2021 On-Line Applications Research Corporation (OAR)
*
* Redistribution and use in source and binary forms, with or without
@@ -30,35 +39,21 @@
#endif
#include <rtems/score/stack.h>
#include <rtems/score/thread.h>
#include <rtems/score/assert.h>
/**
* @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 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.
*
* @return Returns the pointer to begin of the allocated stack area.
*/
static void *_Stack_Allocator_allocate_for_idle_default(
void *_Stack_Allocator_allocate_for_idle_static(
uint32_t cpu_index,
size_t *stack_size
size_t *storage_size
)
{
size_t size;
size = _Stack_Allocator_allocate_for_idle_storage_size;
*storage_size = size;
#if defined(RTEMS_SMP)
return &_Thread_Idle_stacks[ cpu_index * ( *stack_size ) ];
return &_Stack_Allocator_allocate_for_idle_storage_areas[ cpu_index * size ];
#else
_Assert( cpu_index == 0 );
return &_Thread_Idle_stacks[ 0 ];
return &_Stack_Allocator_allocate_for_idle_storage_areas[ 0 ];
#endif
}
const Stack_Allocator_allocate_for_idle _Stack_Allocator_allocate_for_idle =
_Stack_Allocator_allocate_for_idle_default;

View File

@@ -0,0 +1,60 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSScoreStack
*
* @brief This source file contains the implementation of
* _Stack_Allocator_allocate_for_idle_workspace().
*/
/*
* Copyright (C) 2022 embedded brains GmbH
*
* 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/interr.h>
#include <rtems/score/wkspace.h>
void *_Stack_Allocator_allocate_for_idle_workspace(
uint32_t unused,
size_t *storage_size
)
{
void *area;
(void) unused;
area = _Workspace_Allocate( *storage_size );
if ( area == NULL ) {
_Internal_error( INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STORAGE );
}
return area;
}

View File

@@ -53,7 +53,10 @@
#include <string.h>
static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
static void _Thread_Create_idle_for_CPU(
Per_CPU_Control *cpu,
uintptr_t storage_size
)
{
Thread_Configuration config;
Thread_Control *idle;
@@ -70,8 +73,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
config.is_fp = CPU_IDLE_TASK_IS_FP;
config.is_preemptible = true;
config.stack_free = _Objects_Free_nothing;
config.stack_size = _Thread_Idle_stack_size
+ CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE;
config.stack_size = storage_size;
/*
* The IDLE thread stacks may be statically allocated or there may be a
@@ -118,21 +120,28 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
void _Thread_Create_idle( void )
{
uintptr_t storage_size;
#if defined(RTEMS_SMP)
uint32_t cpu_max;
uint32_t cpu_index;
uint32_t cpu_max;
uint32_t cpu_index;
#endif
storage_size = _TLS_Get_allocation_size() +
CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE +
_Thread_Idle_stack_size;
#if defined(RTEMS_SMP)
cpu_max = _SMP_Get_processor_maximum();
for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) {
Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
if ( _Per_CPU_Is_processor_online( cpu ) ) {
_Thread_Create_idle_for_CPU( cpu );
_Thread_Create_idle_for_CPU( cpu, storage_size );
}
}
#else
_Thread_Create_idle_for_CPU( _Per_CPU_Get() );
_Thread_Create_idle_for_CPU( _Per_CPU_Get(), storage_size );
#endif
_CPU_Use_thread_local_storage(

View File

@@ -1545,6 +1545,7 @@ source:
- cpukit/score/src/smpbarrierwait.c
- cpukit/score/src/stackallocator.c
- cpukit/score/src/stackallocatorforidle.c
- cpukit/score/src/stackallocatorforidlewkspace.c
- cpukit/score/src/stackallocatorfree.c
- cpukit/score/src/stackallocatorinit.c
- cpukit/score/src/thread.c

View File

@@ -258,6 +258,8 @@ links:
uid: spfatal34
- role: build-dependency
uid: spfatal35
- role: build-dependency
uid: spfatal36
- role: build-dependency
uid: spfifo01
- role: build-dependency

View File

@@ -0,0 +1,19 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
build-type: test-program
cflags: []
copyrights:
- Copyright (C) 2022 embedded brains GmbH
cppflags: []
cxxflags: []
enabled-by: true
features: c cprogram
includes: []
ldflags: []
links: []
source:
- testsuites/sptests/spfatal36/init.c
stlib: []
target: testsuites/sptests/spfatal36.exe
type: build
use-after: []
use-before: []

View File

@@ -0,0 +1,63 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2022 embedded brains GmbH
*
* 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 "../spfatal_support/spfatal.h"
#include <rtems/sysinit.h>
#include <rtems/score/heapimpl.h>
#include <rtems/score/wkspace.h>
#define FATAL_ERROR_TEST_NAME "36"
#define FATAL_ERROR_DESCRIPTION "failure in idle task storage allocation"
#define FATAL_ERROR_EXPECTED_SOURCE INTERNAL_ERROR_CORE
#define FATAL_ERROR_EXPECTED_ERROR \
INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STORAGE
static void force_error( void )
{
RTEMS_UNREACHABLE();
}
static void empty_workspace( void )
{
(void) _Heap_Greedy_allocate( &_Workspace_Area, NULL, 0 );
}
RTEMS_SYSINIT_ITEM(
empty_workspace,
RTEMS_SYSINIT_IDLE_THREADS,
RTEMS_SYSINIT_ORDER_FIRST
);
#include "../spfatal_support/spfatalimpl.h"

View File

@@ -0,0 +1,11 @@
This file describes the concepts tested by this test set.
test set name: spfatal36
directives:
- _Stack_Allocator_allocate_for_idle_workspace()
concepts:
- Provoke a memory allocation failure in the directive.

View File

@@ -49,7 +49,7 @@ static void test_internal_error_text(void)
} while ( text != text_last );
rtems_test_assert(
error - 3 == INTERNAL_ERROR_IDLE_THREAD_CREATE_FAILED
error - 3 == INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STORAGE
);
}

View File

@@ -44,6 +44,7 @@ const char rtems_test_name[] = "SPSTKALLOC 2";
#include <stdio.h>
#include <inttypes.h>
#include <rtems/malloc.h>
#include <rtems/score/heapimpl.h>
#define TASK_COUNT 5
@@ -56,6 +57,8 @@ static void task_stack_init(size_t stack_space_size);
static void *task_stack_allocate(size_t stack_size);
static void *task_stack_allocate_for_idle(uint32_t unused, size_t *stack_size);
static void task_stack_free(void *addr);
static void print_info(void)
@@ -149,6 +152,7 @@ static rtems_task Init(rtems_task_argument argument)
#define CONFIGURE_TASK_STACK_ALLOCATOR_INIT task_stack_init
#define CONFIGURE_TASK_STACK_ALLOCATOR task_stack_allocate
#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE task_stack_allocate_for_idle
#define CONFIGURE_TASK_STACK_DEALLOCATOR task_stack_free
#define CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE
#define CONFIGURE_TASK_STACK_FROM_ALLOCATOR(stack_size) \
@@ -183,6 +187,15 @@ static void *task_stack_allocate(size_t stack_size)
return _Heap_Allocate(&task_stack_heap, stack_size);
}
static void *task_stack_allocate_for_idle(uint32_t unused, size_t *stack_size)
{
return rtems_heap_allocate_aligned_with_boundary(
*stack_size,
CPU_STACK_ALIGNMENT,
0
);
}
static void task_stack_free(void *addr)
{
_Heap_Free(&task_stack_heap, addr);

View File

@@ -48,7 +48,7 @@ alignas(256) static thread_local long a256 = 256;
static thread_local long i0;
alignas(512) static thread_local long a512;
alignas(RTEMS_MINIMUM_STACK_SIZE) static thread_local long a;
int seven()
{
@@ -61,7 +61,7 @@ static void clobber()
i123 = 0xdead0001;
a256 = 0xdead0002;
i0 = 0xdead0003;
a512 = 0xdead0004;
a = 0xdead0004;
}
static long f456(bool clobber)
@@ -173,8 +173,8 @@ static void checkTLSValues()
RTEMS_OBFUSCATE_VARIABLE(addr);
rtems_test_assert((addr % 256) == 0);
rtems_test_assert(i0 == 0);
rtems_test_assert(a512 == 0);
addr = reinterpret_cast<uintptr_t>(&a512);
rtems_test_assert(a == 0);
addr = reinterpret_cast<uintptr_t>(&a);
RTEMS_OBFUSCATE_VARIABLE(addr);
rtems_test_assert((addr % 512) == 0);
rtems_test_assert(f456(false) == 456);

View File

@@ -317,7 +317,10 @@ RTEMS_SCHEDULER_PRIORITY( a, 64 );
#define CONFIGURE_IDLE_TASK_STACK_SIZE TEST_IDLE_STACK_SIZE
static char test_idle_stacks[ CONFIGURE_MAXIMUM_PROCESSORS ][
( TEST_IDLE_STACK_SIZE + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE )
RTEMS_ALIGN_UP(
MAX_TLS_SIZE + TEST_IDLE_STACK_SIZE + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE,
CPU_INTERRUPT_STACK_ALIGNMENT
)
]
RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
RTEMS_SECTION( ".rtemsstack.idle" );

View File

@@ -133,6 +133,8 @@ RTEMS_SYSINIT_ITEM(
{ .fatal = FatalInitialExtension }, \
{ .fatal = TestSuiteFatalExtension }
#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
#if !defined(CONFIGURE_RTEMS_INIT_TASKS_TABLE)
#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION

View File

@@ -72,6 +72,10 @@ static const T_config test_config = {
#define CONFIGURE_INITIAL_EXTENSIONS \
{ .fatal = FatalInitialExtension }
#ifndef CONFIGURE_IDLE_TASK_STORAGE_SIZE
#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
#endif
#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
void *IdleBody( uintptr_t ignored )

View File

@@ -72,6 +72,8 @@
const char rtems_test_name[] = "ValidationAcfg0";
#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
void *IdleBody( uintptr_t ignored )

View File

@@ -94,6 +94,8 @@ static void Init( rtems_task_argument arg )
#define CONFIGURE_DISABLE_BSP_SETTINGS
#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE

View File

@@ -138,6 +138,8 @@ static void *IdleBody( uintptr_t ignored )
#define CONFIGURE_SCHEDULER_TABLE_ENTRIES { }
#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
#define CONFIGURE_IDLE_TASK_BODY IdleBody

View File

@@ -68,6 +68,9 @@
const char rtems_test_name[] = "ValidationTls1";
#define CONFIGURE_IDLE_TASK_STORAGE_SIZE \
( RTEMS_MINIMUM_STACK_SIZE + 4096 )
#include "ts-idle.h"
/** @} */