RTEMS 6.1
Loading...
Searching...
No Matches
priorityimpl.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
12/*
13 * Copyright (c) 2016 embedded brains GmbH & Co. KG
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _RTEMS_SCORE_PRIORITYIMPL_H
38#define _RTEMS_SCORE_PRIORITYIMPL_H
39
42
43#ifdef __cplusplus
44extern "C" {
45#endif /* __cplusplus */
46
62typedef enum {
68
75
81static inline void _Priority_Actions_initialize_empty(
82 Priority_Actions *actions
83)
84{
85 actions->actions = NULL;
86}
87
96static inline void _Priority_Actions_initialize_one(
97 Priority_Actions *actions,
98 Priority_Aggregation *aggregation,
99 Priority_Node *node,
101)
102{
103#if defined(RTEMS_SMP)
104 aggregation->Action.next = NULL;
105#endif
106 aggregation->Action.node = node;
107 aggregation->Action.type = type;
108
109 actions->actions = aggregation;
110}
111
120static inline bool _Priority_Actions_is_empty(
121 const Priority_Actions *actions
122)
123{
124 return actions->actions == NULL;
125}
126
134static inline Priority_Aggregation *_Priority_Actions_move(
135 Priority_Actions *actions
136)
137{
138 Priority_Aggregation *aggregation;
139
140 aggregation = actions->actions;
141 actions->actions = NULL;
142
143 return aggregation;
144}
145
152static inline void _Priority_Actions_add(
153 Priority_Actions *actions,
154 Priority_Aggregation *aggregation
155)
156{
157#if defined(RTEMS_SMP)
158 /*
159 * Priority aggregations are only added to action lists, so do not care about
160 * the current next pointer value.
161 */
162 _Assert( aggregation->Action.next == NULL );
163 aggregation->Action.next = actions->actions;
164#endif
165 actions->actions = aggregation;
166}
167
174static inline void _Priority_Node_initialize(
175 Priority_Node *node,
176 Priority_Control priority
177)
178{
179 node->priority = priority;
180 _RBTree_Initialize_node( &node->Node.RBTree );
181}
182
189static inline void _Priority_Node_set_priority(
190 Priority_Node *node,
191 Priority_Control priority
192)
193{
194 node->priority = priority;
195}
196
202static inline void _Priority_Node_set_inactive(
203 Priority_Node *node
204)
205{
206 _RBTree_Set_off_tree( &node->Node.RBTree );
207}
208
217static inline bool _Priority_Node_is_active(
218 const Priority_Node *node
219)
220{
221 return !_RBTree_Is_node_off_tree( &node->Node.RBTree );
222}
223
229static inline void _Priority_Initialize_empty(
230 Priority_Aggregation *aggregation
231)
232{
233#if defined(RTEMS_DEBUG)
234#if defined(RTEMS_SMP)
235 aggregation->Action.next = NULL;
236#endif
237 aggregation->Action.node = NULL;
238 aggregation->Action.type = PRIORITY_ACTION_INVALID;
239#endif
240 _RBTree_Initialize_node( &aggregation->Node.Node.RBTree );
241 _RBTree_Initialize_empty( &aggregation->Contributors );
242}
243
250static inline void _Priority_Initialize_one(
251 Priority_Aggregation *aggregation,
252 Priority_Node *node
253)
254{
255#if defined(RTEMS_DEBUG)
256#if defined(RTEMS_SMP)
257 aggregation->Action.next = NULL;
258#endif
259 aggregation->Action.node = NULL;
260 aggregation->Action.type = PRIORITY_ACTION_INVALID;
261#endif
262 _Priority_Node_initialize( &aggregation->Node, node->priority );
263 _RBTree_Initialize_one( &aggregation->Contributors, &node->Node.RBTree );
264}
265
274static inline bool _Priority_Is_empty(
275 const Priority_Aggregation *aggregation
276)
277{
278 return _RBTree_Is_empty( &aggregation->Contributors );
279}
280
288static inline Priority_Control _Priority_Get_priority(
289 const Priority_Aggregation *aggregation
290)
291{
292 return aggregation->Node.priority;
293}
294
302static inline const Scheduler_Control *_Priority_Get_scheduler(
303 const Priority_Aggregation *aggregation
304)
305{
306#if defined(RTEMS_SMP)
307 return aggregation->scheduler;
308#else
309 return &_Scheduler_Table[ 0 ];
310#endif
311}
312
320static inline Priority_Node *_Priority_Get_minimum_node(
321 const Priority_Aggregation *aggregation
322)
323{
324 return (Priority_Node *) _RBTree_Minimum( &aggregation->Contributors );
325}
326
333static inline void _Priority_Set_action_node(
334 Priority_Aggregation *aggregation,
335 Priority_Node *node
336)
337{
338#if defined(RTEMS_SMP)
339 _Assert( aggregation->Action.next == NULL );
340#endif
341 aggregation->Action.node = node;
342}
343
350static inline void _Priority_Set_action_type(
351 Priority_Aggregation *aggregation,
353)
354{
355#if defined(RTEMS_SMP)
356 _Assert( aggregation->Action.next == NULL );
357#endif
358 aggregation->Action.type = type;
359}
360
369static inline void _Priority_Set_action(
370 Priority_Aggregation *aggregation,
371 Priority_Node *node,
373)
374{
375#if defined(RTEMS_SMP)
376 _Assert( aggregation->Action.next == NULL );
377#endif
378 aggregation->Action.node = node;
379 aggregation->Action.type = type;
380}
381
382#if defined(RTEMS_SMP)
391static inline Priority_Aggregation *_Priority_Get_next_action(
392#if defined(RTEMS_DEBUG)
393 Priority_Aggregation *aggregation
394#else
395 const Priority_Aggregation *aggregation
396#endif
397)
398{
400
401 next = aggregation->Action.next;
402#if defined(RTEMS_DEBUG)
403 aggregation->Action.next = NULL;
404#endif
405
406 return next;
407}
408#endif
409
419static inline bool _Priority_Less(
420 const void *left,
421 const RBTree_Node *right
422)
423{
424 const Priority_Control *the_left;
425 const Priority_Node *the_right;
426
427 the_left = (const Priority_Control *) left;
428 the_right = RTEMS_CONTAINER_OF( right, Priority_Node, Node.RBTree );
429
430 return *the_left < the_right->priority;
431}
432
446static inline bool _Priority_Plain_insert(
447 Priority_Aggregation *aggregation,
448 Priority_Node *node,
449 Priority_Control priority
450)
451{
452 return _RBTree_Insert_inline(
453 &aggregation->Contributors,
454 &node->Node.RBTree,
455 &priority,
456 _Priority_Less
457 );
458}
459
468static inline void _Priority_Plain_extract(
469 Priority_Aggregation *aggregation,
470 Priority_Node *node
471)
472{
473 _RBTree_Extract( &aggregation->Contributors, &node->Node.RBTree );
474}
475
485static inline void _Priority_Plain_changed(
486 Priority_Aggregation *aggregation,
487 Priority_Node *node
488)
489{
490 _Priority_Plain_extract( aggregation, node );
491 _Priority_Plain_insert( aggregation, node, node->priority );
492}
493
494typedef void ( *Priority_Add_handler )(
495 Priority_Aggregation *aggregation,
496 Priority_Actions *actions,
497 void *arg
498);
499
500typedef void ( *Priority_Change_handler )(
501 Priority_Aggregation *aggregation,
502 Priority_Group_order group_order,
503 Priority_Actions *actions,
504 void *arg
505);
506
507typedef void ( *Priority_Remove_handler )(
508 Priority_Aggregation *aggregation,
509 Priority_Actions *actions,
510 void *arg
511);
512
523static inline void _Priority_Change_nothing(
524 Priority_Aggregation *aggregation,
525 Priority_Group_order group_order,
526 Priority_Actions *actions,
527 void *arg
528)
529{
530 (void) aggregation;
531 (void) group_order;
532 (void) actions;
533 (void) arg;
534}
535
545static inline void _Priority_Remove_nothing(
546 Priority_Aggregation *aggregation,
547 Priority_Actions *actions,
548 void *arg
549)
550{
551 (void) aggregation;
552 (void) actions;
553 (void) arg;
554}
555
569static inline void _Priority_Non_empty_insert(
570 Priority_Aggregation *aggregation,
571 Priority_Node *node,
572 Priority_Actions *actions,
573 Priority_Change_handler change,
574 void *arg
575)
576{
577 bool is_new_minimum;
578
579 _Assert( !_Priority_Is_empty( aggregation ) );
580 is_new_minimum = _Priority_Plain_insert( aggregation, node, node->priority );
581
582 if ( is_new_minimum ) {
583 aggregation->Node.priority = node->priority;
584 ( *change )( aggregation, PRIORITY_GROUP_LAST, actions, arg );
585 }
586}
587
600static inline void _Priority_Insert(
601 Priority_Aggregation *aggregation,
602 Priority_Node *node,
603 Priority_Actions *actions,
604 Priority_Add_handler add,
605 Priority_Change_handler change,
606 void *arg
607)
608{
609 if ( _Priority_Is_empty( aggregation ) ) {
610 _Priority_Initialize_one( aggregation, node );
611 ( *add )( aggregation, actions, arg );
612 } else {
613 _Priority_Non_empty_insert( aggregation, node, actions, change, arg );
614 }
615}
616
634static inline void _Priority_Extract(
635 Priority_Aggregation *aggregation,
636 Priority_Node *node,
637 Priority_Actions *actions,
638 Priority_Remove_handler remove,
639 Priority_Change_handler change,
640 void *arg
641)
642{
643 _Priority_Plain_extract( aggregation, node );
644
645 if ( _Priority_Is_empty( aggregation ) ) {
646 ( *remove )( aggregation, actions, arg );
647 } else {
648 Priority_Node *min;
649
650 /* The aggregation is non-empty, so the minimum node exists. */
651 min = _Priority_Get_minimum_node( aggregation );
652 _Assert( min != NULL );
653
654 if ( node->priority < min->priority ) {
655 aggregation->Node.priority = min->priority;
656 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
657 }
658 }
659}
660
674static inline void _Priority_Extract_non_empty(
675 Priority_Aggregation *aggregation,
676 Priority_Node *node,
677 Priority_Actions *actions,
678 Priority_Change_handler change,
679 void *arg
680)
681{
682 Priority_Node *min;
683
684 _Priority_Plain_extract( aggregation, node );
685 _Assert( !_Priority_Is_empty( aggregation ) );
686
687 min = _Priority_Get_minimum_node( aggregation );
688
689 if ( node->priority < min->priority ) {
690 aggregation->Node.priority = min->priority;
691 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
692 }
693}
694
709static inline void _Priority_Changed(
710 Priority_Aggregation *aggregation,
711 Priority_Node *node,
712 Priority_Group_order group_order,
713 Priority_Actions *actions,
714 Priority_Change_handler change,
715 void *arg
716)
717{
718 Priority_Node *min;
719
720 _Priority_Plain_changed( aggregation, node );
721
722 /*
723 * There is at least the changed node in the aggregation, so the minimum node
724 * exists.
725 */
726 min = _Priority_Get_minimum_node( aggregation );
727 _Assert( min != NULL );
728
729 if ( min->priority != aggregation->Node.priority ) {
730 aggregation->Node.priority = min->priority;
731 ( *change )( aggregation, group_order, actions, arg );
732 }
733}
734
745static inline void _Priority_Replace(
746 Priority_Aggregation *aggregation,
747 Priority_Node *victim,
748 Priority_Node *replacement
749)
750{
751 replacement->priority = victim->priority;
753 &aggregation->Contributors,
754 &victim->Node.RBTree,
755 &replacement->Node.RBTree
756 );
757}
758
761#ifdef __cplusplus
762}
763#endif /* __cplusplus */
764
765#endif /* _RTEMS_SCORE_PRIORITYIMPL_H */
#define RTEMS_CONTAINER_OF(_m, _type, _member_name)
Gets the container of a member.
Definition: basedefs.h:306
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG and static analysis runs.
Definition: assert.h:96
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:91
Priority_Group_order
The priority group order determines if a priority node is inserted as the first or last node into its...
Definition: priorityimpl.h:62
Priority_Action_type
The priority action type.
Definition: priority.h:130
@ PRIORITY_GROUP_LAST
Priority group last option requests that the priority node is inserted as the last node into its prio...
Definition: priorityimpl.h:73
@ PRIORITY_GROUP_FIRST
Priority group first option requests that the priority node is inserted as the first node into its pr...
Definition: priorityimpl.h:67
void _RBTree_Extract(RBTree_Control *the_rbtree, RBTree_Node *the_node)
Extracts (removes) the node from the red-black tree.
Definition: rbtreeextract.c:63
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:43
RBTree_Node * _RBTree_Minimum(const RBTree_Control *the_rbtree)
Returns the minimum node of the red-black tree.
Definition: rbtreemin.c:43
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
This header file provides interfaces of the Priority Handler which are used by the implementation and...
This header file provides interfaces of the Scheduler Handler which are used by the implementation an...
A list of priority actions.
Definition: priority.h:207
Priority_Aggregation * actions
The first action of a priority action list.
Definition: priority.h:211
The priority aggregation.
Definition: priority.h:147
Priority_Action_type type
The type of the action.
Definition: priority.h:196
struct Priority_Aggregation::@4405 Action
A priority action block to manage priority node additions, changes and removals.
Priority_Node Node
This priority node reflects the overall priority of the aggregation.
Definition: priority.h:161
RBTree_Control Contributors
A red-black tree to contain priority nodes contributing to the overall priority of this priority aggr...
Definition: priority.h:167
Priority_Node * node
The priority node of the action.
Definition: priority.h:191
The priority node to build up a priority aggregation.
Definition: priority.h:112
union Priority_Node::@4404 Node
Node component for a chain or red-black tree.
Priority_Control priority
The priority value of this node.
Definition: priority.h:124
Red-black tree node.
Definition: rbtree.h:73
Scheduler control.
Definition: scheduler.h:337