RTEMS
priorityimpl.h
Go to the documentation of this file.
1 
9 /*
10  * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
11  *
12  * embedded brains GmbH
13  * Dornierstr. 4
14  * 82178 Puchheim
15  * Germany
16  * <rtems@embedded-brains.de>
17  *
18  * The license and distribution terms for this file may be
19  * found in the file LICENSE in this distribution or at
20  * http://www.rtems.org/license/LICENSE.
21  */
22 
23 #ifndef _RTEMS_SCORE_PRIORITYIMPL_H
24 #define _RTEMS_SCORE_PRIORITYIMPL_H
25 
26 #include <rtems/score/priority.h>
27 #include <rtems/score/scheduler.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif /* __cplusplus */
32 
45  Priority_Actions *actions
46 )
47 {
48  actions->actions = NULL;
49 }
50 
60  Priority_Actions *actions,
61  Priority_Aggregation *aggregation,
62  Priority_Node *node,
64 )
65 {
66 #if defined(RTEMS_SMP)
67  aggregation->Action.next = NULL;
68 #endif
69  aggregation->Action.node = node;
70  aggregation->Action.type = type;
71 
72  actions->actions = aggregation;
73 }
74 
84  const Priority_Actions *actions
85 )
86 {
87  return actions->actions == NULL;
88 }
89 
99  const Priority_Aggregation *aggregation
100 )
101 {
102 #if defined(RTEMS_SMP)
103  return aggregation != NULL;
104 #else
105  (void) aggregation;
106  return false;
107 #endif
108 }
109 
118  Priority_Actions *actions
119 )
120 {
121  Priority_Aggregation *aggregation;
122 
123  aggregation = actions->actions;
124  actions->actions = NULL;
125 
126  return aggregation;
127 }
128 
136  Priority_Actions *actions,
137  Priority_Aggregation *aggregation
138 )
139 {
140 #if defined(RTEMS_SMP)
141  /*
142  * Priority aggregations are only added to action lists, so do not care about
143  * the current next pointer value.
144  */
145  aggregation->Action.next = actions->actions;
146 #endif
147  actions->actions = aggregation;
148 }
149 
157  Priority_Node *node,
158  Priority_Control priority
159 )
160 {
161  node->priority = priority;
162  _RBTree_Initialize_node( &node->Node.RBTree );
163 }
164 
172  Priority_Node *node,
173  Priority_Control priority
174 )
175 {
176  node->priority = priority;
177 }
178 
185  Priority_Node *node
186 )
187 {
188  _RBTree_Set_off_tree( &node->Node.RBTree );
189 }
190 
200  const Priority_Node *node
201 )
202 {
203  return !_RBTree_Is_node_off_tree( &node->Node.RBTree );
204 }
205 
212  Priority_Aggregation *aggregation
213 )
214 {
215 #if defined(RTEMS_DEBUG)
216 #if defined(RTEMS_SMP)
217  aggregation->Action.next = NULL;
218 #endif
219  aggregation->Action.node = NULL;
220  aggregation->Action.type = PRIORITY_ACTION_INVALID;
221 #endif
222  _RBTree_Initialize_node( &aggregation->Node.Node.RBTree );
223  _RBTree_Initialize_empty( &aggregation->Contributors );
224 }
225 
233  Priority_Aggregation *aggregation,
234  Priority_Node *node
235 )
236 {
237 #if defined(RTEMS_DEBUG)
238 #if defined(RTEMS_SMP)
239  aggregation->Action.next = NULL;
240 #endif
241  aggregation->Action.node = NULL;
242  aggregation->Action.type = PRIORITY_ACTION_INVALID;
243 #endif
244  _Priority_Node_initialize( &aggregation->Node, node->priority );
245  _RBTree_Initialize_one( &aggregation->Contributors, &node->Node.RBTree );
246 }
247 
257  const Priority_Aggregation *aggregation
258 )
259 {
260  return _RBTree_Is_empty( &aggregation->Contributors );
261 }
262 
271  const Priority_Aggregation *aggregation
272 )
273 {
274  return aggregation->Node.priority;
275 }
276 
285  const Priority_Aggregation *aggregation
286 )
287 {
288 #if defined(RTEMS_SMP)
289  return aggregation->scheduler;
290 #else
291  return &_Scheduler_Table[ 0 ];
292 #endif
293 }
294 
303  const Priority_Aggregation *aggregation
304 )
305 {
306  return (Priority_Node *) _RBTree_Minimum( &aggregation->Contributors );
307 }
308 
316  Priority_Aggregation *aggregation,
317  Priority_Node *node
318 )
319 {
320  aggregation->Action.node = node;
321 }
322 
330  Priority_Aggregation *aggregation,
332 )
333 {
334  aggregation->Action.type = type;
335 }
336 
346  Priority_Aggregation *aggregation,
347  Priority_Node *node,
349 )
350 {
351  aggregation->Action.node = node;
352  aggregation->Action.type = type;
353 }
354 
364  const Priority_Aggregation *aggregation
365 )
366 {
367 #if defined(RTEMS_SMP)
368  return aggregation->Action.next;
369 #else
370  (void) aggregation;
371  return NULL;
372 #endif
373 }
374 
385  const void *left,
386  const RBTree_Node *right
387 )
388 {
389  const Priority_Control *the_left;
390  const Priority_Node *the_right;
391 
392  the_left = left;
393  the_right = RTEMS_CONTAINER_OF( right, Priority_Node, Node.RBTree );
394 
395  return *the_left < the_right->priority;
396 }
397 
412  Priority_Aggregation *aggregation,
413  Priority_Node *node,
414  Priority_Control priority
415 )
416 {
417  return _RBTree_Insert_inline(
418  &aggregation->Contributors,
419  &node->Node.RBTree,
420  &priority,
422  );
423 }
424 
434  Priority_Aggregation *aggregation,
435  Priority_Node *node
436 )
437 {
438  _RBTree_Extract( &aggregation->Contributors, &node->Node.RBTree );
439 }
440 
451  Priority_Aggregation *aggregation,
452  Priority_Node *node
453 )
454 {
455  _Priority_Plain_extract( aggregation, node );
456  _Priority_Plain_insert( aggregation, node, node->priority );
457 }
458 
459 typedef void ( *Priority_Add_handler )(
460  Priority_Aggregation *aggregation,
461  Priority_Actions *actions,
462  void *arg
463 );
464 
465 typedef void ( *Priority_Change_handler )(
466  Priority_Aggregation *aggregation,
467  bool prepend_it,
468  Priority_Actions *actions,
469  void *arg
470 );
471 
472 typedef void ( *Priority_Remove_handler )(
473  Priority_Aggregation *aggregation,
474  Priority_Actions *actions,
475  void *arg
476 );
477 
489  Priority_Aggregation *aggregation,
490  bool prepend_it,
491  Priority_Actions *actions,
492  void *arg
493 )
494 {
495  (void) aggregation;
496  (void) prepend_it;
497  (void) actions;
498  (void) arg;
499 }
500 
511  Priority_Aggregation *aggregation,
512  Priority_Actions *actions,
513  void *arg
514 )
515 {
516  (void) aggregation;
517  (void) actions;
518  (void) arg;
519 }
520 
535  Priority_Aggregation *aggregation,
536  Priority_Node *node,
537  Priority_Actions *actions,
538  Priority_Change_handler change,
539  void *arg
540 )
541 {
542  bool is_new_minimum;
543 
544  _Assert( !_Priority_Is_empty( aggregation ) );
545  is_new_minimum = _Priority_Plain_insert( aggregation, node, node->priority );
546 
547  if ( is_new_minimum ) {
548  aggregation->Node.priority = node->priority;
549  ( *change )( aggregation, false, actions, arg );
550  }
551 }
552 
566  Priority_Aggregation *aggregation,
567  Priority_Node *node,
568  Priority_Actions *actions,
569  Priority_Add_handler add,
570  Priority_Change_handler change,
571  void *arg
572 )
573 {
574  if ( _Priority_Is_empty( aggregation ) ) {
575  _Priority_Initialize_one( aggregation, node );
576  ( *add )( aggregation, actions, arg );
577  } else {
578  _Priority_Non_empty_insert( aggregation, node, actions, change, arg );
579  }
580 }
581 
600  Priority_Aggregation *aggregation,
601  Priority_Node *node,
602  Priority_Actions *actions,
603  Priority_Remove_handler remove,
604  Priority_Change_handler change,
605  void *arg
606 )
607 {
608  _Priority_Plain_extract( aggregation, node );
609 
610  if ( _Priority_Is_empty( aggregation ) ) {
611  ( *remove )( aggregation, actions, arg );
612  } else {
613  Priority_Node *min;
614 
615  min = _Priority_Get_minimum_node( aggregation );
616 
617  if ( node->priority < min->priority ) {
618  aggregation->Node.priority = min->priority;
619  ( *change )( aggregation, true, actions, arg );
620  }
621  }
622 }
623 
638  Priority_Aggregation *aggregation,
639  Priority_Node *node,
640  Priority_Actions *actions,
641  Priority_Change_handler change,
642  void *arg
643 )
644 {
645  Priority_Node *min;
646 
647  _Priority_Plain_extract( aggregation, node );
648  _Assert( !_Priority_Is_empty( aggregation ) );
649 
650  min = _Priority_Get_minimum_node( aggregation );
651 
652  if ( node->priority < min->priority ) {
653  aggregation->Node.priority = min->priority;
654  ( *change )( aggregation, true, actions, arg );
655  }
656 }
657 
674  Priority_Aggregation *aggregation,
675  Priority_Node *node,
676  bool prepend_it,
677  Priority_Actions *actions,
678  Priority_Change_handler change,
679  void *arg
680 )
681 {
682  Priority_Node *min;
683 
684  _Priority_Plain_changed( aggregation, node );
685 
686  min = _Priority_Get_minimum_node( aggregation );
687 
688  if ( min->priority != aggregation->Node.priority ) {
689  aggregation->Node.priority = min->priority;
690  ( *change )( aggregation, prepend_it, actions, arg );
691  }
692 }
693 
705  Priority_Aggregation *aggregation,
706  Priority_Node *victim,
707  Priority_Node *replacement
708 )
709 {
710  replacement->priority = victim->priority;
712  &aggregation->Contributors,
713  &victim->Node.RBTree,
714  &replacement->Node.RBTree
715  );
716 }
717 
720 #ifdef __cplusplus
721 }
722 #endif /* __cplusplus */
723 
724 #endif /* _RTEMS_SCORE_PRIORITYIMPL_H */
The priority aggregation.
Definition: priority.h:133
static __inline__ void _RBTree_Set_off_tree(RBTree_Node *the_node)
Sets a red-black tree node as off-tree.
Definition: rbtree.h:88
static __inline__ void _Priority_Initialize_one(Priority_Aggregation *aggregation, Priority_Node *node)
Initializes the priority aggregation with the given information.
Definition: priorityimpl.h:232
static __inline__ void _Priority_Non_empty_insert(Priority_Aggregation *aggregation, Priority_Node *node, Priority_Actions *actions, Priority_Change_handler change, void *arg)
Inserts the node in a nonempty aggregation and handles change if the node is the new minimum...
Definition: priorityimpl.h:534
static __inline__ void _Priority_Set_action_node(Priority_Aggregation *aggregation, Priority_Node *node)
Sets the action node of the priority aggregation.
Definition: priorityimpl.h:315
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:70
static __inline__ bool _RBTree_Insert_inline(RBTree_Control *the_rbtree, RBTree_Node *the_node, const void *key, bool(*less)(const void *, const RBTree_Node *))
Inserts the node into the red-black tree.
Definition: rbtree.h:508
static __inline__ bool _Priority_Less(const void *left, const RBTree_Node *right)
Compares two priorities.
Definition: priorityimpl.h:384
static __inline__ const Scheduler_Control * _Priority_Get_scheduler(const Priority_Aggregation *aggregation)
Gets the priority aggregation&#39;s scheduler.
Definition: priorityimpl.h:284
static __inline__ void _Priority_Set_action_type(Priority_Aggregation *aggregation, Priority_Action_type type)
Sets the action type of the priority aggregation.
Definition: priorityimpl.h:329
Priority_Aggregation * next
The next priority aggregation in the action list.
Definition: priority.h:171
The priority node to build up a priority aggregation.
Definition: priority.h:98
const struct _Scheduler_Control * scheduler
The scheduler instance of this priority aggregation.
Definition: priority.h:159
static __inline__ void _Priority_Set_action(Priority_Aggregation *aggregation, Priority_Node *node, Priority_Action_type type)
Sets the action type and action node of the priority aggregation.
Definition: priorityimpl.h:345
A list of priority actions.
Definition: priority.h:193
static __inline__ void _RBTree_Initialize_empty(RBTree_Control *the_rbtree)
Initializes this RBTree as empty.
Definition: rbtree.h:410
Priority_Control priority
The priority value of this node.
Definition: priority.h:110
static __inline__ void _Priority_Initialize_empty(Priority_Aggregation *aggregation)
Initializes the priority aggregation empty.
Definition: priorityimpl.h:211
struct Priority_Aggregation::@17 Action
A priority action block to manage priority node additions, changes and removals.
static __inline__ void _Priority_Insert(Priority_Aggregation *aggregation, Priority_Node *node, Priority_Actions *actions, Priority_Add_handler add, Priority_Change_handler change, void *arg)
Definition: priorityimpl.h:565
static __inline__ void _Priority_Node_set_inactive(Priority_Node *node)
Sets the priority node inactive.
Definition: priorityimpl.h:184
static __inline__ void _Priority_Plain_extract(Priority_Aggregation *aggregation, Priority_Node *node)
Extracts the priority node from the aggregation.
Definition: priorityimpl.h:433
Red-black tree node.
Definition: rbtree.h:55
RBTree_Node * _RBTree_Minimum(const RBTree_Control *the_rbtree)
Returns the minimum node of the red-black tree.
Definition: rbtreenext.c:36
static __inline__ Priority_Node * _Priority_Get_minimum_node(const Priority_Aggregation *aggregation)
Gets the minimum node of the priority aggregation.
Definition: priorityimpl.h:302
#define RTEMS_CONTAINER_OF(_m, _type, _member_name)
Returns the pointer to the container of a specified member pointer.
Definition: basedefs.h:550
Priority_Action_type type
The type of the action.
Definition: priority.h:182
static __inline__ void _Priority_Changed(Priority_Aggregation *aggregation, Priority_Node *node, bool prepend_it, Priority_Actions *actions, Priority_Change_handler change, void *arg)
Updates the priority of the node in the aggregation.
Definition: priorityimpl.h:673
static __inline__ bool _RBTree_Is_empty(const RBTree_Control *the_rbtree)
Checks if the RBTree is empty.
Definition: rbtree.h:375
static __inline__ void _Priority_Replace(Priority_Aggregation *aggregation, Priority_Node *victim, Priority_Node *replacement)
Replaces one node by another.
Definition: priorityimpl.h:704
RBTree_Control Contributors
A red-black tree to contain priority nodes contributing to the overall priority of this priority aggr...
Definition: priority.h:153
void _RBTree_Replace_node(RBTree_Control *the_rbtree, RBTree_Node *victim, RBTree_Node *replacement)
Replaces a node in the red-black tree without a rebalance.
Definition: rbtreereplace.c:29
static __inline__ bool _RBTree_Is_node_off_tree(const RBTree_Node *the_node)
Checks if this red-black tree node is off-tree.
Definition: rbtree.h:103
static __inline__ Priority_Aggregation * _Priority_Actions_move(Priority_Actions *actions)
Moves the priority actions&#39; actions.
Definition: priorityimpl.h:117
static __inline__ bool _Priority_Actions_is_valid(const Priority_Aggregation *aggregation)
Checks if the priority actions is valid.
Definition: priorityimpl.h:98
Priority Handler API.
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
static __inline__ void _Priority_Node_set_priority(Priority_Node *node, Priority_Control priority)
Sets the priority of the priority node to the given priority.
Definition: priorityimpl.h:171
Priority_Node Node
This priority node reflects the overall priority of the aggregation.
Definition: priority.h:147
static __inline__ void _Priority_Extract_non_empty(Priority_Aggregation *aggregation, Priority_Node *node, Priority_Actions *actions, Priority_Change_handler change, void *arg)
Extracts the node from the aggregation.
Definition: priorityimpl.h:637
static __inline__ void _RBTree_Initialize_one(RBTree_Control *the_rbtree, RBTree_Node *the_node)
Initializes this red-black tree to contain exactly the specified node.
Definition: rbtree.h:424
static __inline__ void _Priority_Change_nothing(Priority_Aggregation *aggregation, bool prepend_it, Priority_Actions *actions, void *arg)
Does nothing.
Definition: priorityimpl.h:488
static __inline__ void _Priority_Actions_initialize_one(Priority_Actions *actions, Priority_Aggregation *aggregation, Priority_Node *node, Priority_Action_type type)
Initializes the priority actions with the given information.
Definition: priorityimpl.h:59
static __inline__ bool _Priority_Is_empty(const Priority_Aggregation *aggregation)
Checks if the priority aggregation is empty.
Definition: priorityimpl.h:256
static __inline__ void _Priority_Actions_add(Priority_Actions *actions, Priority_Aggregation *aggregation)
Adds actions to the priority actions&#39; actions.
Definition: priorityimpl.h:135
static __inline__ void _RBTree_Initialize_node(RBTree_Node *the_node)
Initializes a red-black tree node.
Definition: rbtree.h:129
Scheduler control.
Definition: scheduler.h:264
static __inline__ Priority_Control _Priority_Get_priority(const Priority_Aggregation *aggregation)
Gets the priority aggregation&#39;s priority.
Definition: priorityimpl.h:270
static __inline__ bool _Priority_Node_is_active(const Priority_Node *node)
Checks if the priority node is active.
Definition: priorityimpl.h:199
static __inline__ void _Priority_Actions_initialize_empty(Priority_Actions *actions)
Initializes the priority actions empty.
Definition: priorityimpl.h:44
static __inline__ bool _Priority_Actions_is_empty(const Priority_Actions *actions)
Checks if the priority actions is empty.
Definition: priorityimpl.h:83
void _RBTree_Extract(RBTree_Control *the_rbtree, RBTree_Node *the_node)
Extracts (removes) the node from the red-black tree.
Definition: rbtreeextract.c:35
Priority_Node * node
The priority node of the action.
Definition: priority.h:177
#define RTEMS_INLINE_ROUTINE
Gives a hint to the compiler in a function declaration to inline this function.
Definition: basedefs.h:683
Priority_Action_type
The priority action type.
Definition: priority.h:116
union Priority_Node::@16 Node
Node component for a chain or red-black tree.
static __inline__ void _Priority_Remove_nothing(Priority_Aggregation *aggregation, Priority_Actions *actions, void *arg)
Does nothing.
Definition: priorityimpl.h:510
static __inline__ void _Priority_Plain_changed(Priority_Aggregation *aggregation, Priority_Node *node)
Updates the priority of the node in the aggregation.
Definition: priorityimpl.h:450
Constants and Structures Associated with the Scheduler.
static __inline__ void _Priority_Extract(Priority_Aggregation *aggregation, Priority_Node *node, Priority_Actions *actions, Priority_Remove_handler remove, Priority_Change_handler change, void *arg)
Extracts the node from the aggregation.
Definition: priorityimpl.h:599
static __inline__ Priority_Aggregation * _Priority_Get_next_action(const Priority_Aggregation *aggregation)
Gets the next action of the priority aggregation.
Definition: priorityimpl.h:363
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Definition: assert.h:100
static __inline__ void _Priority_Node_initialize(Priority_Node *node, Priority_Control priority)
Initializes the priority node to the given priority.
Definition: priorityimpl.h:156
static __inline__ bool _Priority_Plain_insert(Priority_Aggregation *aggregation, Priority_Node *node, Priority_Control priority)
Inserts the node with the given priority into the priority aggregation&#39;s contributors.
Definition: priorityimpl.h:411
Priority_Aggregation * actions
The first action of a priority action list.
Definition: priority.h:197