[PATCH 05/21] score: Simplify FP context allocation

Gedare Bloom gedare at rtems.org
Thu Jan 2 17:46:39 UTC 2020


On Mon, Dec 16, 2019 at 7:28 AM Sebastian Huber
<sebastian.huber at embedded-brains.de> wrote:
>
> 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.

Should this overprovisioning and fine tuning be mentioned in doc?

>
> 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 a19a4a2991..186ab0f39e 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>
> @@ -1326,10 +1327,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
>
>  /**
> @@ -2368,16 +2369,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.
> @@ -2413,30 +2404,6 @@ struct _reent *__getreent(void)
>    #define CONFIGURE_MEMORY_OVERHEAD 0
>  #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.
>   *
> @@ -2444,11 +2411,6 @@ struct _reent *__getreent(void)
>   */
>  #define CONFIGURE_EXECUTIVE_RAM_SIZE \
>  ( \
> -   _CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD + \
> -   _CONFIGURE_MEMORY_FOR_TASKS( \
> -     _CONFIGURE_TASKS, _CONFIGURE_TASKS) + \
> -   _CONFIGURE_MEMORY_FOR_TASKS( \
> -     _CONFIGURE_POSIX_THREADS, _CONFIGURE_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 a01e29683c..364f8c1182 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 ) )

On the maintainability front, do we have an ALIGN_UP macro?
  #define CONTEXT_FP_SIZE ( ALIGN_UP( CPU_CONTEXT_FP_SIZE, CPU_HEAP_ALIGNMENT) )


>  #else
>    #define CONTEXT_FP_SIZE 0
>  #endif
> diff --git a/cpukit/include/rtems/score/stackimpl.h b/cpukit/include/rtems/score/stackimpl.h
> index f4671dea60..60704534c7 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 93e6fd89a5..47a408b333 100644
> --- a/cpukit/posix/src/pthreadcreate.c
> +++ b/cpukit/posix/src/pthreadcreate.c
> @@ -96,6 +96,12 @@ int pthread_create(
>    if ( !the_attr->is_initialized )
>      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;
>      }
>
> @@ -191,12 +197,6 @@ int pthread_create(
>      return EINVAL;
>    }
>
> -  /*
> -   *  Currently all POSIX threads are floating point if the hardware
> -   *  supports it.
> -   */
> -  is_fp = true;
> -
>    /*
>     *  Allocate the thread control block.
>     *
> diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
> index c6e8abf979..48444824b2 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,
> @@ -123,19 +137,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
>     */
> @@ -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 6ff9b44515..aa47fefd1f 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(
> --
> 2.16.4
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list