forked from Imagelibrary/rtems
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:
@@ -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
|
||||
* @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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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,14 +223,39 @@ 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_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;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIGURE_DIRTY_MEMORY
|
||||
RTEMS_SYSINIT_ITEM(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
|
||||
60
cpukit/score/src/stackallocatorforidlewkspace.c
Normal file
60
cpukit/score/src/stackallocatorforidlewkspace.c
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
#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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
19
spec/build/testsuites/sptests/spfatal36.yml
Normal file
19
spec/build/testsuites/sptests/spfatal36.yml
Normal 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: []
|
||||
63
testsuites/sptests/spfatal36/init.c
Normal file
63
testsuites/sptests/spfatal36/init.c
Normal 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"
|
||||
11
testsuites/sptests/spfatal36/spfatal36.doc
Normal file
11
testsuites/sptests/spfatal36/spfatal36.doc
Normal 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.
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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" );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
/** @} */
|
||||
|
||||
Reference in New Issue
Block a user