File indexing completed on 2025-05-11 08:24:26
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
0038
0039
0040
0041
0042
0043
0044
0045
0046 #ifdef HAVE_CONFIG_H
0047 #include "config.h"
0048 #endif
0049
0050 #include <rtems/score/schedulersimplesmp.h>
0051 #include <rtems/score/schedulersmpimpl.h>
0052
0053 static Scheduler_simple_SMP_Context *
0054 _Scheduler_simple_SMP_Get_context( const Scheduler_Control *scheduler )
0055 {
0056 return (Scheduler_simple_SMP_Context *) _Scheduler_Get_context( scheduler );
0057 }
0058
0059 static Scheduler_simple_SMP_Context *
0060 _Scheduler_simple_SMP_Get_self( Scheduler_Context *context )
0061 {
0062 return (Scheduler_simple_SMP_Context *) context;
0063 }
0064
0065 void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler )
0066 {
0067 Scheduler_simple_SMP_Context *self =
0068 _Scheduler_simple_SMP_Get_context( scheduler );
0069
0070 _Scheduler_SMP_Initialize( &self->Base );
0071 _Chain_Initialize_empty( &self->Ready );
0072 }
0073
0074 void _Scheduler_simple_SMP_Node_initialize(
0075 const Scheduler_Control *scheduler,
0076 Scheduler_Node *node,
0077 Thread_Control *the_thread,
0078 Priority_Control priority
0079 )
0080 {
0081 Scheduler_SMP_Node *smp_node;
0082
0083 smp_node = _Scheduler_SMP_Node_downcast( node );
0084 _Scheduler_SMP_Node_initialize( scheduler, smp_node, the_thread, priority );
0085 }
0086
0087 static void _Scheduler_simple_SMP_Do_update(
0088 Scheduler_Context *context,
0089 Scheduler_Node *node,
0090 Priority_Control new_priority
0091 )
0092 {
0093 Scheduler_SMP_Node *smp_node;
0094
0095 (void) context;
0096
0097 smp_node = _Scheduler_SMP_Node_downcast( node );
0098 _Scheduler_SMP_Node_update_priority( smp_node, new_priority );
0099 }
0100
0101 static bool _Scheduler_simple_SMP_Has_ready( Scheduler_Context *context )
0102 {
0103 Scheduler_simple_SMP_Context *self =
0104 _Scheduler_simple_SMP_Get_self( context );
0105
0106 return !_Chain_Is_empty( &self->Ready );
0107 }
0108
0109 static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready(
0110 Scheduler_Context *context,
0111 Scheduler_Node *node
0112 )
0113 {
0114 Scheduler_simple_SMP_Context *self =
0115 _Scheduler_simple_SMP_Get_self( context );
0116 Scheduler_Node *first = (Scheduler_Node *) _Chain_First( &self->Ready );
0117
0118 (void) node;
0119
0120 _Assert( &first->Node.Chain != _Chain_Tail( &self->Ready ) );
0121
0122 return first;
0123 }
0124
0125 static void _Scheduler_simple_SMP_Move_from_scheduled_to_ready(
0126 Scheduler_Context *context,
0127 Scheduler_Node *scheduled_to_ready
0128 )
0129 {
0130 Scheduler_simple_SMP_Context *self;
0131 Priority_Control insert_priority;
0132
0133 self = _Scheduler_simple_SMP_Get_self( context );
0134
0135 _Chain_Extract_unprotected( &scheduled_to_ready->Node.Chain );
0136 insert_priority = _Scheduler_SMP_Node_priority( scheduled_to_ready );
0137 _Chain_Insert_ordered_unprotected(
0138 &self->Ready,
0139 &scheduled_to_ready->Node.Chain,
0140 &insert_priority,
0141 _Scheduler_SMP_Priority_less_equal
0142 );
0143 }
0144
0145 static void _Scheduler_simple_SMP_Move_from_ready_to_scheduled(
0146 Scheduler_Context *context,
0147 Scheduler_Node *ready_to_scheduled
0148 )
0149 {
0150 Scheduler_simple_SMP_Context *self;
0151 Priority_Control insert_priority;
0152
0153 self = _Scheduler_simple_SMP_Get_self( context );
0154
0155 _Chain_Extract_unprotected( &ready_to_scheduled->Node.Chain );
0156 insert_priority = _Scheduler_SMP_Node_priority( ready_to_scheduled );
0157 insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
0158 _Chain_Insert_ordered_unprotected(
0159 &self->Base.Scheduled,
0160 &ready_to_scheduled->Node.Chain,
0161 &insert_priority,
0162 _Scheduler_SMP_Priority_less_equal
0163 );
0164 }
0165
0166 static void _Scheduler_simple_SMP_Insert_ready(
0167 Scheduler_Context *context,
0168 Scheduler_Node *node_to_insert,
0169 Priority_Control insert_priority
0170 )
0171 {
0172 Scheduler_simple_SMP_Context *self;
0173
0174 self = _Scheduler_simple_SMP_Get_self( context );
0175
0176 _Chain_Insert_ordered_unprotected(
0177 &self->Ready,
0178 &node_to_insert->Node.Chain,
0179 &insert_priority,
0180 _Scheduler_SMP_Priority_less_equal
0181 );
0182 }
0183
0184 static void _Scheduler_simple_SMP_Extract_from_ready(
0185 Scheduler_Context *context,
0186 Scheduler_Node *node_to_extract
0187 )
0188 {
0189 (void) context;
0190
0191 _Chain_Extract_unprotected( &node_to_extract->Node.Chain );
0192 }
0193
0194 static inline Scheduler_Node *_Scheduler_simple_SMP_Get_idle( void *arg )
0195 {
0196 Scheduler_simple_SMP_Context *self =
0197 _Scheduler_simple_SMP_Get_self( arg );
0198 Scheduler_Node *lowest_ready = (Scheduler_Node *) _Chain_Last( &self->Ready );
0199
0200 _Assert( &lowest_ready->Node.Chain != _Chain_Head( &self->Ready ) );
0201 _Chain_Extract_unprotected( &lowest_ready->Node.Chain );
0202
0203 return lowest_ready;
0204 }
0205
0206 static inline void _Scheduler_simple_SMP_Release_idle(
0207 Scheduler_Node *node,
0208 void *arg
0209 )
0210 {
0211 Scheduler_simple_SMP_Context *self;
0212
0213 self = _Scheduler_simple_SMP_Get_self( arg );
0214
0215 _Chain_Append_unprotected( &self->Ready, &node->Node.Chain );
0216 }
0217
0218 void _Scheduler_simple_SMP_Block(
0219 const Scheduler_Control *scheduler,
0220 Thread_Control *thread,
0221 Scheduler_Node *node
0222 )
0223 {
0224 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0225
0226 _Scheduler_SMP_Block(
0227 context,
0228 thread,
0229 node,
0230 _Scheduler_SMP_Extract_from_scheduled,
0231 _Scheduler_simple_SMP_Extract_from_ready,
0232 _Scheduler_simple_SMP_Get_highest_ready,
0233 _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
0234 _Scheduler_SMP_Allocate_processor_lazy,
0235 _Scheduler_simple_SMP_Get_idle
0236 );
0237 }
0238
0239 static bool _Scheduler_simple_SMP_Enqueue(
0240 Scheduler_Context *context,
0241 Scheduler_Node *node,
0242 Priority_Control insert_priority
0243 )
0244 {
0245 return _Scheduler_SMP_Enqueue(
0246 context,
0247 node,
0248 insert_priority,
0249 _Scheduler_SMP_Priority_less_equal,
0250 _Scheduler_simple_SMP_Insert_ready,
0251 _Scheduler_SMP_Insert_scheduled,
0252 _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
0253 _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
0254 _Scheduler_SMP_Get_lowest_scheduled,
0255 _Scheduler_SMP_Allocate_processor_lazy,
0256 _Scheduler_simple_SMP_Get_idle,
0257 _Scheduler_simple_SMP_Release_idle
0258 );
0259 }
0260
0261 static void _Scheduler_simple_SMP_Enqueue_scheduled(
0262 Scheduler_Context *context,
0263 Scheduler_Node *node,
0264 Priority_Control insert_priority
0265 )
0266 {
0267 _Scheduler_SMP_Enqueue_scheduled(
0268 context,
0269 node,
0270 insert_priority,
0271 _Scheduler_SMP_Priority_less_equal,
0272 _Scheduler_simple_SMP_Extract_from_ready,
0273 _Scheduler_simple_SMP_Get_highest_ready,
0274 _Scheduler_simple_SMP_Insert_ready,
0275 _Scheduler_SMP_Insert_scheduled,
0276 _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
0277 _Scheduler_SMP_Allocate_processor_lazy,
0278 _Scheduler_simple_SMP_Get_idle,
0279 _Scheduler_simple_SMP_Release_idle
0280 );
0281 }
0282
0283 void _Scheduler_simple_SMP_Unblock(
0284 const Scheduler_Control *scheduler,
0285 Thread_Control *thread,
0286 Scheduler_Node *node
0287 )
0288 {
0289 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0290
0291 _Scheduler_SMP_Unblock(
0292 context,
0293 thread,
0294 node,
0295 _Scheduler_simple_SMP_Do_update,
0296 _Scheduler_simple_SMP_Enqueue,
0297 _Scheduler_simple_SMP_Release_idle
0298 );
0299 }
0300
0301 static bool _Scheduler_simple_SMP_Do_ask_for_help(
0302 Scheduler_Context *context,
0303 Thread_Control *the_thread,
0304 Scheduler_Node *node
0305 )
0306 {
0307 return _Scheduler_SMP_Ask_for_help(
0308 context,
0309 the_thread,
0310 node,
0311 _Scheduler_SMP_Priority_less_equal,
0312 _Scheduler_simple_SMP_Insert_ready,
0313 _Scheduler_SMP_Insert_scheduled,
0314 _Scheduler_simple_SMP_Move_from_scheduled_to_ready,
0315 _Scheduler_SMP_Get_lowest_scheduled,
0316 _Scheduler_SMP_Allocate_processor_lazy,
0317 _Scheduler_simple_SMP_Release_idle
0318 );
0319 }
0320
0321 void _Scheduler_simple_SMP_Update_priority(
0322 const Scheduler_Control *scheduler,
0323 Thread_Control *thread,
0324 Scheduler_Node *node
0325 )
0326 {
0327 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0328
0329 _Scheduler_SMP_Update_priority(
0330 context,
0331 thread,
0332 node,
0333 _Scheduler_SMP_Extract_from_scheduled,
0334 _Scheduler_simple_SMP_Extract_from_ready,
0335 _Scheduler_simple_SMP_Do_update,
0336 _Scheduler_simple_SMP_Enqueue,
0337 _Scheduler_simple_SMP_Enqueue_scheduled,
0338 _Scheduler_simple_SMP_Do_ask_for_help
0339 );
0340 }
0341
0342 bool _Scheduler_simple_SMP_Ask_for_help(
0343 const Scheduler_Control *scheduler,
0344 Thread_Control *the_thread,
0345 Scheduler_Node *node
0346 )
0347 {
0348 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0349
0350 return _Scheduler_simple_SMP_Do_ask_for_help( context, the_thread, node );
0351 }
0352
0353 void _Scheduler_simple_SMP_Reconsider_help_request(
0354 const Scheduler_Control *scheduler,
0355 Thread_Control *the_thread,
0356 Scheduler_Node *node
0357 )
0358 {
0359 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0360
0361 _Scheduler_SMP_Reconsider_help_request(
0362 context,
0363 the_thread,
0364 node,
0365 _Scheduler_simple_SMP_Extract_from_ready
0366 );
0367 }
0368
0369 void _Scheduler_simple_SMP_Withdraw_node(
0370 const Scheduler_Control *scheduler,
0371 Thread_Control *the_thread,
0372 Scheduler_Node *node,
0373 Thread_Scheduler_state next_state
0374 )
0375 {
0376 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0377
0378 _Scheduler_SMP_Withdraw_node(
0379 context,
0380 the_thread,
0381 node,
0382 next_state,
0383 _Scheduler_SMP_Extract_from_scheduled,
0384 _Scheduler_simple_SMP_Extract_from_ready,
0385 _Scheduler_simple_SMP_Get_highest_ready,
0386 _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
0387 _Scheduler_SMP_Allocate_processor_lazy,
0388 _Scheduler_simple_SMP_Get_idle
0389 );
0390 }
0391
0392 void _Scheduler_simple_SMP_Make_sticky(
0393 const Scheduler_Control *scheduler,
0394 Thread_Control *the_thread,
0395 Scheduler_Node *node
0396 )
0397 {
0398 _Scheduler_SMP_Make_sticky(
0399 scheduler,
0400 the_thread,
0401 node,
0402 _Scheduler_simple_SMP_Do_update,
0403 _Scheduler_simple_SMP_Enqueue
0404 );
0405 }
0406
0407 void _Scheduler_simple_SMP_Clean_sticky(
0408 const Scheduler_Control *scheduler,
0409 Thread_Control *the_thread,
0410 Scheduler_Node *node
0411 )
0412 {
0413 _Scheduler_SMP_Clean_sticky(
0414 scheduler,
0415 the_thread,
0416 node,
0417 _Scheduler_SMP_Extract_from_scheduled,
0418 _Scheduler_simple_SMP_Extract_from_ready,
0419 _Scheduler_simple_SMP_Get_highest_ready,
0420 _Scheduler_simple_SMP_Move_from_ready_to_scheduled,
0421 _Scheduler_SMP_Allocate_processor_lazy,
0422 _Scheduler_simple_SMP_Get_idle,
0423 _Scheduler_simple_SMP_Release_idle
0424 );
0425 }
0426
0427 void _Scheduler_simple_SMP_Add_processor(
0428 const Scheduler_Control *scheduler,
0429 Thread_Control *idle
0430 )
0431 {
0432 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0433
0434 _Scheduler_SMP_Add_processor(
0435 context,
0436 idle,
0437 _Scheduler_simple_SMP_Has_ready,
0438 _Scheduler_simple_SMP_Enqueue_scheduled,
0439 _Scheduler_SMP_Do_nothing_register_idle
0440 );
0441 }
0442
0443 Thread_Control *_Scheduler_simple_SMP_Remove_processor(
0444 const Scheduler_Control *scheduler,
0445 Per_CPU_Control *cpu
0446 )
0447 {
0448 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0449
0450 return _Scheduler_SMP_Remove_processor(
0451 context,
0452 cpu,
0453 _Scheduler_SMP_Extract_from_scheduled,
0454 _Scheduler_simple_SMP_Extract_from_ready,
0455 _Scheduler_simple_SMP_Enqueue,
0456 _Scheduler_simple_SMP_Get_idle,
0457 _Scheduler_simple_SMP_Release_idle
0458 );
0459 }
0460
0461 void _Scheduler_simple_SMP_Yield(
0462 const Scheduler_Control *scheduler,
0463 Thread_Control *thread,
0464 Scheduler_Node *node
0465 )
0466 {
0467 Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0468
0469 _Scheduler_SMP_Yield(
0470 context,
0471 thread,
0472 node,
0473 _Scheduler_SMP_Extract_from_scheduled,
0474 _Scheduler_simple_SMP_Extract_from_ready,
0475 _Scheduler_simple_SMP_Enqueue,
0476 _Scheduler_simple_SMP_Enqueue_scheduled
0477 );
0478 }