[rtems commit] score: Simplify FP context allocation

Sebastian Huber sebh at rtems.org
Wed Feb 12 15:11:58 UTC 2020


Module:    rtems
Branch:    master
Commit:    fc398fde77d25c086e109403eddd6de267982653
Changeset: http://git.rtems.org/rtems/commit/?id=fc398fde77d25c086e109403eddd6de267982653

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Sat Dec  7 16:50:35 2019 +0100

score: Simplify FP context allocation

Use the stack area to allocate the FP context.  This considerably
simplifies the application configuration since the task count no longer
influences the configured work space size.  With this change the stack
space size is overestimated since an FP context for each thread is
accounted.  Memory constraint applications can use the stack size for
fine tuning.

Update #3835.

---

 cpukit/include/rtems/confdefs.h        | 44 +++-------------------------------
 cpukit/include/rtems/score/context.h   |  4 +++-
 cpukit/include/rtems/score/stackimpl.h | 19 ++++++++++++---
 cpukit/posix/src/pthreadcreate.c       | 14 +++++------
 cpukit/score/src/threadinitialize.c    | 39 +++++++++++++-----------------
 cpukit/score/src/threadrestart.c       |  2 --
 6 files changed, 46 insertions(+), 76 deletions(-)

diff --git a/cpukit/include/rtems/confdefs.h b/cpukit/include/rtems/confdefs.h
index 659fee9..a356a94 100644
--- a/cpukit/include/rtems/confdefs.h
+++ b/cpukit/include/rtems/confdefs.h
@@ -30,6 +30,7 @@
 #include <rtems/ioimpl.h>
 #include <rtems/sysinit.h>
 #include <rtems/score/apimutex.h>
+#include <rtems/score/context.h>
 #include <rtems/score/percpu.h>
 #include <rtems/score/userextimpl.h>
 #include <rtems/score/wkspace.h>
@@ -1315,10 +1316,10 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
  */
 #ifdef CONFIGURE_TASK_STACK_FROM_ALLOCATOR
   #define _Configure_From_stackspace(_stack_size) \
-    CONFIGURE_TASK_STACK_FROM_ALLOCATOR(_stack_size)
+    CONFIGURE_TASK_STACK_FROM_ALLOCATOR(_stack_size + CONTEXT_FP_SIZE)
 #else
   #define _Configure_From_stackspace(_stack_size) \
-    _Configure_From_workspace(_stack_size)
+    _Configure_From_workspace(_stack_size + CONTEXT_FP_SIZE)
 #endif
 
 /**
@@ -2313,16 +2314,6 @@ struct _reent *__getreent(void)
  */
 #ifndef CONFIGURE_EXECUTIVE_RAM_SIZE
 
-/*
- * Account for allocating the following per object
- *   + array of object control structures
- *   + local pointer table -- pointer per object plus a zero'th
- *     entry in the local pointer table.
- */
-#define _CONFIGURE_MEMORY_FOR_TASKS(_tasks, _number_FP_tasks) \
-  (_Configure_Max_Objects(_number_FP_tasks) \
-    * _Configure_From_workspace(CONTEXT_FP_SIZE))
-
 /**
  * The following macro is used to calculate the memory allocated by RTEMS
  * for the message buffers associated with a particular message queue.
@@ -2359,41 +2350,12 @@ struct _reent *__getreent(void)
 #endif
 
 /**
- * This defines the formula used to compute the amount of memory
- * reserved for internal task control structures.
- */
-#if CPU_IDLE_TASK_IS_FP == TRUE
-  #define _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS \
-    _CONFIGURE_MEMORY_FOR_TASKS( \
-      _CONFIGURE_IDLE_TASKS_COUNT + _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT, \
-      _CONFIGURE_IDLE_TASKS_COUNT + _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT \
-    )
-#else
-  #define _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS \
-    _CONFIGURE_MEMORY_FOR_TASKS( \
-      _CONFIGURE_IDLE_TASKS_COUNT + _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT, \
-      _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT \
-    )
-#endif
-
-/**
- * This macro accounts for general RTEMS system overhead.
- */
-#define _CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \
-  _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS
-
-/**
  * This calculates the memory required for the executive workspace.
  *
  * This is an internal parameter.
  */
 #define CONFIGURE_EXECUTIVE_RAM_SIZE \
 ( \
-   _CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD + \
-   _CONFIGURE_MEMORY_FOR_TASKS( \
-     _CONFIGURE_TASKS, _CONFIGURE_TASKS) + \
-   _CONFIGURE_MEMORY_FOR_TASKS( \
-     CONFIGURE_MAXIMUM_POSIX_THREADS, CONFIGURE_MAXIMUM_POSIX_THREADS) + \
    _CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES( \
      CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES) + \
    _CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( \
diff --git a/cpukit/include/rtems/score/context.h b/cpukit/include/rtems/score/context.h
index a01e296..364f8c1 100644
--- a/cpukit/include/rtems/score/context.h
+++ b/cpukit/include/rtems/score/context.h
@@ -49,7 +49,9 @@ extern "C" {
  *  to store a full floating point context.
  */
 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-  #define CONTEXT_FP_SIZE CPU_CONTEXT_FP_SIZE
+  #define CONTEXT_FP_SIZE \
+    ( ( CPU_CONTEXT_FP_SIZE + CPU_HEAP_ALIGNMENT - 1 ) \
+      & ~( CPU_HEAP_ALIGNMENT - 1 ) )
 #else
   #define CONTEXT_FP_SIZE 0
 #endif
diff --git a/cpukit/include/rtems/score/stackimpl.h b/cpukit/include/rtems/score/stackimpl.h
index f4671de..6070453 100644
--- a/cpukit/include/rtems/score/stackimpl.h
+++ b/cpukit/include/rtems/score/stackimpl.h
@@ -22,6 +22,7 @@
 #define _RTEMS_SCORE_STACKIMPL_H
 
 #include <rtems/score/stack.h>
+#include <rtems/score/context.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -74,15 +75,27 @@ RTEMS_INLINE_ROUTINE uint32_t _Stack_Minimum (void)
  * a valid stack area on this processor, and false otherwise.
  *
  * @param size The stack size to check.
+ * @param is_fp Indicates if the stack is for a floating-point thread.
  *
  * @retval true @a size is large enough.
  * @retval false @a size is not large enough.
  */
-RTEMS_INLINE_ROUTINE bool _Stack_Is_enough (
-  size_t size
+RTEMS_INLINE_ROUTINE bool _Stack_Is_enough(
+  size_t size,
+  bool   is_fp
 )
 {
-  return ( size >= _Stack_Minimum() );
+  size_t minimum;
+
+  minimum = _Stack_Minimum();
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+  if ( is_fp ) {
+    minimum += CONTEXT_FP_SIZE;
+  }
+#endif
+
+  return ( size >= minimum );
 }
 
 /**
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index 93e6fd8..47a408b 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -97,6 +97,12 @@ int pthread_create(
     return EINVAL;
 
   /*
+   *  Currently all POSIX threads are floating point if the hardware
+   *  supports it.
+   */
+  is_fp = true;
+
+  /*
    *  Core Thread Initialize ensures we get the minimum amount of
    *  stack space if it is allowed to allocate it itself.
    *
@@ -104,7 +110,7 @@ int pthread_create(
    *        twice the minimum.
    */
   if ( the_attr->stackaddr != NULL ) {
-    if ( !_Stack_Is_enough(the_attr->stacksize) ) {
+    if ( !_Stack_Is_enough( the_attr->stacksize, is_fp ) ) {
       return EINVAL;
     }
 
@@ -192,12 +198,6 @@ int pthread_create(
   }
 
   /*
-   *  Currently all POSIX threads are floating point if the hardware
-   *  supports it.
-   */
-  is_fp = true;
-
-  /*
    *  Allocate the thread control block.
    *
    *  NOTE:  Global threads are not currently supported.
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index c6e8abf..4844482 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -43,9 +43,6 @@ bool _Thread_Initialize(
 )
 {
   uintptr_t                tls_size = _TLS_Get_size();
-  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-    void                  *fp_area = NULL;
-  #endif
   bool                     extension_status;
   size_t                   i;
   Scheduler_Node          *scheduler_node;
@@ -91,6 +88,13 @@ bool _Thread_Initialize(
   if ( stack_area == NULL ) {
 #endif
     stack_size = _Stack_Ensure_minimum( stack_size );
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+    if ( is_fp ) {
+      stack_size += CONTEXT_FP_SIZE;
+    }
+#endif
+
     stack_area = _Stack_Allocate( stack_size );
 
     if ( stack_area == NULL ) {
@@ -102,6 +106,16 @@ bool _Thread_Initialize(
   }
 #endif
 
+  /* Allocate floating-point context in stack area */
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+  if ( is_fp ) {
+    the_thread->fp_context = stack_area;
+    the_thread->Start.fp_context = stack_area;
+    stack_size -= CONTEXT_FP_SIZE;
+    stack_area = (char *) stack_area + CONTEXT_FP_SIZE;
+  }
+#endif
+
   _Stack_Initialize(
      &the_thread->Start.Initial_stack,
      stack_area,
@@ -124,19 +138,6 @@ bool _Thread_Initialize(
   }
 
   /*
-   *  Allocate the floating point area for this thread
-   */
-  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-    if ( is_fp ) {
-      fp_area = _Workspace_Allocate( CONTEXT_FP_SIZE );
-      if ( !fp_area )
-        goto failed;
-    }
-    the_thread->fp_context       = fp_area;
-    the_thread->Start.fp_context = fp_area;
-  #endif
-
-  /*
    *  Get thread queue heads
    */
   the_thread->Wait.spare_heads = _Freechain_Get(
@@ -301,16 +302,10 @@ failed:
 #endif
 
   _Workspace_Free( the_thread->Start.tls_area );
-
   _Freechain_Put(
     &information->Thread_queue_heads.Free,
     the_thread->Wait.spare_heads
   );
-
-  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-    _Workspace_Free( fp_area );
-  #endif
-
   _Stack_Free( the_thread->Start.allocated_stack );
   return false;
 }
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index 6ff9b44..aa47fef 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -172,8 +172,6 @@ static void _Thread_Free( Thread_Control *the_thread )
   if ( _Thread_Is_allocated_fp( the_thread ) )
     _Thread_Deallocate_fp();
 #endif
-
-  _Workspace_Free( the_thread->Start.fp_context );
 #endif
 
   _Freechain_Put(



More information about the vc mailing list