40#ifndef _RTEMS_SCORE_CHAINIMPL_H
41#define _RTEMS_SCORE_CHAINIMPL_H
59#define CHAIN_INITIALIZER_EMPTY(name) \
60 { { { &(name).Tail.Node, NULL }, &(name).Head.Node } }
67#define CHAIN_INITIALIZER_ONE_NODE( node ) \
68 { { { (node), NULL }, (node) } }
75#define CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
76 { &(chain)->Tail.Node, &(chain)->Head.Node }
81#define CHAIN_DEFINE_EMPTY(name) \
82 Chain_Control name = CHAIN_INITIALIZER_EMPTY(name)
99 void *starting_address,
124static inline void _Chain_Set_off_chain(
129#if defined(RTEMS_DEBUG)
142static inline void _Chain_Initialize_node(
Chain_Node *the_node )
144#if defined(RTEMS_DEBUG)
145 _Chain_Set_off_chain( the_node );
162static inline bool _Chain_Is_node_off_chain(
const Chain_Node *node )
164 if ( node->
next == NULL ) {
165#if defined( RTEMS_DEBUG )
187static inline bool _Chain_Are_nodes_equal(
192 return left == right;
208 return &the_chain->Head.Node;
220static inline const Chain_Node *_Chain_Immutable_head(
224 return &the_chain->Head.Node;
240 return &the_chain->Tail.Node;
252static inline const Chain_Node *_Chain_Immutable_tail(
256 return &the_chain->Tail.Node;
273 return _Chain_Immutable_head( the_chain )->
next;
286static inline const Chain_Node *_Chain_Immutable_first(
290 return _Chain_Immutable_head( the_chain )->
next;
307 return _Chain_Immutable_tail( the_chain )->
previous;
320static inline const Chain_Node *_Chain_Immutable_last(
324 return _Chain_Immutable_tail( the_chain )->
previous;
340 return the_node->next;
352static inline const Chain_Node *_Chain_Immutable_next(
356 return the_node->next;
372 return the_node->previous;
384static inline const Chain_Node *_Chain_Immutable_previous(
388 return the_node->previous;
402static inline bool _Chain_Is_empty(
406 return _Chain_Immutable_first( the_chain )
407 == _Chain_Immutable_tail( the_chain );
422static inline bool _Chain_Is_first(
426 return (the_node->previous->previous == NULL);
441static inline bool _Chain_Is_last(
445 return (the_node->next->next == NULL);
459static inline bool _Chain_Has_only_one_node(
463 return _Chain_Immutable_first( the_chain )
464 == _Chain_Immutable_last( the_chain );
479static inline bool _Chain_Is_head(
484 return (the_node == _Chain_Immutable_head( the_chain ));
499static inline bool _Chain_Is_tail(
504 return (the_node == _Chain_Immutable_tail( the_chain ));
514static inline void _Chain_Initialize_empty(
523 head = _Chain_Head( the_chain );
524 tail = _Chain_Tail( the_chain );
537static inline void _Chain_Initialize_one(
545 _Assert( _Chain_Is_node_off_chain( the_node ) );
547 head = _Chain_Head( the_chain );
548 tail = _Chain_Tail( the_chain );
550 the_node->next = tail;
551 the_node->previous = head;
553 head->
next = the_node;
567static inline void _Chain_Extract_unprotected(
574 _Assert( !_Chain_Is_node_off_chain( the_node ) );
576 next = the_node->next;
577 previous = the_node->previous;
578 next->previous = previous;
579 previous->
next = next;
581#if defined(RTEMS_DEBUG)
582 _Chain_Set_off_chain( the_node );
601static inline Chain_Node *_Chain_Get_first_unprotected(
609 _Assert( !_Chain_Is_empty( the_chain ) );
611 head = _Chain_Head( the_chain );
612 old_first = head->
next;
613 new_first = old_first->
next;
615 head->
next = new_first;
618#if defined(RTEMS_DEBUG)
619 _Chain_Set_off_chain( old_first );
639static inline Chain_Node *_Chain_Get_unprotected(
643 if ( !_Chain_Is_empty(the_chain))
644 return _Chain_Get_first_unprotected(the_chain);
662static inline void _Chain_Insert_unprotected(
669 _Assert( _Chain_Is_node_off_chain( the_node ) );
671 the_node->previous = after_node;
672 before_node = after_node->
next;
673 after_node->
next = the_node;
674 the_node->next = before_node;
689static inline void _Chain_Append_unprotected(
697 _Assert( _Chain_Is_node_off_chain( the_node ) );
699 tail = _Chain_Tail( the_chain );
702 the_node->next = tail;
704 old_last->
next = the_node;
705 the_node->previous = old_last;
720static inline void _Chain_Append_if_is_off_chain_unprotected(
725 if ( _Chain_Is_node_off_chain( the_node ) ) {
726 _Chain_Append_unprotected( the_chain, the_node );
741static inline void _Chain_Prepend_unprotected(
746 _Chain_Insert_unprotected(_Chain_Head(the_chain), the_node);
763static inline bool _Chain_Append_with_empty_check_unprotected(
768 bool was_empty = _Chain_Is_empty( the_chain );
770 _Chain_Append_unprotected( the_chain, the_node );
789static inline bool _Chain_Prepend_with_empty_check_unprotected(
794 bool was_empty = _Chain_Is_empty( the_chain );
796 _Chain_Prepend_unprotected( the_chain, the_node );
819static inline bool _Chain_Get_with_empty_check_unprotected(
824 bool is_empty_now =
true;
829 if ( old_first != tail ) {
832 head->
next = new_first;
835 *the_node = old_first;
837 is_empty_now = new_first == tail;
874static inline void _Chain_Insert_ordered_unprotected(
881 const Chain_Node *tail = _Chain_Immutable_tail( the_chain );
882 Chain_Node *previous = _Chain_Head( the_chain );
885 while ( next != tail && !( *order )( key, to_insert, next ) ) {
887 next = _Chain_Next( next );
890 _Chain_Insert_unprotected( previous, to_insert );
955#define CHAIN_ITERATOR_REGISTRY_INITIALIZER( name ) \
956 { CHAIN_INITIALIZER_EMPTY( name.Iterators ) }
963static inline void _Chain_Iterator_registry_initialize(
967 _Chain_Initialize_empty( &the_registry->Iterators );
982static inline void _Chain_Iterator_registry_update(
990 iter_node = _Chain_Head( &the_registry->Iterators );
991 iter_tail = _Chain_Tail( &the_registry->Iterators );
993 while ( ( iter_node = _Chain_Next( iter_node ) ) != iter_tail ) {
998 if ( iter->
position == the_node_to_extract ) {
1000 iter->
position = _Chain_Previous( the_node_to_extract );
1002 iter->
position = _Chain_Next( the_node_to_extract );
1071static inline void _Chain_Iterator_initialize(
1079 _Chain_Append_unprotected(
1080 &the_registry->Iterators,
1087 the_iterator->
position = _Chain_Head( the_chain );
1089 the_iterator->
position = _Chain_Tail( the_chain );
1103static inline Chain_Node *_Chain_Iterator_next(
1108 return _Chain_Next( the_iterator->
position );
1110 return _Chain_Previous( the_iterator->
position );
1120static inline void _Chain_Iterator_set_position(
1135static inline void _Chain_Iterator_destroy(
This header file provides the interfaces of the Assert Handler.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG and static analysis runs.
Definition: assert.h:96
size_t _Chain_Node_count_unprotected(const Chain_Control *chain)
Returns the node count of the chain.
Definition: chainnodecount.c:42
void _Chain_Initialize(Chain_Control *the_chain, void *starting_address, size_t number_nodes, size_t node_size)
Initializes a chain header.
Definition: chain.c:46
bool(* Chain_Node_order)(const void *key, const Chain_Node *left, const Chain_Node *right)
Chain node order.
Definition: chainimpl.h:853
Chain_Iterator_direction
The chain iterator direction.
Definition: chainimpl.h:896
@ CHAIN_ITERATOR_BACKWARD
Iteration from tail to head.
Definition: chainimpl.h:905
@ CHAIN_ITERATOR_FORWARD
Iteration from head to tail.
Definition: chainimpl.h:900
This header file provides interfaces of the Chain Handler which are used by the implementation and th...
A registry for chain iterators.
Definition: chainimpl.h:946
A chain iterator which is updated during node extraction if it is properly registered.
Definition: chainimpl.h:914
Chain_Node * position
The current position of this iterator.
Definition: chainimpl.h:937
Chain_Node Registry_node
Node for registration.
Definition: chainimpl.h:920
Chain_Iterator_direction direction
The direction of this iterator.
Definition: chainimpl.h:927
This structure represents a chain node.
Definition: chain.h:78
struct Chain_Node * next
Definition: chain.h:80
struct Chain_Node * previous
Definition: chain.h:82
This union represents a chain control block.
Definition: chain.h:96