From a08dcb2f7c7c883559e10c389404a4dc751376fa Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 9 Dec 2019 13:57:51 +0100 Subject: score: Add Thread_Configuration Add the Thread_Configuration structure to reduce the parameter count of _Thread_Initialize(). This makes it easier to add more parameters in the future. It simplifies the code generation since most architectures do not have that many registers available for function parameters. Update #3835. --- cpukit/include/rtems/score/threadimpl.h | 83 ++++++++++++++++++++++++--------- cpukit/posix/src/pthreadcreate.c | 51 ++++++++++---------- cpukit/rtems/src/taskcreate.c | 45 ++++++++---------- cpukit/score/src/mpci.c | 37 +++++++-------- cpukit/score/src/threadcreateidle.c | 37 +++++++-------- cpukit/score/src/threadinitialize.c | 70 +++++++++++++-------------- 6 files changed, 170 insertions(+), 153 deletions(-) diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h index 1289a3002f..54f6c8c797 100644 --- a/cpukit/include/rtems/score/threadimpl.h +++ b/cpukit/include/rtems/score/threadimpl.h @@ -124,6 +124,61 @@ void _Thread_Create_idle(void); */ void _Thread_Start_multitasking( void ) RTEMS_NO_RETURN; +/** + * @brief The configuration of a new thread to initialize. + */ +typedef struct { + /** + * @brief The scheduler control instance for the thread. + */ + const struct _Scheduler_Control *scheduler; + + /** + * @brief The starting address of the thread area. + */ + void *stack_area; + + /** + * @brief The size of the thread area in bytes. + */ + size_t stack_size; + + /** + * @brief The new thread's priority. + */ + Priority_Control priority; + + /** + * @brief The thread's budget algorithm. + */ + Thread_CPU_budget_algorithms budget_algorithm; + + /** + * @brief The thread's initial budget callout. + */ + Thread_CPU_budget_algorithm_callout budget_callout; + + /** + * @brief Name of the object for the thread. + */ + Objects_Name name; + + /** + * @brief The thread's initial ISR level. + */ + uint32_t isr_level; + + /** + * @brief Indicates whether the thread needs a floating-point area. + */ + bool is_fp; + + /** + * @brief Indicates whether the new thread is preemptible. + */ + bool is_preemptible; +} Thread_Configuration; + /** * @brief Initializes thread. * @@ -138,34 +193,16 @@ void _Thread_Start_multitasking( void ) RTEMS_NO_RETURN; * guaranteed to be of at least minimum size. * * @param information The thread information. - * @param[out] the_thread The thread to initialize. - * @param scheduler The scheduler control instance for the thread. - * @param stack_area The starting address of the thread area. - * @param stack_size The size of the thread area in bytes. - * @param is_fp Indicates whether the thread needs a floating point area. - * @param priority The new thread's priority. - * @param is_preemptible Indicates whether the new thread is preemptible. - * @param budget_algorithm The thread's budget algorithm. - * @param budget_callout The thread's initial budget callout. - * @param isr_level The thread's initial isr level. - * @param name Name of the object for the thread. + * @param the_thread The thread to initialize. + * @param config The configuration of the thread to initialize. * * @retval true The thread initialization was successful. * @retval false The thread initialization failed. */ bool _Thread_Initialize( - Thread_Information *information, - Thread_Control *the_thread, - const struct _Scheduler_Control *scheduler, - void *stack_area, - size_t stack_size, - bool is_fp, - Priority_Control priority, - bool is_preemptible, - Thread_CPU_budget_algorithms budget_algorithm, - Thread_CPU_budget_algorithm_callout budget_callout, - uint32_t isr_level, - Objects_Name name + Thread_Information *information, + Thread_Control *the_thread, + const Thread_Configuration *config ); /** diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index 47a408b333..2a418c4b68 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -39,6 +39,8 @@ #include #include +#include + static inline size_t _POSIX_Threads_Ensure_minimum_stack ( size_t size ) @@ -68,18 +70,12 @@ int pthread_create( const pthread_attr_t *the_attr; int normal_prio; bool valid; - Priority_Control core_normal_prio; - Thread_CPU_budget_algorithms budget_algorithm; - Thread_CPU_budget_algorithm_callout budget_callout; - bool is_fp; + Thread_Configuration config; bool status; Thread_Control *the_thread; Thread_Control *executing; - const Scheduler_Control *scheduler; int schedpolicy = SCHED_RR; struct sched_param schedparam; - size_t stacksize; - Objects_Name name; int error; ISR_lock_Context lock_context; #if defined(RTEMS_POSIX_API) @@ -96,11 +92,15 @@ int pthread_create( if ( !the_attr->is_initialized ) return EINVAL; + memset( &config, 0, sizeof( config ) ); + /* * Currently all POSIX threads are floating point if the hardware * supports it. */ - is_fp = true; + config.is_fp = true; + + config.is_preemptible = true; /* * Core Thread Initialize ensures we get the minimum amount of @@ -110,13 +110,16 @@ int pthread_create( * twice the minimum. */ if ( the_attr->stackaddr != NULL ) { - if ( !_Stack_Is_enough( the_attr->stacksize, is_fp ) ) { + if ( !_Stack_Is_enough( the_attr->stacksize, config.is_fp ) ) { return EINVAL; } - stacksize = the_attr->stacksize; + config.stack_area = the_attr->stackaddr; + config.stack_size = the_attr->stacksize; } else { - stacksize = _POSIX_Threads_Ensure_minimum_stack( the_attr->stacksize ); + config.stack_size = _POSIX_Threads_Ensure_minimum_stack( + the_attr->stacksize + ); } #if 0 @@ -164,8 +167,8 @@ int pthread_create( error = _POSIX_Thread_Translate_sched_param( schedpolicy, &schedparam, - &budget_algorithm, - &budget_callout + &config.budget_algorithm, + &config.budget_callout ); if ( error != 0 ) { return error; @@ -173,9 +176,13 @@ int pthread_create( normal_prio = schedparam.sched_priority; - scheduler = _Thread_Scheduler_get_home( executing ); + config.scheduler = _Thread_Scheduler_get_home( executing ); - core_normal_prio = _POSIX_Priority_To_core( scheduler, normal_prio, &valid ); + config.priority = _POSIX_Priority_To_core( + config.scheduler, + normal_prio, + &valid + ); if ( !valid ) { return EINVAL; } @@ -187,7 +194,7 @@ int pthread_create( low_prio = normal_prio; } - core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio, &valid ); + core_low_prio = _POSIX_Priority_To_core( config.scheduler, low_prio, &valid ); if ( !valid ) { return EINVAL; } @@ -211,20 +218,10 @@ int pthread_create( /* * Initialize the core thread for this task. */ - name.name_p = NULL; /* posix threads don't have a name by default */ status = _Thread_Initialize( &_POSIX_Threads_Information, the_thread, - scheduler, - the_attr->stackaddr, - stacksize, - is_fp, - core_normal_prio, - true, /* preemptible */ - budget_algorithm, - budget_callout, - 0, /* isr level */ - name /* posix threads don't have a name */ + &config ); if ( !status ) { _POSIX_Threads_Free( the_thread ); diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c index e27b82ced4..5b53ed6f78 100644 --- a/cpukit/rtems/src/taskcreate.c +++ b/cpukit/rtems/src/taskcreate.c @@ -30,6 +30,8 @@ #include #include +#include + rtems_status_code rtems_task_create( rtems_name name, rtems_task_priority initial_priority, @@ -40,8 +42,7 @@ rtems_status_code rtems_task_create( ) { Thread_Control *the_thread; - const Scheduler_Control *scheduler; - bool is_fp; + Thread_Configuration config; #if defined(RTEMS_MULTIPROCESSING) Objects_MP_Control *the_global_object = NULL; bool is_global; @@ -49,11 +50,9 @@ rtems_status_code rtems_task_create( bool status; rtems_attribute the_attribute_set; bool valid; - Priority_Control priority; RTEMS_API_Control *api; ASR_Information *asr; - if ( !id ) return RTEMS_INVALID_ADDRESS; @@ -78,10 +77,15 @@ rtems_status_code rtems_task_create( the_attribute_set = _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); - if ( _Attributes_Is_floating_point( the_attribute_set ) ) - is_fp = true; - else - is_fp = false; + 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, + config.isr_level = _Modes_Get_interrupt_level( initial_modes ); + config.name.name_u32 = name; + config.is_fp = _Attributes_Is_floating_point( the_attribute_set ); + config.is_preemptible = _Modes_Is_preempt( initial_modes ); /* * Validate the RTEMS API priority and convert it to the core priority range. @@ -93,9 +97,13 @@ rtems_status_code rtems_task_create( } } - scheduler = _Thread_Scheduler_get_home( _Thread_Get_executing() ); + config.scheduler = _Thread_Scheduler_get_home( _Thread_Get_executing() ); - priority = _RTEMS_Priority_To_core( scheduler, initial_priority, &valid ); + config.priority = _RTEMS_Priority_To_core( + config.scheduler, + initial_priority, + &valid + ); if ( !valid ) { return RTEMS_INVALID_PRIORITY; } @@ -144,22 +152,7 @@ rtems_status_code rtems_task_create( * Initialize the core thread for this task. */ - status = _Thread_Initialize( - &_RTEMS_tasks_Information, - the_thread, - scheduler, - NULL, - stack_size, - is_fp, - priority, - _Modes_Is_preempt(initial_modes) ? true : false, - _Modes_Is_timeslice(initial_modes) ? - THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE : - THREAD_CPU_BUDGET_ALGORITHM_NONE, - NULL, /* no budget algorithm callout */ - _Modes_Get_interrupt_level(initial_modes), - (Objects_Name) name - ); + 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 513d096480..32489ac0cf 100644 --- a/cpukit/score/src/mpci.c +++ b/cpukit/score/src/mpci.c @@ -29,6 +29,8 @@ #include #include +#include + RTEMS_STATIC_ASSERT( sizeof(MPCI_Internal_packet) <= MP_PACKET_MINIMUM_PACKET_SIZE, MPCI_Internal_packet @@ -111,8 +113,8 @@ static void _MPCI_Create_server( void ) } } }; - ISR_lock_Context lock_context; - Objects_Name name; + Thread_Configuration config; + ISR_lock_Context lock_context; if ( !_System_state_Is_multiprocessing ) @@ -123,24 +125,19 @@ static void _MPCI_Create_server( void ) */ _MPCI_Receive_server_tcb = _Thread_Internal_allocate(); - - name.name_u32 = _Objects_Build_name( 'M', 'P', 'C', 'I' ); - _Thread_Initialize( - &_Thread_Information, - _MPCI_Receive_server_tcb, - &_Scheduler_Table[ 0 ], - NULL, /* allocate the stack */ - _Stack_Minimum() + - CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK + - _MPCI_Configuration.extra_mpci_receive_server_stack, - CPU_ALL_TASKS_ARE_FP, - PRIORITY_PSEUDO_ISR, - false, /* no preempt */ - THREAD_CPU_BUDGET_ALGORITHM_NONE, - NULL, /* no budget algorithm callout */ - 0, /* all interrupts enabled */ - name - ); + _Assert( _MPCI_Receive_server_tcb != NULL ); + + 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 ); _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 3e6f19ee69..e7243ae09c 100644 --- a/cpukit/score/src/threadcreateidle.c +++ b/cpukit/score/src/threadcreateidle.c @@ -25,21 +25,31 @@ #include #include +#include + static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) { - Objects_Name name; + Thread_Configuration config; Thread_Control *idle; - const Scheduler_Control *scheduler; - scheduler = _Scheduler_Get_by_CPU( cpu ); + memset( &config, 0, sizeof( config ) ); + config.scheduler = _Scheduler_Get_by_CPU( cpu ); #if defined(RTEMS_SMP) - if (scheduler == NULL) { + if ( config.scheduler == NULL ) { return; } #endif - name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' ); + config.stack_size = rtems_configuration_get_idle_task_stack_size(); + config.priority = _Scheduler_Map_priority( + config.scheduler, + config.scheduler->maximum_priority + ); + config.budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; + config.name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' ); + config.is_fp = CPU_IDLE_TASK_IS_FP; + config.is_preemptible = true; /* * The entire workspace is zeroed during its initialization. Thus, all @@ -49,20 +59,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) idle = _Thread_Internal_allocate(); _Assert( idle != NULL ); - _Thread_Initialize( - &_Thread_Information, - idle, - scheduler, - NULL, /* allocate the stack */ - rtems_configuration_get_idle_task_stack_size(), - CPU_IDLE_TASK_IS_FP, - _Scheduler_Map_priority( scheduler, scheduler->maximum_priority ), - true, /* preemptable */ - THREAD_CPU_BUDGET_ALGORITHM_NONE, - NULL, /* no budget algorithm callout */ - 0, /* all interrupts enabled */ - name - ); + _Thread_Initialize( &_Thread_Information, idle, &config ); /* * WARNING!!! This is necessary to "kick" start the system and @@ -78,7 +75,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) _Thread_Load_environment( idle ); idle->current_state = STATES_READY; - _Scheduler_Start_idle( scheduler, idle, cpu ); + _Scheduler_Start_idle( config.scheduler, idle, cpu ); _User_extensions_Thread_start( idle ); } diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index a1bc3b2939..cf21602ac0 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -28,23 +28,16 @@ #include bool _Thread_Initialize( - Thread_Information *information, - Thread_Control *the_thread, - const Scheduler_Control *scheduler, - void *stack_area, - size_t stack_size, - bool is_fp, - Priority_Control priority, - bool is_preemptible, - Thread_CPU_budget_algorithms budget_algorithm, - Thread_CPU_budget_algorithm_callout budget_callout, - uint32_t isr_level, - Objects_Name name + Thread_Information *information, + Thread_Control *the_thread, + const Thread_Configuration *config ) { uintptr_t tls_size; bool extension_status; size_t i; + char *stack_area; + size_t stack_size; Scheduler_Node *scheduler_node; #if defined(RTEMS_SMP) Scheduler_Node *scheduler_node_for_index; @@ -54,14 +47,14 @@ bool _Thread_Initialize( Per_CPU_Control *cpu = _Per_CPU_Get_by_index( 0 ); #if defined(RTEMS_SMP) - if ( !is_preemptible && rtems_configuration_is_smp_enabled() ) { + if ( !config->is_preemptible && rtems_configuration_is_smp_enabled() ) { return false; } #endif #if defined(RTEMS_SMP) || CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE if ( - isr_level != 0 + config->isr_level != 0 #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE && rtems_configuration_is_smp_enabled() #endif @@ -87,12 +80,12 @@ bool _Thread_Initialize( /* Allocate the stack for this thread */ #if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API) - if ( stack_area == NULL ) { + if ( config->stack_area == NULL ) { #endif - stack_size = _Stack_Ensure_minimum( stack_size ); + stack_size = _Stack_Ensure_minimum( config->stack_size ); #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) - if ( is_fp ) { + if ( config->is_fp ) { stack_size += CONTEXT_FP_SIZE; } #endif @@ -106,16 +99,19 @@ bool _Thread_Initialize( 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; } #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; + if ( config->is_fp ) { + the_thread->fp_context = ( Context_Control_fp *) stack_area; + the_thread->Start.fp_context = ( Context_Control_fp *) stack_area; stack_size -= CONTEXT_FP_SIZE; - stack_area = (char *) stack_area + CONTEXT_FP_SIZE; + stack_area += CONTEXT_FP_SIZE; } #endif @@ -127,7 +123,7 @@ bool _Thread_Initialize( the_thread->Start.tls_area = (void *) ( ( (uintptr_t) stack_area + tls_align - 1 ) & ~( tls_align - 1 ) ); stack_size -= tls_size; - stack_area = (char *) stack_area + tls_size; + stack_area += tls_size; } _Stack_Initialize( @@ -156,15 +152,15 @@ bool _Thread_Initialize( * General initialization */ - the_thread->is_fp = is_fp; - the_thread->Start.isr_level = isr_level; - the_thread->Start.is_preemptible = is_preemptible; - the_thread->Start.budget_algorithm = budget_algorithm; - the_thread->Start.budget_callout = budget_callout; + the_thread->is_fp = config->is_fp; + the_thread->Start.isr_level = config->isr_level; + the_thread->Start.is_preemptible = config->is_preemptible; + the_thread->Start.budget_algorithm = config->budget_algorithm; + the_thread->Start.budget_callout = config->budget_callout; _Thread_Timer_initialize( &the_thread->Timer, cpu ); - switch ( budget_algorithm ) { + switch ( config->budget_algorithm ) { case THREAD_CPU_BUDGET_ALGORITHM_NONE: case THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE: break; @@ -188,8 +184,8 @@ bool _Thread_Initialize( while ( scheduler_index < _Scheduler_Count ) { Priority_Control priority_for_index; - if ( scheduler_for_index == scheduler ) { - priority_for_index = priority; + if ( scheduler_for_index == config->scheduler ) { + priority_for_index = config->priority; scheduler_node = scheduler_node_for_index; } else { /* @@ -226,15 +222,15 @@ bool _Thread_Initialize( #else scheduler_node = _Thread_Scheduler_get_home_node( the_thread ); _Scheduler_Node_initialize( - scheduler, + config->scheduler, scheduler_node, the_thread, - priority + config->priority ); scheduler_index = 1; #endif - _Priority_Node_initialize( &the_thread->Real_priority, priority ); + _Priority_Node_initialize( &the_thread->Real_priority, config->priority ); _Priority_Initialize_one( &scheduler_node->Wait.Priority, &the_thread->Real_priority @@ -242,7 +238,7 @@ bool _Thread_Initialize( #if defined(RTEMS_SMP) RTEMS_STATIC_ASSERT( THREAD_SCHEDULER_BLOCKED == 0, Scheduler_state ); - the_thread->Scheduler.home_scheduler = scheduler; + the_thread->Scheduler.home_scheduler = config->scheduler; _ISR_lock_Initialize( &the_thread->Scheduler.Lock, "Thread Scheduler" ); _Processor_mask_Assign( &the_thread->Scheduler.Affinity, @@ -260,7 +256,7 @@ bool _Thread_Initialize( the_thread->current_state = STATES_DORMANT; the_thread->Wait.operations = &_Thread_queue_Operations_default; - the_thread->Start.initial_priority = priority; + the_thread->Start.initial_priority = config->priority; RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags ); @@ -273,7 +269,7 @@ bool _Thread_Initialize( /* * Open the object */ - _Objects_Open( &information->Objects, &the_thread->Object, name ); + _Objects_Open( &information->Objects, &the_thread->Object, config->name ); /* * We assume the Allocator Mutex is locked and dispatching is @@ -298,7 +294,7 @@ failed: } #else if ( scheduler_index > 0 ) { - _Scheduler_Node_destroy( scheduler, scheduler_node ); + _Scheduler_Node_destroy( config->scheduler, scheduler_node ); } #endif -- cgit v1.2.3