config: CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE

In order to better support applications which use the new
rtems_task_construct() directive add the
CONFIGURE_INIT_TASK_CONSTURCT_STORAGE_SIZE configuration option.  If
this option is specified, then the Classic API initialization task is
constructed with rtems_task_construct().

Update #4181.
This commit is contained in:
Sebastian Huber
2020-11-19 16:07:04 +01:00
parent bc175a1cab
commit 657e30c135
14 changed files with 318 additions and 15 deletions

View File

@@ -790,6 +790,7 @@ librtemscpu_a_SOURCES += rtems/src/statustoerrno.c
librtemscpu_a_SOURCES += rtems/src/systemeventreceive.c
librtemscpu_a_SOURCES += rtems/src/systemeventsend.c
librtemscpu_a_SOURCES += rtems/src/taskconstruct.c
librtemscpu_a_SOURCES += rtems/src/taskconstructuser.c
librtemscpu_a_SOURCES += rtems/src/taskcreate.c
librtemscpu_a_SOURCES += rtems/src/taskdelete.c
librtemscpu_a_SOURCES += rtems/src/taskexit.c

View File

@@ -1048,6 +1048,58 @@
*/
#define CONFIGURE_INIT_TASK_ATTRIBUTES
/* Generated from spec:/acfg/if/init-task-construct-storage-size */
/**
* @brief This configuration option is an integer define.
*
* The value of this configuration option defines the task storage size of the
* Classic API initialization task.
*
* @par Default Value
* The default value is 0.
*
* @par Value Constraints
* @parblock
* The value of this configuration option shall satisfy all of the following
* constraints:
*
* * It shall be greater than or equal to #CONFIGURE_MINIMUM_TASK_STACK_SIZE.
*
* * It shall be defined using RTEMS_TASK_STORAGE_SIZE().
* @endparblock
*
* @par Notes
* @parblock
* If this configuration option is specified, then
*
* * a task storage area of the specified size is statically allocated by
* ``<rtems/confdefs.h>`` for the Classic API initialization task,
*
* * the Classic API initialization task is constructed by
* rtems_task_construct() instead of using rtems_task_create(),
*
* * the maximum thread-local storage size defined by
* #CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE is used for the Classic API
* initialization task,
*
* * the Classic API initialization task should be accounted for in
* #CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE, and
*
* * the task storage area used for the Classic API initialization task is not
* reclaimed by the system, if the task is deleted.
*
* The
*
* * #CONFIGURE_INIT_TASK_STACK_SIZE and
*
* * ``CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE``
*
* configuration options are mutually exclusive.
* @endparblock
*/
#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE
/* Generated from spec:/acfg/if/init-task-entrypoint */
/**
@@ -1145,6 +1197,17 @@
* out by ``<rtems/confdefs.h>`` does not overflow an integer of type <a
* href="https://en.cppreference.com/w/c/types/integer">uintptr_t</a>.
* @endparblock
*
* @par Notes
* @parblock
* The
*
* * ``CONFIGURE_INIT_TASK_STACK_SIZE`` and
*
* * #CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE
*
* configuration options are mutually exclusive.
* @endparblock
*/
#define CONFIGURE_INIT_TASK_STACK_SIZE

View File

@@ -48,6 +48,7 @@
#ifdef CONFIGURE_RTEMS_INIT_TASKS_TABLE
#include <rtems/confdefs/percpu.h>
#include <rtems/confdefs/threads.h>
#include <rtems/rtems/object.h>
#include <rtems/rtems/tasksdata.h>
#include <rtems/sysinit.h>
@@ -72,15 +73,6 @@
#define CONFIGURE_INIT_TASK_PRIORITY 1
#endif
#ifndef CONFIGURE_INIT_TASK_STACK_SIZE
#define CONFIGURE_INIT_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE
#endif
#if CONFIGURE_INIT_TASK_STACK_SIZE > CONFIGURE_MINIMUM_TASK_STACK_SIZE
#define _CONFIGURE_INIT_TASK_STACK_EXTRA \
( CONFIGURE_INIT_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE )
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -121,6 +113,52 @@ RTEMS_STATIC_ASSERT(
#pragma GCC diagnostic pop
#ifdef CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE
#ifdef CONFIGURE_INIT_TASK_STACK_SIZE
#error "CONFIGURE_INIT_TASK_STACK_SIZE and CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE are mutually exclusive"
#endif
RTEMS_STATIC_ASSERT(
CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE >= CONFIGURE_MINIMUM_TASK_STACK_SIZE,
CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE_IS_TOO_SMALL
);
RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT )
static char _RTEMS_tasks_User_task_storage[ CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE ];
const RTEMS_tasks_User_task_config _RTEMS_tasks_User_task_config = {
{
CONFIGURE_INIT_TASK_NAME,
CONFIGURE_INIT_TASK_PRIORITY,
_RTEMS_tasks_User_task_storage,
sizeof( _RTEMS_tasks_User_task_storage ),
CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE,
NULL,
CONFIGURE_INIT_TASK_INITIAL_MODES,
CONFIGURE_INIT_TASK_ATTRIBUTES,
},
CONFIGURE_INIT_TASK_ENTRY_POINT,
CONFIGURE_INIT_TASK_ARGUMENTS
};
RTEMS_SYSINIT_ITEM(
_RTEMS_tasks_Construct_user_task,
RTEMS_SYSINIT_CLASSIC_USER_TASKS,
RTEMS_SYSINIT_ORDER_MIDDLE
);
#else /* CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE */
#ifndef CONFIGURE_INIT_TASK_STACK_SIZE
#define CONFIGURE_INIT_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE
#endif
#if CONFIGURE_INIT_TASK_STACK_SIZE > CONFIGURE_MINIMUM_TASK_STACK_SIZE
#define _CONFIGURE_INIT_TASK_STACK_EXTRA \
( CONFIGURE_INIT_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE )
#endif
const rtems_initialization_tasks_table _RTEMS_tasks_User_task_table = {
CONFIGURE_INIT_TASK_NAME,
CONFIGURE_INIT_TASK_STACK_SIZE,
@@ -137,6 +175,8 @@ RTEMS_SYSINIT_ITEM(
RTEMS_SYSINIT_ORDER_MIDDLE
);
#endif /* CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE */
#ifdef __cplusplus
}
#endif

View File

@@ -61,10 +61,49 @@ typedef struct {
extern const rtems_initialization_tasks_table _RTEMS_tasks_User_task_table;
/**
* @brief System initialization handler to create and start the first user
* task.
* @brief Creates and starts the Classic API initialization task using
* rtems_task_create() and the configuration provided by
* ::_RTEMS_tasks_User_task_table.
*/
extern void _RTEMS_tasks_Initialize_user_task( void );
void _RTEMS_tasks_Initialize_user_task( void );
/**
* @brief This structure provides the configuration to construct and start the
* Classic API initialization task.
*/
typedef struct {
/**
* @brief This member provides the task configuration for
* rtems_task_construct().
*/
rtems_task_config config;
/**
* @brief This member provides the task entry point for rtems_task_start().
*/
rtems_task_entry entry_point;
/**
* @brief This member provides the task argument for rtems_task_start().
*/
rtems_task_argument argument;
} RTEMS_tasks_User_task_config;
/**
* @brief This structure provides the configuration of the Classic API
* initialization task.
*
* It is used by _RTEMS_tasks_Construct_user_task() and initialized via
* <rtems/confdefs.h>, see also #CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE.
*/
extern const RTEMS_tasks_User_task_config _RTEMS_tasks_User_task_config;
/**
* @brief Constructs and starts the Classic API initialization task using
* rtems_task_construct() and the configuration provided by
* ::_RTEMS_tasks_User_task_config.
*/
void _RTEMS_tasks_Construct_user_task( void );
/**
* The following instantiates the information control block used to

View File

@@ -204,7 +204,8 @@ typedef enum {
INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT = 38,
INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL = 39,
INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA = 40,
INTERNAL_ERROR_TOO_LARGE_TLS_SIZE = 41
INTERNAL_ERROR_TOO_LARGE_TLS_SIZE = 41,
INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED = 42,
} Internal_errors_Core_list;
typedef CPU_Uint32ptr Internal_errors_t;

View File

@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup ClassicTasks
*
* @brief This source file contains the implementation of
* _RTEMS_tasks_Construct_user_task().
*/
/*
* Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
*
* 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/rtems/tasksimpl.h>
#include <rtems/score/assert.h>
#include <rtems/score/threadimpl.h>
#include <rtems/score/interr.h>
void _RTEMS_tasks_Construct_user_task( void )
{
const RTEMS_tasks_User_task_config *config;
rtems_status_code status;
rtems_id id;
config = &_RTEMS_tasks_User_task_config;
status = rtems_task_construct( &config->config, &id );
if ( status != RTEMS_SUCCESSFUL ) {
_Internal_error( INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED );
}
status = rtems_task_start( id, config->entry_point, config->argument );
_Assert( status == RTEMS_SUCCESSFUL );
(void) status;
_Assert( _Thread_Global_constructor == 0 );
_Thread_Global_constructor = id;
}

View File

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

View File

@@ -1284,6 +1284,7 @@ source:
- cpukit/rtems/src/systemeventreceive.c
- cpukit/rtems/src/systemeventsend.c
- cpukit/rtems/src/taskconstruct.c
- cpukit/rtems/src/taskconstructuser.c
- cpukit/rtems/src/taskcreate.c
- cpukit/rtems/src/taskdelete.c
- cpukit/rtems/src/taskexit.c

View File

@@ -254,6 +254,8 @@ links:
uid: spfatal32
- role: build-dependency
uid: spfatal33
- role: build-dependency
uid: spfatal34
- 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) 2020 embedded brains GmbH (http://www.embedded-brains.de)
cppflags: []
cxxflags: []
enabled-by: true
features: c cprogram
includes: []
ldflags: []
links: []
source:
- testsuites/sptests/spfatal34/init.c
stlib: []
target: testsuites/sptests/spfatal34.exe
type: build
use-after: []
use-before: []

View File

@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
*
* 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"
#define FATAL_ERROR_TEST_NAME "34"
#define FATAL_ERROR_DESCRIPTION "Classic API Init task construct failure"
#define FATAL_ERROR_EXPECTED_SOURCE INTERNAL_ERROR_CORE
#define FATAL_ERROR_EXPECTED_ERROR \
INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED
#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
#define CONFIGURE_INIT_TASK_PRIORITY 0
static void force_error( void )
{
RTEMS_UNREACHABLE();
}
#include "../spfatal_support/spfatalimpl.h"

View File

@@ -0,0 +1,11 @@
This file describes the directives and concepts tested by this test set.
test set name: spfatal34
directives:
- _RTEMS_tasks_Construct_user_task()
concepts:
- Provoke a Classic API initialization task construct failure.

View File

@@ -0,0 +1,8 @@
*** BEGIN OF TEST SPFATAL 34 ***
*** TEST VERSION: 6.0.0.be2dc00ae7b5db5381da49a3ec42f2088fa66bc9
*** TEST STATE: EXPECTED_PASS
*** TEST BUILD:
*** TEST TOOLS: 10.2.1 20200918 (RTEMS 6, RSB 3ce72f014292bbb4e6b3bab9ede9e0b4a71ef5a8, Newlib 749cbcc)
Fatal error (Classic API Init task construct failure) hit
*** END OF TEST SPFATAL 34 ***

View File

@@ -36,7 +36,7 @@ static void test_internal_error_text(void)
} while ( text != text_last );
rtems_test_assert(
error - 3 == INTERNAL_ERROR_TOO_LARGE_TLS_SIZE
error - 3 == INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED
);
}