On Mon, Dec 16, 2019 at 7:28 AM Sebastian Huber <sebastian.hu...@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@rtems.org > http://lists.rtems.org/mailman/listinfo/devel _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel