File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040
0041 #include <rtems/rtems/scheduler.h>
0042 #include <rtems/score/assert.h>
0043 #include <rtems/score/schedulerimpl.h>
0044 #include <rtems/config.h>
0045
0046 rtems_status_code rtems_scheduler_add_processor(
0047 rtems_id scheduler_id,
0048 uint32_t cpu_index
0049 )
0050 {
0051 uint32_t scheduler_index;
0052 #if defined(RTEMS_SMP)
0053 Per_CPU_Control *cpu;
0054 rtems_status_code status;
0055 #endif
0056
0057 scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
0058
0059 if ( scheduler_index >= _Scheduler_Count ) {
0060 return RTEMS_INVALID_ID;
0061 }
0062
0063 if ( cpu_index >= rtems_configuration_get_maximum_processors() ) {
0064 return RTEMS_NOT_CONFIGURED;
0065 }
0066
0067 #if defined(RTEMS_SMP)
0068 cpu = _Per_CPU_Get_by_index( cpu_index );
0069
0070 if ( _Scheduler_Initial_assignments[ cpu_index ].scheduler == NULL ) {
0071 return RTEMS_NOT_CONFIGURED;
0072 }
0073
0074 if ( !_Per_CPU_Is_processor_online( cpu ) ) {
0075 return RTEMS_INCORRECT_STATE;
0076 }
0077
0078 _Objects_Allocator_lock();
0079
0080 if ( cpu->Scheduler.control == NULL ) {
0081 const Scheduler_Control *scheduler;
0082 Scheduler_Context *scheduler_context;
0083 Priority_Control idle_priority;
0084 Thread_Control *idle;
0085 Scheduler_Node *scheduler_node;
0086 ISR_lock_Context lock_context;
0087 Per_CPU_Control *cpu_self;
0088
0089 scheduler = &_Scheduler_Table[ scheduler_index ];
0090 scheduler_context = _Scheduler_Get_context( scheduler );
0091 idle_priority =
0092 _Scheduler_Map_priority( scheduler, scheduler->maximum_priority );
0093
0094 idle = cpu->Scheduler.idle_if_online_and_unused;
0095 _Assert( idle != NULL );
0096 cpu->Scheduler.idle_if_online_and_unused = NULL;
0097
0098 idle->Scheduler.home_scheduler = scheduler;
0099 idle->Start.initial_priority = idle_priority;
0100 scheduler_node =
0101 _Thread_Scheduler_get_node_by_index( idle, scheduler_index );
0102 _Priority_Node_set_priority( &idle->Real_priority, idle_priority );
0103 _Priority_Initialize_one(
0104 &scheduler_node->Wait.Priority,
0105 &idle->Real_priority
0106 );
0107 _Assert( _Chain_Is_empty( &idle->Scheduler.Wait_nodes ) );
0108 _Chain_Initialize_one(
0109 &idle->Scheduler.Wait_nodes,
0110 &scheduler_node->Thread.Wait_node
0111 );
0112 _Assert( _Chain_Is_empty( &idle->Scheduler.Scheduler_nodes ) );
0113 _Chain_Initialize_one(
0114 &idle->Scheduler.Scheduler_nodes,
0115 &scheduler_node->Thread.Scheduler_node.Chain
0116 );
0117
0118 _ISR_lock_ISR_disable( &lock_context );
0119 _Scheduler_Acquire_critical( scheduler, &lock_context );
0120 _Processor_mask_Set( &scheduler_context->Processors, cpu_index );
0121 cpu->Scheduler.control = scheduler;
0122 cpu->Scheduler.context = scheduler_context;
0123 ( *scheduler->Operations.add_processor )( scheduler, idle );
0124 cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
0125 _Scheduler_Release_critical( scheduler, &lock_context );
0126 _ISR_lock_ISR_enable( &lock_context );
0127 _Thread_Dispatch_direct( cpu_self );
0128 status = RTEMS_SUCCESSFUL;
0129 } else {
0130 status = RTEMS_RESOURCE_IN_USE;
0131 }
0132
0133 _Objects_Allocator_unlock();
0134 return status;
0135 #else
0136 return RTEMS_RESOURCE_IN_USE;
0137 #endif
0138 }