RTEMS 6.1-rc7
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 _Assert( aggregation->Action.next == NULL );
339 aggregation->Action.node = node;
340}
341
348static inline void _Priority_Set_action_type(
349 Priority_Aggregation *aggregation,
351)
352{
353 _Assert( aggregation->Action.next == NULL );
354 aggregation->Action.type = type;
355}
356
365static inline void _Priority_Set_action(
366 Priority_Aggregation *aggregation,
367 Priority_Node *node,
369)
370{
371 _Assert( aggregation->Action.next == NULL );
372 aggregation->Action.node = node;
373 aggregation->Action.type = type;
374}
375
376#if defined(RTEMS_SMP)
385static inline Priority_Aggregation *_Priority_Get_next_action(
386#if defined(RTEMS_DEBUG)
387 Priority_Aggregation *aggregation
388#else
389 const Priority_Aggregation *aggregation
390#endif
391)
392{
394
395 next = aggregation->Action.next;
396#if defined(RTEMS_DEBUG)
397 aggregation->Action.next = NULL;
398#endif
399
400 return next;
401}
402#endif
403
413static inline bool _Priority_Less(
414 const void *left,
415 const RBTree_Node *right
416)
417{
418 const Priority_Control *the_left;
419 const Priority_Node *the_right;
420
421 the_left = (const Priority_Control *) left;
422 the_right = RTEMS_CONTAINER_OF( right, Priority_Node, Node.RBTree );
423
424 return *the_left < the_right->priority;
425}
426
440static inline bool _Priority_Plain_insert(
441 Priority_Aggregation *aggregation,
442 Priority_Node *node,
443 Priority_Control priority
444)
445{
446 return _RBTree_Insert_inline(
447 &aggregation->Contributors,
448 &node->Node.RBTree,
449 &priority,
450 _Priority_Less
451 );
452}
453
462static inline void _Priority_Plain_extract(
463 Priority_Aggregation *aggregation,
464 Priority_Node *node
465)
466{
467 _RBTree_Extract( &aggregation->Contributors, &node->Node.RBTree );
468}
469
479static inline void _Priority_Plain_changed(
480 Priority_Aggregation *aggregation,
481 Priority_Node *node
482)
483{
484 _Priority_Plain_extract( aggregation, node );
485 _Priority_Plain_insert( aggregation, node, node->priority );
486}
487
488typedef void ( *Priority_Add_handler )(
489 Priority_Aggregation *aggregation,
490 Priority_Actions *actions,
491 void *arg
492);
493
494typedef void ( *Priority_Change_handler )(
495 Priority_Aggregation *aggregation,
496 Priority_Group_order group_order,
497 Priority_Actions *actions,
498 void *arg
499);
500
501typedef void ( *Priority_Remove_handler )(
502 Priority_Aggregation *aggregation,
503 Priority_Actions *actions,
504 void *arg
505);
506
517static inline void _Priority_Change_nothing(
518 Priority_Aggregation *aggregation,
519 Priority_Group_order group_order,
520 Priority_Actions *actions,
521 void *arg
522)
523{
524 (void) aggregation;
525 (void) group_order;
526 (void) actions;
527 (void) arg;
528}
529
539static inline void _Priority_Remove_nothing(
540 Priority_Aggregation *aggregation,
541 Priority_Actions *actions,
542 void *arg
543)
544{
545 (void) aggregation;
546 (void) actions;
547 (void) arg;
548}
549
563static inline void _Priority_Non_empty_insert(
564 Priority_Aggregation *aggregation,
565 Priority_Node *node,
566 Priority_Actions *actions,
567 Priority_Change_handler change,
568 void *arg
569)
570{
571 bool is_new_minimum;
572
573 _Assert( !_Priority_Is_empty( aggregation ) );
574 is_new_minimum = _Priority_Plain_insert( aggregation, node, node->priority );
575
576 if ( is_new_minimum ) {
577 aggregation->Node.priority = node->priority;
578 ( *change )( aggregation, PRIORITY_GROUP_LAST, actions, arg );
579 }
580}
581
594static inline void _Priority_Insert(
595 Priority_Aggregation *aggregation,
596 Priority_Node *node,
597 Priority_Actions *actions,
598 Priority_Add_handler add,
599 Priority_Change_handler change,
600 void *arg
601)
602{
603 if ( _Priority_Is_empty( aggregation ) ) {
604 _Priority_Initialize_one( aggregation, node );
605 ( *add )( aggregation, actions, arg );
606 } else {
607 _Priority_Non_empty_insert( aggregation, node, actions, change, arg );
608 }
609}
610
628static inline void _Priority_Extract(
629 Priority_Aggregation *aggregation,
630 Priority_Node *node,
631 Priority_Actions *actions,
632 Priority_Remove_handler remove,
633 Priority_Change_handler change,
634 void *arg
635)
636{
637 _Priority_Plain_extract( aggregation, node );
638
639 if ( _Priority_Is_empty( aggregation ) ) {
640 ( *remove )( aggregation, actions, arg );
641 } else {
642 Priority_Node *min;
643
644 /* The aggregation is non-empty, so the minimum node exists. */
645 min = _Priority_Get_minimum_node( aggregation );
646 _Assert( min != NULL );
647
648 if ( node->priority < min->priority ) {
649 aggregation->Node.priority = min->priority;
650 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
651 }
652 }
653}
654
668static inline void _Priority_Extract_non_empty(
669 Priority_Aggregation *aggregation,
670 Priority_Node *node,
671 Priority_Actions *actions,
672 Priority_Change_handler change,
673 void *arg
674)
675{
676 Priority_Node *min;
677
678 _Priority_Plain_extract( aggregation, node );
679 _Assert( !_Priority_Is_empty( aggregation ) );
680
681 min = _Priority_Get_minimum_node( aggregation );
682
683 if ( node->priority < min->priority ) {
684 aggregation->Node.priority = min->priority;
685 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
686 }
687}
688
703static inline void _Priority_Changed(
704 Priority_Aggregation *aggregation,
705 Priority_Node *node,
706 Priority_Group_order group_order,
707 Priority_Actions *actions,
708 Priority_Change_handler change,
709 void *arg
710)
711{
712 Priority_Node *min;
713
714 _Priority_Plain_changed( aggregation, node );
715
716 /*
717 * There is at least the changed node in the aggregation, so the minimum node
718 * exists.
719 */
720 min = _Priority_Get_minimum_node( aggregation );
721 _Assert( min != NULL );
722
723 if ( min->priority != aggregation->Node.priority ) {
724 aggregation->Node.priority = min->priority;
725 ( *change )( aggregation, group_order, actions, arg );
726 }
727}
728
739static inline void _Priority_Replace(
740 Priority_Aggregation *aggregation,
741 Priority_Node *victim,
742 Priority_Node *replacement
743)
744{
745 replacement->priority = victim->priority;
747 &aggregation->Contributors,
748 &victim->Node.RBTree,
749 &replacement->Node.RBTree
750 );
751}
752
755#ifdef __cplusplus
756}
757#endif /* __cplusplus */
758
759#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