Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScorePriority
0007  *
0008  * @brief This header file provides interfaces of the
0009  *   @ref RTEMSScorePriority which are only used by the implementation.
0010  */
0011 
0012 /*
0013  * Copyright (c) 2016 embedded brains GmbH & Co. KG
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
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 /* __cplusplus */
0046 
0047 /**
0048  * @addtogroup RTEMSScorePriority
0049  *
0050  * @{
0051  */
0052 
0053  /**
0054   * @brief The priority group order determines if a priority node is inserted
0055   *   as the first or last node into its priority group.
0056   *
0057   * The values of the enumerators matter.  The least significant bit of a
0058   * ::Priority_Control value is not used for the actual priority of a node.
0059   * During insertion the least significant bit is used to determine the
0060   * ordering within a priority group based on the enumerator values.
0061   */
0062 typedef enum {
0063   /**
0064    * @brief Priority group first option requests that the priority node is
0065    *   inserted as the first node into its priority group.
0066    */
0067   PRIORITY_GROUP_FIRST = 0,
0068 
0069   /**
0070    * @brief Priority group last option requests that the priority node is
0071    *   inserted as the last node into its priority group.
0072    */
0073   PRIORITY_GROUP_LAST = 1
0074 } Priority_Group_order;
0075 
0076 /**
0077  * @brief Initializes the priority actions empty.
0078  *
0079  * @param[out] actions The actions to be initialized empty.
0080  */
0081 static inline void _Priority_Actions_initialize_empty(
0082   Priority_Actions *actions
0083 )
0084 {
0085   actions->actions = NULL;
0086 }
0087 
0088 /**
0089  * @brief Initializes the priority actions with the given information.
0090  *
0091  * @param[out] actions The actions to be initialized.
0092  * @param aggregation The aggregation for the @a actions to be initialized.
0093  * @param node The action node for the @a actions to be initialized.
0094  * @param type The action type for the @a actions to be initialized.
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  * @brief Checks if the priority actions is empty.
0114  *
0115  * @param actions The priority actions to check if it is empty.
0116  *
0117  * @retval true The priority actions @a actions is empty.
0118  * @retval false The priority actions @a actions is empty.
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  * @brief Moves the priority actions' actions.
0129  *
0130  * @param[in, out] actions The priority actions to move the actions away from.
0131  *
0132  * @return The former actions of @a actions that were moved.
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  * @brief Adds actions to the priority actions' actions.
0148  *
0149  * @param[in, out] actions The priority actions to add actions to.
0150  * @param[out] aggregation The actions to add to @a actions.
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    * Priority aggregations are only added to action lists, so do not care about
0160    * the current next pointer value.
0161    */
0162   _Assert( aggregation->Action.next == NULL );
0163   aggregation->Action.next = actions->actions;
0164 #endif
0165   actions->actions = aggregation;
0166 }
0167 
0168 /**
0169  * @brief Initializes the priority node to the given priority.
0170  *
0171  * @param[out] node The priority node to be initialized.
0172  * @param priority The priority to initialize @a node to.
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  * @brief Sets the priority of the priority node to the given priority.
0185  *
0186  * @param[out] node The priority node to set the priority of.
0187  * @param priority The new priority for @a node.
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  * @brief Sets the priority node inactive.
0199  *
0200  * @param[in, out] node The priority node to set inactive.
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  * @brief Checks if the priority node is active.
0211  *
0212  * @param node The priority node that shall be verified if it is active.
0213  *
0214  * @retval true The priority node is active.
0215  * @retval false The priority node is inactive.
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  * @brief Initializes the priority aggregation empty.
0226  *
0227  * @param[out] aggregation The priority aggregaton to initialize empty.
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  * @brief Initializes the priority aggregation with the given information.
0246  *
0247  * @param[out] aggregation The priority aggregaton to initialize.
0248  * @param node The priority node to initialize @a aggregation with.
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  * @brief Checks if the priority aggregation is empty.
0268  *
0269  * @param aggregation The priority aggregation that shall be verified if it is empty.
0270  *
0271  * @retval true The priority aggregation is empty.
0272  * @retval false The priority aggregation is not empty.
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  * @brief Gets the priority aggregation's priority.
0283  *
0284  * @param aggregation The priority aggregation to get the priority from.
0285  *
0286  * @return The priority of @a aggregation.
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  * @brief Gets the priority aggregation's scheduler.
0297  *
0298  * @param aggregation The priority aggregation to get the scheduler from.
0299  *
0300  * @return The scheduler of @a aggregation.
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  * @brief Gets the minimum node of the priority aggregation
0315  *
0316  * @param aggregation The priority aggregation to get the minimum node from.
0317  *
0318  * @return The minimum node of @a aggregation
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  * @brief Sets the action node of the priority aggregation.
0329  *
0330  * @param[out] aggregation The priority aggregation to set the action node of.
0331  * @param node The new priority node for @a aggregation.
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  * @brief Sets the action type of the priority aggregation.
0346  *
0347  * @param[out] aggregation The priority aggregation to set the action type of.
0348  * @param type The new action type for @a aggregation.
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  * @brief Sets the action type and action node of the priority aggregation.
0363  *
0364  * @param[out] aggregation The priority aggregation to set the action type
0365  *      and action node of.
0366  * @param node The new action node for @a aggregation.
0367  * @param type The new action type for @a aggregation.
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  * @brief Gets the next action of the priority aggregation.
0385  *
0386  * @param aggregation is the priority aggregation to get the next action of.
0387  *
0388  * @return Returns the next action of the priority aggregation or NULL if there
0389  *   is no next action.
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  * @brief Compares two priorities.
0412  *
0413  * @param left The priority control on the left hand side of the comparison.
0414  * @param right THe RBTree_Node to get the priority for the comparison from.
0415  *
0416  * @retval true The priority on the left hand side of the comparison is smaller.
0417  * @retval false The priority on the left hand side of the comparison is greater of equal.
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  * @brief Inserts the node with the given priority into the
0435  *      priority aggregation's contributors.
0436  *
0437  * This method does not handle the case that @a node was the minimal node.
0438  *
0439  * @param[in, out] aggregation The aggregation to insert the node in its contributors.
0440  * @param[in] node The node to insert in the contributors.
0441  * @param priority The priority control for the inserted node.
0442  *
0443  * @retval true The inserted node with its priority is the minimum of the RBTree.
0444  * @retval false The inserted node with its priority is not the minimum of the RBTree.
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  * @brief Extracts the priority node from the aggregation.
0462  *
0463  * This method does not handle the case that @a node was the minimal node.
0464  *
0465  * @param[in,  out] aggregation The aggregation to extract the node from.
0466  * @param node The node to be extracted.
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  * @brief Updates the priority of the node in the aggregation.
0478  *
0479  * It first extracts the node and inserts it again, with the new @a node priority as key.
0480  *   This method does not handle the case that @a node was the minimal node.
0481  *
0482  * @param[in, out] aggregation The aggregation to change the node in.
0483  * @param node The node that has a new priority and will be reinserted in the aggregation.
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  * @brief Does nothing.
0515  *
0516  * This method does nothing.
0517  *
0518  * @param aggregation Is ignored by the method.
0519  * @param group_order Is ignored by the method.
0520  * @param actions Is ignored by the method.
0521  * @param arg Is ignored by the method.
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  * @brief Does nothing.
0538  *
0539  * This method does nothing.
0540  *
0541  * @param aggregation Is ignored by the method.
0542  * @param actions Is ignored by the method.
0543  * @param arg Is ignored by the method.
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  * @brief Inserts the node in a nonempty aggregation and handles change if
0558  *      the node is the new minimum.
0559  *
0560  * @param[in, out] aggregation The aggregation to insert the node into.
0561  * @param node The node to be inserted.  The node's priority is used as a key.
0562  * @param actions Parameter for @a change that is used if the node is the new
0563  *      minimum.
0564  * @param change The priority change handler that is called in the case that
0565  *      the new node is the minimum of the aggregation.
0566  * @param arg Arguments for @a change that is used if the node is the new
0567  *      minimum.
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  * @brief
0590  *
0591  * @param[in, out] aggregation The aggregation to insert the node in.
0592  * @param node The node to be inserted.  The node's priority is used as key.
0593  * @param actions Priority actions for the case that the aggregation was empty before
0594  *      the insert or the node is the new minimum.
0595  * @param add Is called in the case that @a aggregation was empty before the insert.
0596  * @param change Is called in the case that @a aggregation was nonempty before the
0597  *      insert and @a node is the new minimum of the aggregation.
0598  * @param arg The arguments for @a change.
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  * @brief Extracts the node from the aggregation.
0619  *
0620  * This method extracts the node from the aggregation and handles the
0621  * cases that @a aggregation is empty after the extraction, or that
0622  * @a node was the minimal node in @a aggregation by calling remove (if
0623  * empty) or change (if @a node was the minimal node).
0624  *
0625  * @param[in, out] aggregation The aggregation to extract the @a node from.
0626  * @param node The node to extract from @a aggregation.
0627  * @param actions The actions for the cases that the aggregation is empty
0628  *      after the extraction, or the minimal node was extracted.
0629  * @param remove Is called in the case that the aggregation is empty after
0630  *      the extraction.
0631  * @param change Is called in the case that the minimal node was extracted.
0632  * @param arg The arguments for @a remove and @a change.
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     /* The aggregation is non-empty, so the minimum node exists. */
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  * @brief Extracts the node from the aggregation.
0663  *
0664  * This method extracts the node from the aggregation and handles the
0665  * case that @a node was the minimal node in @a aggregation by calling
0666  * change (if @a node was the minimal node).
0667  *
0668  * @param[in, out] aggregation The aggregation to extract the @a node from.
0669  * @param node The node to extract from @a aggregation.
0670  * @param actions The actions for the case that the minimal node was extracted.
0671  * @param change Is called in the case that the minimal node was extracted.
0672  * @param arg The arguments for @a change.
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  * @brief Updates the priority of the node in the aggregation.
0697  *
0698  * This method handles the case that @a node was the minimal node in
0699  * @a aggregation.
0700  *
0701  * @param[in, out] aggregation The aggregation to change the node in.
0702  * @param node The node that has a new priority and will be reinserted in the aggregation.
0703  * @param group_order The priority group order which may be used by @ change.
0704  * @param actions The actions for the case that the minimal priority is incorrectly set
0705  *      after the change.
0706  * @param change Is called if the minimal priority is incorrectly set after the change.
0707  * @param arg The arguments for @a change.
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    * There is at least the changed node in the aggregation, so the minimum node
0724    * exists.
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  * @brief Replaces one node by another.
0737  *
0738  * The new node has the priority of the old node.
0739  *
0740  * @param[in, out] aggregation The aggregation to replace @a victim by @a replacement in.
0741  * @param victim The node that will be replaced.
0742  * @param[out] replacement The node that replaces @a victim.  It obtains its priority
0743  *      from @a victim.
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 /* __cplusplus */
0764 
0765 #endif /* _RTEMS_SCORE_PRIORITYIMPL_H */