[PATCH 06/13] config: Add rtems_malloc_task_stack_for_idle()

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Sep 30 09:21:29 UTC 2022


Update #4524.
---
 cpukit/doxygen/appl-config.h                | 13 +++++
 cpukit/include/rtems/rtems/config.h         | 29 +++++++++-
 cpukit/include/rtems/score/interr.h         |  1 +
 cpukit/sapi/src/interrtext.c                |  3 +-
 cpukit/sapi/src/malloctaskstackforidle.c    | 59 +++++++++++++++++++++
 spec/build/cpukit/librtemscpu.yml           |  1 +
 spec/build/testsuites/sptests/grp.yml       |  2 +
 spec/build/testsuites/sptests/spfatal36.yml | 19 +++++++
 testsuites/sptests/spfatal36/init.c         | 52 ++++++++++++++++++
 testsuites/sptests/spfatal36/spfatal36.doc  | 11 ++++
 testsuites/sptests/spinternalerror02/init.c |  2 +-
 testsuites/sptests/sptls04/init.c           |  2 +
 12 files changed, 191 insertions(+), 3 deletions(-)
 create mode 100644 cpukit/sapi/src/malloctaskstackforidle.c
 create mode 100644 spec/build/testsuites/sptests/spfatal36.yml
 create mode 100644 testsuites/sptests/spfatal36/init.c
 create mode 100644 testsuites/sptests/spfatal36/spfatal36.doc

diff --git a/cpukit/doxygen/appl-config.h b/cpukit/doxygen/appl-config.h
index aa6dbae648..ee647dc961 100644
--- a/cpukit/doxygen/appl-config.h
+++ b/cpukit/doxygen/appl-config.h
@@ -4842,6 +4842,19 @@
  * 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.
+ *
+ * For applications with a thread-local storage size which is completely
+ * unknown at the time the application configuration is defined, RTEMS provides
+ * an IDLE task stack allocator which uses rtems_malloc().  The size of the
+ * allocated thread storage area is the sum of stack size defined by the
+ * #CONFIGURE_IDLE_TASK_STACK_SIZE configuration option and the actual
+ * thread-local storage size of the application.  Define this configuration
+ * option to ``rtems_malloc_task_stack_for_idle`` to use this allocator.  If
+ * the memory allocation fails, then the system terminates with the
+ * INTERNAL_ERROR_CORE fatal source and the
+ * INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STACK fatal code during system
+ * initialization.
+ * @endparblock
  */
 #define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE
 
diff --git a/cpukit/include/rtems/rtems/config.h b/cpukit/include/rtems/rtems/config.h
index 3d813c55b6..7c7f1e3aa3 100644
--- a/cpukit/include/rtems/rtems/config.h
+++ b/cpukit/include/rtems/rtems/config.h
@@ -10,7 +10,7 @@
  */
 
 /*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020, 2022 embedded brains GmbH (http://www.embedded-brains.de)
  * Copyright (C) 1989, 2008 On-Line Applications Research Corporation (OAR)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,7 @@
 #define _RTEMS_RTEMS_CONFIG_H
 
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
 #include <rtems/rtems/tasks.h>
 
@@ -328,6 +329,32 @@ uint32_t rtems_configuration_get_maximum_tasks( void );
  */
 uint32_t rtems_configuration_get_maximum_timers( void );
 
+/* Generated from spec:/rtems/config/if/malloc-task-stack-for-idle */
+
+/**
+ * @ingroup RTEMSAPIConfig
+ *
+ * @brief Allocates a thread storage area for an IDLE task using
+ *   rtems_malloc().
+ *
+ * @param unused is an unused parameter.
+ *
+ * @param[in,out] size is the pointer to an size_t object.  At function entry,
+ *   the object contains the size of the thread storage area not accounting for
+ *   the thread-local storage size.  When the directive call is successful, the
+ *   size of the allocated thread storage area will be stored in this object.
+ *
+ * The thread storage size is determined by the #CONFIGURE_IDLE_TASK_STACK_SIZE
+ * application configuration option and the actual thread-local storage size of
+ * the application.  The memory is allocated using rtems_malloc().
+ *
+ * @return Returns the begin address of the allocated thread storage area.
+ *
+ * @par Notes
+ * See #CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE.
+ */
+void *rtems_malloc_task_stack_for_idle( uint32_t unused, size_t *size );
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpukit/include/rtems/score/interr.h b/cpukit/include/rtems/score/interr.h
index ae4966d6d8..6e6926ab61 100644
--- a/cpukit/include/rtems/score/interr.h
+++ b/cpukit/include/rtems/score/interr.h
@@ -229,6 +229,7 @@ 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_NO_MEMORY_FOR_IDLE_TASK_STACK = 43
 } Internal_errors_Core_list;
 
 typedef CPU_Uint32ptr Internal_errors_t;
diff --git a/cpukit/sapi/src/interrtext.c b/cpukit/sapi/src/interrtext.c
index 383cc5bc0a..005cdc4508 100644
--- a/cpukit/sapi/src/interrtext.c
+++ b/cpukit/sapi/src/interrtext.c
@@ -83,7 +83,8 @@ static const char *const internal_error_text[] = {
   "INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL",
   "INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA",
   "INTERNAL_ERROR_TOO_LARGE_TLS_SIZE",
-  "INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED"
+  "INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED",
+  "INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STACK"
 };
 
 const char *rtems_internal_error_text( rtems_fatal_code error )
diff --git a/cpukit/sapi/src/malloctaskstackforidle.c b/cpukit/sapi/src/malloctaskstackforidle.c
new file mode 100644
index 0000000000..c136a6ad4b
--- /dev/null
+++ b/cpukit/sapi/src/malloctaskstackforidle.c
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSAPIConfig
+ *
+ * @brief This source file contains the implementation of
+ *   rtems_malloc_task_stack_for_idle().
+ */
+
+/*
+ * 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/config.h>
+#include <rtems/malloc.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/tls.h>
+
+void *rtems_malloc_task_stack_for_idle( uint32_t unused, size_t *size )
+{
+  void *area;
+
+  (void) unused;
+  *size += _TLS_Get_allocation_size();
+  area = rtems_malloc( *size );
+
+  if ( area == NULL ) {
+    _Internal_error( INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STACK );
+  }
+
+  return area;
+}
diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml
index f034f3fadf..57c97d9213 100644
--- a/spec/build/cpukit/librtemscpu.yml
+++ b/spec/build/cpukit/librtemscpu.yml
@@ -1363,6 +1363,7 @@ source:
 - cpukit/sapi/src/ioregisterdriver.c
 - cpukit/sapi/src/iounregisterdriver.c
 - cpukit/sapi/src/iowrite.c
+- cpukit/sapi/src/malloctaskstackforidle.c
 - cpukit/sapi/src/panic.c
 - cpukit/sapi/src/profilingiterate.c
 - cpukit/sapi/src/profilingreportxml.c
diff --git a/spec/build/testsuites/sptests/grp.yml b/spec/build/testsuites/sptests/grp.yml
index c8f70ed13b..b14eefb145 100644
--- a/spec/build/testsuites/sptests/grp.yml
+++ b/spec/build/testsuites/sptests/grp.yml
@@ -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
diff --git a/spec/build/testsuites/sptests/spfatal36.yml b/spec/build/testsuites/sptests/spfatal36.yml
new file mode 100644
index 0000000000..9e623e3511
--- /dev/null
+++ b/spec/build/testsuites/sptests/spfatal36.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) 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: []
diff --git a/testsuites/sptests/spfatal36/init.c b/testsuites/sptests/spfatal36/init.c
new file mode 100644
index 0000000000..78a9bc9082
--- /dev/null
+++ b/testsuites/sptests/spfatal36/init.c
@@ -0,0 +1,52 @@
+/* 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"
+
+#define FATAL_ERROR_TEST_NAME "36"
+
+#define FATAL_ERROR_DESCRIPTION "failure in idle task stack allocation"
+
+#define FATAL_ERROR_EXPECTED_SOURCE INTERNAL_ERROR_CORE
+
+#define FATAL_ERROR_EXPECTED_ERROR \
+  INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STACK
+
+#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE rtems_malloc_task_stack_for_idle
+
+#define CONFIGURE_IDLE_TASK_STACK_SIZE ( SIZE_MAX - RTEMS_MINIMUM_STACK_SIZE )
+
+static void force_error( void )
+{
+  RTEMS_UNREACHABLE();
+}
+
+#include "../spfatal_support/spfatalimpl.h"
diff --git a/testsuites/sptests/spfatal36/spfatal36.doc b/testsuites/sptests/spfatal36/spfatal36.doc
new file mode 100644
index 0000000000..bf4a0d492d
--- /dev/null
+++ b/testsuites/sptests/spfatal36/spfatal36.doc
@@ -0,0 +1,11 @@
+This file describes the concepts tested by this test set.
+
+test set name: spfatal36
+
+directives:
+
+  - rtems_malloc_task_stack_for_idle()
+
+concepts:
+
+  - Provoke a memory allocation failure in the directive.
diff --git a/testsuites/sptests/spinternalerror02/init.c b/testsuites/sptests/spinternalerror02/init.c
index 08aeabd3a7..e139547ca5 100644
--- a/testsuites/sptests/spinternalerror02/init.c
+++ b/testsuites/sptests/spinternalerror02/init.c
@@ -49,7 +49,7 @@ static void test_internal_error_text(void)
   } while ( text != text_last );
 
   rtems_test_assert(
-    error - 3 == INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED
+    error - 3 == INTERNAL_ERROR_NO_MEMORY_FOR_IDLE_TASK_STACK
   );
 }
 
diff --git a/testsuites/sptests/sptls04/init.c b/testsuites/sptests/sptls04/init.c
index 79ab5a5a9a..7239092185 100644
--- a/testsuites/sptests/sptls04/init.c
+++ b/testsuites/sptests/sptls04/init.c
@@ -63,6 +63,8 @@ static void Init(rtems_task_argument arg)
 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
 
+#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE rtems_malloc_task_stack_for_idle
+
 #define CONFIGURE_MAXIMUM_TASKS 1
 
 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
-- 
2.35.3



More information about the devel mailing list