From 01d59443b06ab351039cbc63a688cfa87f196ea0 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 9 Dec 2019 14:48:34 +0100 Subject: score: Move thread stack allocation Move thread stack allocation to caller side of _Thread_Initialize(). Update #3835. --- cpukit/include/rtems/score/thread.h | 2 -- cpukit/include/rtems/score/threadimpl.h | 9 ++++-- cpukit/posix/src/pthreadcreate.c | 20 +++++++++---- cpukit/rtems/src/taskcreate.c | 16 ++++++++-- cpukit/score/src/mpci.c | 20 +++++++++---- cpukit/score/src/threadcreateidle.c | 17 ++++++++--- cpukit/score/src/threadinitialize.c | 53 ++++++++++++--------------------- 7 files changed, 83 insertions(+), 54 deletions(-) diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h index 336be281bd..c70624f64a 100644 --- a/cpukit/include/rtems/score/thread.h +++ b/cpukit/include/rtems/score/thread.h @@ -83,8 +83,6 @@ extern "C" { */ #define RTEMS_SCORE_THREAD_ENABLE_SCHEDULER_CALLOUT -#define RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API - #if defined(RTEMS_DEBUG) #define RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT #endif diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h index 54f6c8c797..b4b85ffa90 100644 --- a/cpukit/include/rtems/score/threadimpl.h +++ b/cpukit/include/rtems/score/threadimpl.h @@ -134,15 +134,20 @@ typedef struct { const struct _Scheduler_Control *scheduler; /** - * @brief The starting address of the thread area. + * @brief The starting address of the stack area. */ void *stack_area; /** - * @brief The size of the thread area in bytes. + * @brief The size of the stack area in bytes. */ size_t stack_size; + /** + * @brief The address of the allocated stack area or NULL. + */ + void *allocated_stack; + /** * @brief The new thread's priority. */ diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index 2a418c4b68..1960a4478b 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -120,6 +120,7 @@ int pthread_create( config.stack_size = _POSIX_Threads_Ensure_minimum_stack( the_attr->stacksize ); + config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp ); } #if 0 @@ -215,14 +216,23 @@ int pthread_create( return EAGAIN; } + if ( config.stack_area == NULL ) { + config.stack_area = _Stack_Allocate( config.stack_size ); + config.allocated_stack = config.stack_area; + } + + status = ( config.stack_area != NULL ); + /* * Initialize the core thread for this task. */ - status = _Thread_Initialize( - &_POSIX_Threads_Information, - the_thread, - &config - ); + if ( status ) { + status = _Thread_Initialize( + &_POSIX_Threads_Information, + the_thread, + &config + ); + } if ( !status ) { _POSIX_Threads_Free( the_thread ); _Objects_Allocator_unlock(); diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c index 5b53ed6f78..03917f3cf4 100644 --- a/cpukit/rtems/src/taskcreate.c +++ b/cpukit/rtems/src/taskcreate.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -78,7 +79,6 @@ rtems_status_code rtems_task_create( _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); memset( &config, 0, sizeof( config ) ); - config.stack_size = stack_size; config.budget_algorithm = _Modes_Is_timeslice( initial_modes ) ? THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE : THREAD_CPU_BUDGET_ALGORITHM_NONE, @@ -86,6 +86,8 @@ rtems_status_code rtems_task_create( config.name.name_u32 = name; config.is_fp = _Attributes_Is_floating_point( the_attribute_set ); config.is_preemptible = _Modes_Is_preempt( initial_modes ); + config.stack_size = _Stack_Ensure_minimum( stack_size ); + config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp ); /* * Validate the RTEMS API priority and convert it to the core priority range. @@ -148,11 +150,21 @@ rtems_status_code rtems_task_create( } #endif + config.stack_area = _Stack_Allocate( config.stack_size ); + config.allocated_stack = config.stack_area; + status = ( config.stack_area != NULL ); + /* * Initialize the core thread for this task. */ - status = _Thread_Initialize( &_RTEMS_tasks_Information, the_thread, &config ); + if ( status ) { + status = _Thread_Initialize( + &_RTEMS_tasks_Information, + the_thread, + &config + ); + } if ( !status ) { #if defined(RTEMS_MULTIPROCESSING) diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c index 32489ac0cf..1f9b838796 100644 --- a/cpukit/score/src/mpci.c +++ b/cpukit/score/src/mpci.c @@ -114,6 +114,7 @@ static void _MPCI_Create_server( void ) } }; Thread_Configuration config; + bool ok; ISR_lock_Context lock_context; @@ -129,15 +130,24 @@ static void _MPCI_Create_server( void ) memset( &config, 0, sizeof( config ) ); config.scheduler = &_Scheduler_Table[ 0 ]; - config.stack_size = _Stack_Minimum() - + CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK - + _MPCI_Configuration.extra_mpci_receive_server_stack; config.name.name_u32 = _Objects_Build_name( 'M', 'P', 'C', 'I' ); config.priority = PRIORITY_PSEUDO_ISR; config.budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; config.is_fp = CPU_ALL_TASKS_ARE_FP; - - _Thread_Initialize( &_Thread_Information, _MPCI_Receive_server_tcb, &config ); + config.stack_size = _Stack_Minimum() + + 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 ); + + ok = _Thread_Initialize( + &_Thread_Information, + _MPCI_Receive_server_tcb, + &config + ); + _Assert( ok ); + (void) ok; _ISR_lock_ISR_disable( &lock_context ); _Thread_Start( _MPCI_Receive_server_tcb, &entry, &lock_context ); diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c index e7243ae09c..c06f211a6b 100644 --- a/cpukit/score/src/threadcreateidle.c +++ b/cpukit/score/src/threadcreateidle.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -29,8 +30,9 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) { - Thread_Configuration config; - Thread_Control *idle; + Thread_Configuration config; + Thread_Control *idle; + bool ok; memset( &config, 0, sizeof( config ) ); config.scheduler = _Scheduler_Get_by_CPU( cpu ); @@ -41,7 +43,6 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) } #endif - config.stack_size = rtems_configuration_get_idle_task_stack_size(); config.priority = _Scheduler_Map_priority( config.scheduler, config.scheduler->maximum_priority @@ -50,6 +51,12 @@ 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 ); /* * The entire workspace is zeroed during its initialization. Thus, all @@ -59,7 +66,9 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) idle = _Thread_Internal_allocate(); _Assert( idle != NULL ); - _Thread_Initialize( &_Thread_Information, idle, &config ); + ok = _Thread_Initialize( &_Thread_Information, idle, &config ); + _Assert( ok ); + (void) ok; /* * WARNING!!! This is necessary to "kick" start the system and diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index a2bb09425d..6b9b6bef21 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -46,23 +46,6 @@ bool _Thread_Initialize( size_t scheduler_index; Per_CPU_Control *cpu = _Per_CPU_Get_by_index( 0 ); -#if defined(RTEMS_SMP) - if ( !config->is_preemptible && rtems_configuration_is_smp_enabled() ) { - return false; - } -#endif - -#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE - if ( - config->isr_level != 0 -#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE - && rtems_configuration_is_smp_enabled() -#endif - ) { - return false; - } -#endif - memset( &the_thread->Join_queue, 0, @@ -76,26 +59,30 @@ bool _Thread_Initialize( (char *) the_thread + add_on->source_offset; } - /* Allocate the stack for this thread */ -#if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API) - if ( config->stack_area == NULL ) { -#endif - stack_size = _Stack_Ensure_minimum( config->stack_size ); - stack_size = _Stack_Extend_size( stack_size, config->is_fp ); - stack_area = _Stack_Allocate( stack_size ); + /* Set everything to perform the error case clean up */ + scheduler_index = 0; + the_thread->Start.allocated_stack = config->allocated_stack; - if ( stack_area == NULL ) { - return false; - } +#if defined(RTEMS_SMP) + if ( !config->is_preemptible && rtems_configuration_is_smp_enabled() ) { + goto failed; + } +#endif - the_thread->Start.allocated_stack = stack_area; -#if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API) - } else { - stack_area = config->stack_area; - stack_size = config->stack_size; +#if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE + if ( + config->isr_level != 0 +#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE + && rtems_configuration_is_smp_enabled() +#endif + ) { + goto failed; } #endif + stack_area = config->stack_area; + stack_size = config->stack_size; + /* Allocate floating-point context in stack area */ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) if ( config->is_fp ) { @@ -125,8 +112,6 @@ bool _Thread_Initialize( stack_size ); - scheduler_index = 0; - /* * Get thread queue heads */ -- cgit v1.2.3