File indexing completed on 2025-05-11 08:24:13
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 #ifndef _RTEMS_SCORE_PRIORITYIMPL_H
0038 #define _RTEMS_SCORE_PRIORITYIMPL_H
0039
0040 #include <rtems/score/priority.h>
0041 #include <rtems/score/scheduler.h>
0042
0043 #ifdef __cplusplus
0044 extern "C" {
0045 #endif
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 typedef enum {
0063
0064
0065
0066
0067 PRIORITY_GROUP_FIRST = 0,
0068
0069
0070
0071
0072
0073 PRIORITY_GROUP_LAST = 1
0074 } Priority_Group_order;
0075
0076
0077
0078
0079
0080
0081 static inline void _Priority_Actions_initialize_empty(
0082 Priority_Actions *actions
0083 )
0084 {
0085 actions->actions = NULL;
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 static inline void _Priority_Actions_initialize_one(
0097 Priority_Actions *actions,
0098 Priority_Aggregation *aggregation,
0099 Priority_Node *node,
0100 Priority_Action_type type
0101 )
0102 {
0103 #if defined(RTEMS_SMP)
0104 aggregation->Action.next = NULL;
0105 #endif
0106 aggregation->Action.node = node;
0107 aggregation->Action.type = type;
0108
0109 actions->actions = aggregation;
0110 }
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 static inline bool _Priority_Actions_is_empty(
0121 const Priority_Actions *actions
0122 )
0123 {
0124 return actions->actions == NULL;
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134 static inline Priority_Aggregation *_Priority_Actions_move(
0135 Priority_Actions *actions
0136 )
0137 {
0138 Priority_Aggregation *aggregation;
0139
0140 aggregation = actions->actions;
0141 actions->actions = NULL;
0142
0143 return aggregation;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152 static inline void _Priority_Actions_add(
0153 Priority_Actions *actions,
0154 Priority_Aggregation *aggregation
0155 )
0156 {
0157 #if defined(RTEMS_SMP)
0158
0159
0160
0161
0162 _Assert( aggregation->Action.next == NULL );
0163 aggregation->Action.next = actions->actions;
0164 #endif
0165 actions->actions = aggregation;
0166 }
0167
0168
0169
0170
0171
0172
0173
0174 static inline void _Priority_Node_initialize(
0175 Priority_Node *node,
0176 Priority_Control priority
0177 )
0178 {
0179 node->priority = priority;
0180 _RBTree_Initialize_node( &node->Node.RBTree );
0181 }
0182
0183
0184
0185
0186
0187
0188
0189 static inline void _Priority_Node_set_priority(
0190 Priority_Node *node,
0191 Priority_Control priority
0192 )
0193 {
0194 node->priority = priority;
0195 }
0196
0197
0198
0199
0200
0201
0202 static inline void _Priority_Node_set_inactive(
0203 Priority_Node *node
0204 )
0205 {
0206 _RBTree_Set_off_tree( &node->Node.RBTree );
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 static inline bool _Priority_Node_is_active(
0218 const Priority_Node *node
0219 )
0220 {
0221 return !_RBTree_Is_node_off_tree( &node->Node.RBTree );
0222 }
0223
0224
0225
0226
0227
0228
0229 static inline void _Priority_Initialize_empty(
0230 Priority_Aggregation *aggregation
0231 )
0232 {
0233 #if defined(RTEMS_DEBUG)
0234 #if defined(RTEMS_SMP)
0235 aggregation->Action.next = NULL;
0236 #endif
0237 aggregation->Action.node = NULL;
0238 aggregation->Action.type = PRIORITY_ACTION_INVALID;
0239 #endif
0240 _RBTree_Initialize_node( &aggregation->Node.Node.RBTree );
0241 _RBTree_Initialize_empty( &aggregation->Contributors );
0242 }
0243
0244
0245
0246
0247
0248
0249
0250 static inline void _Priority_Initialize_one(
0251 Priority_Aggregation *aggregation,
0252 Priority_Node *node
0253 )
0254 {
0255 #if defined(RTEMS_DEBUG)
0256 #if defined(RTEMS_SMP)
0257 aggregation->Action.next = NULL;
0258 #endif
0259 aggregation->Action.node = NULL;
0260 aggregation->Action.type = PRIORITY_ACTION_INVALID;
0261 #endif
0262 _Priority_Node_initialize( &aggregation->Node, node->priority );
0263 _RBTree_Initialize_one( &aggregation->Contributors, &node->Node.RBTree );
0264 }
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 static inline bool _Priority_Is_empty(
0275 const Priority_Aggregation *aggregation
0276 )
0277 {
0278 return _RBTree_Is_empty( &aggregation->Contributors );
0279 }
0280
0281
0282
0283
0284
0285
0286
0287
0288 static inline Priority_Control _Priority_Get_priority(
0289 const Priority_Aggregation *aggregation
0290 )
0291 {
0292 return aggregation->Node.priority;
0293 }
0294
0295
0296
0297
0298
0299
0300
0301
0302 static inline const Scheduler_Control *_Priority_Get_scheduler(
0303 const Priority_Aggregation *aggregation
0304 )
0305 {
0306 #if defined(RTEMS_SMP)
0307 return aggregation->scheduler;
0308 #else
0309 return &_Scheduler_Table[ 0 ];
0310 #endif
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320 static inline Priority_Node *_Priority_Get_minimum_node(
0321 const Priority_Aggregation *aggregation
0322 )
0323 {
0324 return (Priority_Node *) _RBTree_Minimum( &aggregation->Contributors );
0325 }
0326
0327
0328
0329
0330
0331
0332
0333 static inline void _Priority_Set_action_node(
0334 Priority_Aggregation *aggregation,
0335 Priority_Node *node
0336 )
0337 {
0338 #if defined(RTEMS_SMP)
0339 _Assert( aggregation->Action.next == NULL );
0340 #endif
0341 aggregation->Action.node = node;
0342 }
0343
0344
0345
0346
0347
0348
0349
0350 static inline void _Priority_Set_action_type(
0351 Priority_Aggregation *aggregation,
0352 Priority_Action_type type
0353 )
0354 {
0355 #if defined(RTEMS_SMP)
0356 _Assert( aggregation->Action.next == NULL );
0357 #endif
0358 aggregation->Action.type = type;
0359 }
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369 static inline void _Priority_Set_action(
0370 Priority_Aggregation *aggregation,
0371 Priority_Node *node,
0372 Priority_Action_type type
0373 )
0374 {
0375 #if defined(RTEMS_SMP)
0376 _Assert( aggregation->Action.next == NULL );
0377 #endif
0378 aggregation->Action.node = node;
0379 aggregation->Action.type = type;
0380 }
0381
0382 #if defined(RTEMS_SMP)
0383
0384
0385
0386
0387
0388
0389
0390
0391 static inline Priority_Aggregation *_Priority_Get_next_action(
0392 #if defined(RTEMS_DEBUG)
0393 Priority_Aggregation *aggregation
0394 #else
0395 const Priority_Aggregation *aggregation
0396 #endif
0397 )
0398 {
0399 Priority_Aggregation *next;
0400
0401 next = aggregation->Action.next;
0402 #if defined(RTEMS_DEBUG)
0403 aggregation->Action.next = NULL;
0404 #endif
0405
0406 return next;
0407 }
0408 #endif
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419 static inline bool _Priority_Less(
0420 const void *left,
0421 const RBTree_Node *right
0422 )
0423 {
0424 const Priority_Control *the_left;
0425 const Priority_Node *the_right;
0426
0427 the_left = (const Priority_Control *) left;
0428 the_right = RTEMS_CONTAINER_OF( right, Priority_Node, Node.RBTree );
0429
0430 return *the_left < the_right->priority;
0431 }
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446 static inline bool _Priority_Plain_insert(
0447 Priority_Aggregation *aggregation,
0448 Priority_Node *node,
0449 Priority_Control priority
0450 )
0451 {
0452 return _RBTree_Insert_inline(
0453 &aggregation->Contributors,
0454 &node->Node.RBTree,
0455 &priority,
0456 _Priority_Less
0457 );
0458 }
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468 static inline void _Priority_Plain_extract(
0469 Priority_Aggregation *aggregation,
0470 Priority_Node *node
0471 )
0472 {
0473 _RBTree_Extract( &aggregation->Contributors, &node->Node.RBTree );
0474 }
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485 static inline void _Priority_Plain_changed(
0486 Priority_Aggregation *aggregation,
0487 Priority_Node *node
0488 )
0489 {
0490 _Priority_Plain_extract( aggregation, node );
0491 _Priority_Plain_insert( aggregation, node, node->priority );
0492 }
0493
0494 typedef void ( *Priority_Add_handler )(
0495 Priority_Aggregation *aggregation,
0496 Priority_Actions *actions,
0497 void *arg
0498 );
0499
0500 typedef void ( *Priority_Change_handler )(
0501 Priority_Aggregation *aggregation,
0502 Priority_Group_order group_order,
0503 Priority_Actions *actions,
0504 void *arg
0505 );
0506
0507 typedef void ( *Priority_Remove_handler )(
0508 Priority_Aggregation *aggregation,
0509 Priority_Actions *actions,
0510 void *arg
0511 );
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523 static inline void _Priority_Change_nothing(
0524 Priority_Aggregation *aggregation,
0525 Priority_Group_order group_order,
0526 Priority_Actions *actions,
0527 void *arg
0528 )
0529 {
0530 (void) aggregation;
0531 (void) group_order;
0532 (void) actions;
0533 (void) arg;
0534 }
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545 static inline void _Priority_Remove_nothing(
0546 Priority_Aggregation *aggregation,
0547 Priority_Actions *actions,
0548 void *arg
0549 )
0550 {
0551 (void) aggregation;
0552 (void) actions;
0553 (void) arg;
0554 }
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569 static inline void _Priority_Non_empty_insert(
0570 Priority_Aggregation *aggregation,
0571 Priority_Node *node,
0572 Priority_Actions *actions,
0573 Priority_Change_handler change,
0574 void *arg
0575 )
0576 {
0577 bool is_new_minimum;
0578
0579 _Assert( !_Priority_Is_empty( aggregation ) );
0580 is_new_minimum = _Priority_Plain_insert( aggregation, node, node->priority );
0581
0582 if ( is_new_minimum ) {
0583 aggregation->Node.priority = node->priority;
0584 ( *change )( aggregation, PRIORITY_GROUP_LAST, actions, arg );
0585 }
0586 }
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600 static inline void _Priority_Insert(
0601 Priority_Aggregation *aggregation,
0602 Priority_Node *node,
0603 Priority_Actions *actions,
0604 Priority_Add_handler add,
0605 Priority_Change_handler change,
0606 void *arg
0607 )
0608 {
0609 if ( _Priority_Is_empty( aggregation ) ) {
0610 _Priority_Initialize_one( aggregation, node );
0611 ( *add )( aggregation, actions, arg );
0612 } else {
0613 _Priority_Non_empty_insert( aggregation, node, actions, change, arg );
0614 }
0615 }
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634 static inline void _Priority_Extract(
0635 Priority_Aggregation *aggregation,
0636 Priority_Node *node,
0637 Priority_Actions *actions,
0638 Priority_Remove_handler remove,
0639 Priority_Change_handler change,
0640 void *arg
0641 )
0642 {
0643 _Priority_Plain_extract( aggregation, node );
0644
0645 if ( _Priority_Is_empty( aggregation ) ) {
0646 ( *remove )( aggregation, actions, arg );
0647 } else {
0648 Priority_Node *min;
0649
0650
0651 min = _Priority_Get_minimum_node( aggregation );
0652 _Assert( min != NULL );
0653
0654 if ( node->priority < min->priority ) {
0655 aggregation->Node.priority = min->priority;
0656 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
0657 }
0658 }
0659 }
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674 static inline void _Priority_Extract_non_empty(
0675 Priority_Aggregation *aggregation,
0676 Priority_Node *node,
0677 Priority_Actions *actions,
0678 Priority_Change_handler change,
0679 void *arg
0680 )
0681 {
0682 Priority_Node *min;
0683
0684 _Priority_Plain_extract( aggregation, node );
0685 _Assert( !_Priority_Is_empty( aggregation ) );
0686
0687 min = _Priority_Get_minimum_node( aggregation );
0688
0689 if ( node->priority < min->priority ) {
0690 aggregation->Node.priority = min->priority;
0691 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
0692 }
0693 }
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709 static inline void _Priority_Changed(
0710 Priority_Aggregation *aggregation,
0711 Priority_Node *node,
0712 Priority_Group_order group_order,
0713 Priority_Actions *actions,
0714 Priority_Change_handler change,
0715 void *arg
0716 )
0717 {
0718 Priority_Node *min;
0719
0720 _Priority_Plain_changed( aggregation, node );
0721
0722
0723
0724
0725
0726 min = _Priority_Get_minimum_node( aggregation );
0727 _Assert( min != NULL );
0728
0729 if ( min->priority != aggregation->Node.priority ) {
0730 aggregation->Node.priority = min->priority;
0731 ( *change )( aggregation, group_order, actions, arg );
0732 }
0733 }
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745 static inline void _Priority_Replace(
0746 Priority_Aggregation *aggregation,
0747 Priority_Node *victim,
0748 Priority_Node *replacement
0749 )
0750 {
0751 replacement->priority = victim->priority;
0752 _RBTree_Replace_node(
0753 &aggregation->Contributors,
0754 &victim->Node.RBTree,
0755 &replacement->Node.RBTree
0756 );
0757 }
0758
0759
0760
0761 #ifdef __cplusplus
0762 }
0763 #endif
0764
0765 #endif