RTEMS 7.0-rc1
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 (void) aggregation;
310 return &_Scheduler_Table[ 0 ];
311#endif
312}
313
321static inline Priority_Node *_Priority_Get_minimum_node(
322 const Priority_Aggregation *aggregation
323)
324{
325 return (Priority_Node *) _RBTree_Minimum( &aggregation->Contributors );
326}
327
334static inline void _Priority_Set_action_node(
335 Priority_Aggregation *aggregation,
336 Priority_Node *node
337)
338{
339#if defined(RTEMS_SMP)
340 _Assert( aggregation->Action.next == NULL );
341#endif
342 aggregation->Action.node = node;
343}
344
351static inline void _Priority_Set_action_type(
352 Priority_Aggregation *aggregation,
354)
355{
356#if defined(RTEMS_SMP)
357 _Assert( aggregation->Action.next == NULL );
358#endif
359 aggregation->Action.type = type;
360}
361
370static inline void _Priority_Set_action(
371 Priority_Aggregation *aggregation,
372 Priority_Node *node,
374)
375{
376#if defined(RTEMS_SMP)
377 _Assert( aggregation->Action.next == NULL );
378#endif
379 aggregation->Action.node = node;
380 aggregation->Action.type = type;
381}
382
383#if defined(RTEMS_SMP)
392static inline Priority_Aggregation *_Priority_Get_next_action(
393#if defined(RTEMS_DEBUG)
394 Priority_Aggregation *aggregation
395#else
396 const Priority_Aggregation *aggregation
397#endif
398)
399{
401
402 next = aggregation->Action.next;
403#if defined(RTEMS_DEBUG)
404 aggregation->Action.next = NULL;
405#endif
406
407 return next;
408}
409#endif
410
420static inline bool _Priority_Less(
421 const void *left,
422 const RBTree_Node *right
423)
424{
425 const Priority_Control *the_left;
426 const Priority_Node *the_right;
427
428 the_left = (const Priority_Control *) left;
429 the_right = RTEMS_CONTAINER_OF( right, Priority_Node, Node.RBTree );
430
431 return *the_left < the_right->priority;
432}
433
447static inline bool _Priority_Plain_insert(
448 Priority_Aggregation *aggregation,
449 Priority_Node *node,
450 Priority_Control priority
451)
452{
453 return _RBTree_Insert_inline(
454 &aggregation->Contributors,
455 &node->Node.RBTree,
456 &priority,
457 _Priority_Less
458 );
459}
460
469static inline void _Priority_Plain_extract(
470 Priority_Aggregation *aggregation,
471 Priority_Node *node
472)
473{
474 _RBTree_Extract( &aggregation->Contributors, &node->Node.RBTree );
475}
476
486static inline void _Priority_Plain_changed(
487 Priority_Aggregation *aggregation,
488 Priority_Node *node
489)
490{
491 _Priority_Plain_extract( aggregation, node );
492 _Priority_Plain_insert( aggregation, node, node->priority );
493}
494
495typedef void ( *Priority_Add_handler )(
496 Priority_Aggregation *aggregation,
497 Priority_Actions *actions,
498 void *arg
499);
500
501typedef void ( *Priority_Change_handler )(
502 Priority_Aggregation *aggregation,
503 Priority_Group_order group_order,
504 Priority_Actions *actions,
505 void *arg
506);
507
508typedef void ( *Priority_Remove_handler )(
509 Priority_Aggregation *aggregation,
510 Priority_Actions *actions,
511 void *arg
512);
513
524static inline void _Priority_Change_nothing(
525 Priority_Aggregation *aggregation,
526 Priority_Group_order group_order,
527 Priority_Actions *actions,
528 void *arg
529)
530{
531 (void) aggregation;
532 (void) group_order;
533 (void) actions;
534 (void) arg;
535}
536
546static inline void _Priority_Remove_nothing(
547 Priority_Aggregation *aggregation,
548 Priority_Actions *actions,
549 void *arg
550)
551{
552 (void) aggregation;
553 (void) actions;
554 (void) arg;
555}
556
570static inline void _Priority_Non_empty_insert(
571 Priority_Aggregation *aggregation,
572 Priority_Node *node,
573 Priority_Actions *actions,
574 Priority_Change_handler change,
575 void *arg
576)
577{
578 bool is_new_minimum;
579
580 _Assert( !_Priority_Is_empty( aggregation ) );
581 is_new_minimum = _Priority_Plain_insert( aggregation, node, node->priority );
582
583 if ( is_new_minimum ) {
584 aggregation->Node.priority = node->priority;
585 ( *change )( aggregation, PRIORITY_GROUP_LAST, actions, arg );
586 }
587}
588
601static inline void _Priority_Insert(
602 Priority_Aggregation *aggregation,
603 Priority_Node *node,
604 Priority_Actions *actions,
605 Priority_Add_handler add,
606 Priority_Change_handler change,
607 void *arg
608)
609{
610 if ( _Priority_Is_empty( aggregation ) ) {
611 _Priority_Initialize_one( aggregation, node );
612 ( *add )( aggregation, actions, arg );
613 } else {
614 _Priority_Non_empty_insert( aggregation, node, actions, change, arg );
615 }
616}
617
635static inline void _Priority_Extract(
636 Priority_Aggregation *aggregation,
637 Priority_Node *node,
638 Priority_Actions *actions,
639 Priority_Remove_handler remove,
640 Priority_Change_handler change,
641 void *arg
642)
643{
644 _Priority_Plain_extract( aggregation, node );
645
646 if ( _Priority_Is_empty( aggregation ) ) {
647 ( *remove )( aggregation, actions, arg );
648 } else {
649 Priority_Node *min;
650
651 /* The aggregation is non-empty, so the minimum node exists. */
652 min = _Priority_Get_minimum_node( aggregation );
653 _Assert( min != NULL );
654
655 if ( node->priority < min->priority ) {
656 aggregation->Node.priority = min->priority;
657 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
658 }
659 }
660}
661
675static inline void _Priority_Extract_non_empty(
676 Priority_Aggregation *aggregation,
677 Priority_Node *node,
678 Priority_Actions *actions,
679 Priority_Change_handler change,
680 void *arg
681)
682{
683 Priority_Node *min;
684
685 _Priority_Plain_extract( aggregation, node );
686 _Assert( !_Priority_Is_empty( aggregation ) );
687
688 min = _Priority_Get_minimum_node( aggregation );
689
690 if ( node->priority < min->priority ) {
691 aggregation->Node.priority = min->priority;
692 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
693 }
694}
695
710static inline void _Priority_Changed(
711 Priority_Aggregation *aggregation,
712 Priority_Node *node,
713 Priority_Group_order group_order,
714 Priority_Actions *actions,
715 Priority_Change_handler change,
716 void *arg
717)
718{
719 Priority_Node *min;
720
721 _Priority_Plain_changed( aggregation, node );
722
723 /*
724 * There is at least the changed node in the aggregation, so the minimum node
725 * exists.
726 */
727 min = _Priority_Get_minimum_node( aggregation );
728 _Assert( min != NULL );
729
730 if ( min->priority != aggregation->Node.priority ) {
731 aggregation->Node.priority = min->priority;
732 ( *change )( aggregation, group_order, actions, arg );
733 }
734}
735
746static inline void _Priority_Replace(
747 Priority_Aggregation *aggregation,
748 Priority_Node *victim,
749 Priority_Node *replacement
750)
751{
752 replacement->priority = victim->priority;
754 &aggregation->Contributors,
755 &victim->Node.RBTree,
756 &replacement->Node.RBTree
757 );
758}
759
762#ifdef __cplusplus
763}
764#endif /* __cplusplus */
765
766#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::@4365 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::@4364 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