[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