RTEMS 6.1-rc2
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 aggregation->Action.next = actions->actions;
163#endif
164 actions->actions = aggregation;
165}
166
173static inline void _Priority_Node_initialize(
174 Priority_Node *node,
175 Priority_Control priority
176)
177{
178 node->priority = priority;
179 _RBTree_Initialize_node( &node->Node.RBTree );
180}
181
188static inline void _Priority_Node_set_priority(
189 Priority_Node *node,
190 Priority_Control priority
191)
192{
193 node->priority = priority;
194}
195
201static inline void _Priority_Node_set_inactive(
202 Priority_Node *node
203)
204{
205 _RBTree_Set_off_tree( &node->Node.RBTree );
206}
207
216static inline bool _Priority_Node_is_active(
217 const Priority_Node *node
218)
219{
220 return !_RBTree_Is_node_off_tree( &node->Node.RBTree );
221}
222
228static inline void _Priority_Initialize_empty(
229 Priority_Aggregation *aggregation
230)
231{
232#if defined(RTEMS_DEBUG)
233#if defined(RTEMS_SMP)
234 aggregation->Action.next = NULL;
235#endif
236 aggregation->Action.node = NULL;
237 aggregation->Action.type = PRIORITY_ACTION_INVALID;
238#endif
239 _RBTree_Initialize_node( &aggregation->Node.Node.RBTree );
240 _RBTree_Initialize_empty( &aggregation->Contributors );
241}
242
249static inline void _Priority_Initialize_one(
250 Priority_Aggregation *aggregation,
251 Priority_Node *node
252)
253{
254#if defined(RTEMS_DEBUG)
255#if defined(RTEMS_SMP)
256 aggregation->Action.next = NULL;
257#endif
258 aggregation->Action.node = NULL;
259 aggregation->Action.type = PRIORITY_ACTION_INVALID;
260#endif
261 _Priority_Node_initialize( &aggregation->Node, node->priority );
262 _RBTree_Initialize_one( &aggregation->Contributors, &node->Node.RBTree );
263}
264
273static inline bool _Priority_Is_empty(
274 const Priority_Aggregation *aggregation
275)
276{
277 return _RBTree_Is_empty( &aggregation->Contributors );
278}
279
287static inline Priority_Control _Priority_Get_priority(
288 const Priority_Aggregation *aggregation
289)
290{
291 return aggregation->Node.priority;
292}
293
301static inline const Scheduler_Control *_Priority_Get_scheduler(
302 const Priority_Aggregation *aggregation
303)
304{
305#if defined(RTEMS_SMP)
306 return aggregation->scheduler;
307#else
308 return &_Scheduler_Table[ 0 ];
309#endif
310}
311
319static inline Priority_Node *_Priority_Get_minimum_node(
320 const Priority_Aggregation *aggregation
321)
322{
323 return (Priority_Node *) _RBTree_Minimum( &aggregation->Contributors );
324}
325
332static inline void _Priority_Set_action_node(
333 Priority_Aggregation *aggregation,
334 Priority_Node *node
335)
336{
337 aggregation->Action.node = node;
338}
339
346static inline void _Priority_Set_action_type(
347 Priority_Aggregation *aggregation,
349)
350{
351 aggregation->Action.type = type;
352}
353
362static inline void _Priority_Set_action(
363 Priority_Aggregation *aggregation,
364 Priority_Node *node,
366)
367{
368 aggregation->Action.node = node;
369 aggregation->Action.type = type;
370}
371
372#if defined(RTEMS_SMP)
381static inline Priority_Aggregation *_Priority_Get_next_action(
382 const Priority_Aggregation *aggregation
383)
384{
385 return aggregation->Action.next;
386}
387#endif
388
398static inline bool _Priority_Less(
399 const void *left,
400 const RBTree_Node *right
401)
402{
403 const Priority_Control *the_left;
404 const Priority_Node *the_right;
405
406 the_left = (const Priority_Control *) left;
407 the_right = RTEMS_CONTAINER_OF( right, Priority_Node, Node.RBTree );
408
409 return *the_left < the_right->priority;
410}
411
425static inline bool _Priority_Plain_insert(
426 Priority_Aggregation *aggregation,
427 Priority_Node *node,
428 Priority_Control priority
429)
430{
431 return _RBTree_Insert_inline(
432 &aggregation->Contributors,
433 &node->Node.RBTree,
434 &priority,
435 _Priority_Less
436 );
437}
438
447static inline void _Priority_Plain_extract(
448 Priority_Aggregation *aggregation,
449 Priority_Node *node
450)
451{
452 _RBTree_Extract( &aggregation->Contributors, &node->Node.RBTree );
453}
454
464static inline void _Priority_Plain_changed(
465 Priority_Aggregation *aggregation,
466 Priority_Node *node
467)
468{
469 _Priority_Plain_extract( aggregation, node );
470 _Priority_Plain_insert( aggregation, node, node->priority );
471}
472
473typedef void ( *Priority_Add_handler )(
474 Priority_Aggregation *aggregation,
475 Priority_Actions *actions,
476 void *arg
477);
478
479typedef void ( *Priority_Change_handler )(
480 Priority_Aggregation *aggregation,
481 Priority_Group_order group_order,
482 Priority_Actions *actions,
483 void *arg
484);
485
486typedef void ( *Priority_Remove_handler )(
487 Priority_Aggregation *aggregation,
488 Priority_Actions *actions,
489 void *arg
490);
491
502static inline void _Priority_Change_nothing(
503 Priority_Aggregation *aggregation,
504 Priority_Group_order group_order,
505 Priority_Actions *actions,
506 void *arg
507)
508{
509 (void) aggregation;
510 (void) group_order;
511 (void) actions;
512 (void) arg;
513}
514
524static inline void _Priority_Remove_nothing(
525 Priority_Aggregation *aggregation,
526 Priority_Actions *actions,
527 void *arg
528)
529{
530 (void) aggregation;
531 (void) actions;
532 (void) arg;
533}
534
548static inline void _Priority_Non_empty_insert(
549 Priority_Aggregation *aggregation,
550 Priority_Node *node,
551 Priority_Actions *actions,
552 Priority_Change_handler change,
553 void *arg
554)
555{
556 bool is_new_minimum;
557
558 _Assert( !_Priority_Is_empty( aggregation ) );
559 is_new_minimum = _Priority_Plain_insert( aggregation, node, node->priority );
560
561 if ( is_new_minimum ) {
562 aggregation->Node.priority = node->priority;
563 ( *change )( aggregation, PRIORITY_GROUP_LAST, actions, arg );
564 }
565}
566
579static inline void _Priority_Insert(
580 Priority_Aggregation *aggregation,
581 Priority_Node *node,
582 Priority_Actions *actions,
583 Priority_Add_handler add,
584 Priority_Change_handler change,
585 void *arg
586)
587{
588 if ( _Priority_Is_empty( aggregation ) ) {
589 _Priority_Initialize_one( aggregation, node );
590 ( *add )( aggregation, actions, arg );
591 } else {
592 _Priority_Non_empty_insert( aggregation, node, actions, change, arg );
593 }
594}
595
613static inline void _Priority_Extract(
614 Priority_Aggregation *aggregation,
615 Priority_Node *node,
616 Priority_Actions *actions,
617 Priority_Remove_handler remove,
618 Priority_Change_handler change,
619 void *arg
620)
621{
622 _Priority_Plain_extract( aggregation, node );
623
624 if ( _Priority_Is_empty( aggregation ) ) {
625 ( *remove )( aggregation, actions, arg );
626 } else {
627 Priority_Node *min;
628
629 /* The aggregation is non-empty, so the minimum node exists. */
630 min = _Priority_Get_minimum_node( aggregation );
631 _Assert( min != NULL );
632
633 if ( node->priority < min->priority ) {
634 aggregation->Node.priority = min->priority;
635 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
636 }
637 }
638}
639
653static inline void _Priority_Extract_non_empty(
654 Priority_Aggregation *aggregation,
655 Priority_Node *node,
656 Priority_Actions *actions,
657 Priority_Change_handler change,
658 void *arg
659)
660{
661 Priority_Node *min;
662
663 _Priority_Plain_extract( aggregation, node );
664 _Assert( !_Priority_Is_empty( aggregation ) );
665
666 min = _Priority_Get_minimum_node( aggregation );
667
668 if ( node->priority < min->priority ) {
669 aggregation->Node.priority = min->priority;
670 ( *change )( aggregation, PRIORITY_GROUP_FIRST, actions, arg );
671 }
672}
673
688static inline void _Priority_Changed(
689 Priority_Aggregation *aggregation,
690 Priority_Node *node,
691 Priority_Group_order group_order,
692 Priority_Actions *actions,
693 Priority_Change_handler change,
694 void *arg
695)
696{
697 Priority_Node *min;
698
699 _Priority_Plain_changed( aggregation, node );
700
701 /*
702 * There is at least the changed node in the aggregation, so the minimum node
703 * exists.
704 */
705 min = _Priority_Get_minimum_node( aggregation );
706 _Assert( min != NULL );
707
708 if ( min->priority != aggregation->Node.priority ) {
709 aggregation->Node.priority = min->priority;
710 ( *change )( aggregation, group_order, actions, arg );
711 }
712}
713
724static inline void _Priority_Replace(
725 Priority_Aggregation *aggregation,
726 Priority_Node *victim,
727 Priority_Node *replacement
728)
729{
730 replacement->priority = victim->priority;
732 &aggregation->Contributors,
733 &victim->Node.RBTree,
734 &replacement->Node.RBTree
735 );
736}
737
740#ifdef __cplusplus
741}
742#endif /* __cplusplus */
743
744#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.
#define NULL
Requests a GPIO pin group configuration.
Definition: xil_types.h:54
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
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
struct Priority_Aggregation::@4382 Action
A priority action block to manage priority node additions, changes and removals.
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
Priority_Control priority
The priority value of this node.
Definition: priority.h:124
union Priority_Node::@4381 Node
Node component for a chain or red-black tree.
Red-black tree node.
Definition: rbtree.h:73
Scheduler control.
Definition: scheduler.h:335