[PATCH 11/21] score: Statically allocate idle/MPCI stacks
Sebastian Huber
sebastian.huber at embedded-brains.de
Mon Dec 16 14:28:16 UTC 2019
Place idle and MPCI stacks into extra linker sections. This can be
optionally used by applications to control the placement of the stacks.
Update #3835.
---
cpukit/include/rtems/confdefs.h | 39 +++++++++++++++---------------------
cpukit/include/rtems/score/mpci.h | 7 +++++++
cpukit/include/rtems/score/thread.h | 7 +++++++
cpukit/score/src/mpci.c | 7 +++----
cpukit/score/src/mpcidefault.c | 8 ++++++++
cpukit/score/src/threadcreateidle.c | 11 +++++-----
testsuites/sptests/spstkalloc/init.c | 4 ++--
7 files changed, 48 insertions(+), 35 deletions(-)
diff --git a/cpukit/include/rtems/confdefs.h b/cpukit/include/rtems/confdefs.h
index a5728e9868..05dfc3c91a 100644
--- a/cpukit/include/rtems/confdefs.h
+++ b/cpukit/include/rtems/confdefs.h
@@ -1824,6 +1824,14 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK, /* MPCI stack > minimum */
CONFIGURE_MP_MPCI_TABLE_POINTER /* ptr to MPCI config table */
};
+
+ char _MPCI_Receive_server_stack[
+ CONFIGURE_MINIMUM_TASK_STACK_SIZE
+ + CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK
+ + CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK
+ + CPU_ALL_TASKS_ARE_FP * CONTEXT_FP_SIZE
+ ] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
+ RTEMS_SECTION( ".rtemsstack.mpci" );
#endif
#define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 1
@@ -2432,22 +2440,6 @@ struct _reent *__getreent(void)
(_CONFIGURE_INITIALIZATION_THREADS_STACKS_CLASSIC_PART + \
_CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART)
-/*
- * This macro is calculated to specify the memory required for
- * the Idle tasks(s) stack.
- */
-#define _CONFIGURE_IDLE_TASKS_STACK \
- (_CONFIGURE_IDLE_TASKS_COUNT * \
- _Configure_From_stackspace( CONFIGURE_IDLE_TASK_STACK_SIZE ) )
-
-/*
- * This macro is calculated to specify the stack memory required for the MPCI
- * task.
- */
-#define _CONFIGURE_MPCI_RECEIVE_SERVER_STACK \
- (_CONFIGURE_MPCI_RECEIVE_SERVER_COUNT * \
- _Configure_From_stackspace(CONFIGURE_MINIMUM_TASK_STACK_SIZE))
-
/*
* This macro is calculated to specify the memory required for
* the stacks of all tasks.
@@ -2474,8 +2466,6 @@ struct _reent *__getreent(void)
#else /* CONFIGURE_EXECUTIVE_RAM_SIZE */
-#define _CONFIGURE_IDLE_TASKS_STACK 0
-#define _CONFIGURE_MPCI_RECEIVE_SERVER_STACK 0
#define _CONFIGURE_INITIALIZATION_THREADS_EXTRA_STACKS 0
#define _CONFIGURE_TASKS_STACK 0
#define _CONFIGURE_POSIX_THREADS_STACK 0
@@ -2497,13 +2487,10 @@ struct _reent *__getreent(void)
*/
#define _CONFIGURE_STACK_SPACE_SIZE \
( \
- _CONFIGURE_IDLE_TASKS_STACK + \
- _CONFIGURE_MPCI_RECEIVE_SERVER_STACK + \
_CONFIGURE_INITIALIZATION_THREADS_EXTRA_STACKS + \
_CONFIGURE_TASKS_STACK + \
_CONFIGURE_POSIX_THREADS_STACK + \
_CONFIGURE_ADA_TASKS_STACK + \
- CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK + \
_CONFIGURE_LIBBLOCK_TASK_EXTRA_STACKS + \
CONFIGURE_EXTRA_TASK_STACKS + \
_CONFIGURE_HEAP_HANDLER_OVERHEAD \
@@ -2628,8 +2615,7 @@ struct _reent *__getreent(void)
const uint32_t _Watchdog_Ticks_per_second = _CONFIGURE_TICKS_PER_SECOND;
- const size_t _Thread_Initial_thread_count = _CONFIGURE_IDLE_TASKS_COUNT +
- _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT +
+ const size_t _Thread_Initial_thread_count =
rtems_resource_maximum_per_allocation( _CONFIGURE_TASKS ) +
rtems_resource_maximum_per_allocation( _CONFIGURE_POSIX_THREADS );
@@ -2640,6 +2626,13 @@ struct _reent *__getreent(void)
_CONFIGURE_IDLE_TASKS_COUNT + _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT
);
+ char _Thread_Idle_stacks[
+ _CONFIGURE_IDLE_TASKS_COUNT
+ * ( CONFIGURE_IDLE_TASK_STACK_SIZE
+ + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE )
+ ] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
+ RTEMS_SECTION( ".rtemsstack.idle" );
+
#if CONFIGURE_MAXIMUM_BARRIERS > 0
BARRIER_INFORMATION_DEFINE( CONFIGURE_MAXIMUM_BARRIERS );
#endif
diff --git a/cpukit/include/rtems/score/mpci.h b/cpukit/include/rtems/score/mpci.h
index a72b1f0d5b..0de29739e8 100644
--- a/cpukit/include/rtems/score/mpci.h
+++ b/cpukit/include/rtems/score/mpci.h
@@ -162,6 +162,13 @@ typedef struct {
*/
extern const MPCI_Configuration _MPCI_Configuration;
+/**
+ * @brief The MPCI receive server stack.
+ *
+ * Provided by the application via <rtems/confdefs.h>
+ */
+extern char _MPCI_Receive_server_stack[];
+
/** @} */
#ifdef __cplusplus
diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h
index c70624f64a..e438549ff8 100644
--- a/cpukit/include/rtems/score/thread.h
+++ b/cpukit/include/rtems/score/thread.h
@@ -1062,6 +1062,13 @@ 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.
diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c
index 1f9b838796..f173eeb588 100644
--- a/cpukit/score/src/mpci.c
+++ b/cpukit/score/src/mpci.c
@@ -135,11 +135,10 @@ static void _MPCI_Create_server( void )
config.budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
config.is_fp = CPU_ALL_TASKS_ARE_FP;
config.stack_size = _Stack_Minimum()
+ + _MPCI_Configuration.extra_mpci_receive_server_stack
+ CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK
- + _MPCI_Configuration.extra_mpci_receive_server_stack;
- config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp );
- config.stack_area = _Stack_Allocate( config.stack_size );
- _Assert( config.stack_area != NULL );
+ + CPU_ALL_TASKS_ARE_FP * CONTEXT_FP_SIZE;
+ config.stack_area = _MPCI_Receive_server_stack;
ok = _Thread_Initialize(
&_Thread_Information,
diff --git a/cpukit/score/src/mpcidefault.c b/cpukit/score/src/mpcidefault.c
index fad806c5c1..395515759b 100644
--- a/cpukit/score/src/mpcidefault.c
+++ b/cpukit/score/src/mpcidefault.c
@@ -19,6 +19,7 @@
#endif
#include <rtems/score/mpci.h>
+#include <rtems/score/context.h>
#include <rtems/score/objectdata.h>
#include <rtems/score/stack.h>
#include <rtems/score/thread.h>
@@ -35,3 +36,10 @@ const MPCI_Configuration _MPCI_Configuration = {
STACK_MINIMUM_SIZE, /* MPCI receive server stack size */
NULL /* pointer to MPCI address table */
};
+
+char _MPCI_Receive_server_stack[
+ STACK_MINIMUM_SIZE
+ + CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK
+ + CPU_ALL_TASKS_ARE_FP * CONTEXT_FP_SIZE
+] RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
+RTEMS_SECTION( ".rtemsstack.mpci" );
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
index c06f211a6b..dbb2018bf8 100644
--- a/cpukit/score/src/threadcreateidle.c
+++ b/cpukit/score/src/threadcreateidle.c
@@ -51,12 +51,11 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu )
config.name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' );
config.is_fp = CPU_IDLE_TASK_IS_FP;
config.is_preemptible = true;
- config.stack_size = _Stack_Ensure_minimum(
- rtems_configuration_get_idle_task_stack_size()
- );
- config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp );
- config.stack_area = _Stack_Allocate( config.stack_size );
- _Assert( config.stack_area != NULL );
+ config.stack_size = rtems_configuration_get_idle_task_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 entire workspace is zeroed during its initialization. Thus, all
diff --git a/testsuites/sptests/spstkalloc/init.c b/testsuites/sptests/spstkalloc/init.c
index ab9612c94a..60169435c4 100644
--- a/testsuites/sptests/spstkalloc/init.c
+++ b/testsuites/sptests/spstkalloc/init.c
@@ -18,14 +18,14 @@ const char rtems_test_name[] = "SPSTKALLOC";
/* forward declarations to avoid warnings */
rtems_task Init(rtems_task_argument argument);
-#define MAXIMUM_STACKS 3
+#define MAXIMUM_STACKS 2
typedef struct {
uint8_t Space[CPU_STACK_MINIMUM_SIZE];
} StackMemory_t;
int stackToAlloc = 0;
-StackMemory_t Stacks[3];
+StackMemory_t Stacks[MAXIMUM_STACKS];
void *StackDeallocated = NULL;
static void *StackAllocator(size_t size)
--
2.16.4
More information about the devel
mailing list