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(
166 return node->
next == NULL;
181static inline bool _Chain_Are_nodes_equal(
186 return left == right;
202 return &the_chain->Head.Node;
214static inline const Chain_Node *_Chain_Immutable_head(
218 return &the_chain->Head.Node;
234 return &the_chain->Tail.Node;
246static inline const Chain_Node *_Chain_Immutable_tail(
250 return &the_chain->Tail.Node;
267 return _Chain_Immutable_head( the_chain )->
next;
280static inline const Chain_Node *_Chain_Immutable_first(
284 return _Chain_Immutable_head( the_chain )->
next;
301 return _Chain_Immutable_tail( the_chain )->
previous;
314static inline const Chain_Node *_Chain_Immutable_last(
318 return _Chain_Immutable_tail( the_chain )->
previous;
334 return the_node->next;
346static inline const Chain_Node *_Chain_Immutable_next(
350 return the_node->next;
366 return the_node->previous;
378static inline const Chain_Node *_Chain_Immutable_previous(
382 return the_node->previous;
396static inline bool _Chain_Is_empty(
400 return _Chain_Immutable_first( the_chain )
401 == _Chain_Immutable_tail( the_chain );
416static inline bool _Chain_Is_first(
420 return (the_node->previous->previous == NULL);
435static inline bool _Chain_Is_last(
439 return (the_node->next->next == NULL);
453static inline bool _Chain_Has_only_one_node(
457 return _Chain_Immutable_first( the_chain )
458 == _Chain_Immutable_last( the_chain );
473static inline bool _Chain_Is_head(
478 return (the_node == _Chain_Immutable_head( the_chain ));
493static inline bool _Chain_Is_tail(
498 return (the_node == _Chain_Immutable_tail( the_chain ));
508static inline void _Chain_Initialize_empty(
517 head = _Chain_Head( the_chain );
518 tail = _Chain_Tail( the_chain );
521 head->previous = NULL;
531static inline void _Chain_Initialize_one(
539 _Assert( _Chain_Is_node_off_chain( the_node ) );
541 head = _Chain_Head( the_chain );
542 tail = _Chain_Tail( the_chain );
544 the_node->next = tail;
545 the_node->previous = head;
547 head->next = the_node;
548 head->previous = NULL;
561static inline void _Chain_Extract_unprotected(
568 _Assert( !_Chain_Is_node_off_chain( the_node ) );
570 next = the_node->next;
571 previous = the_node->previous;
572 next->previous = previous;
573 previous->
next = next;
575#if defined(RTEMS_DEBUG)
576 _Chain_Set_off_chain( the_node );
595static inline Chain_Node *_Chain_Get_first_unprotected(
603 _Assert( !_Chain_Is_empty( the_chain ) );
605 head = _Chain_Head( the_chain );
606 old_first = head->next;
607 new_first = old_first->
next;
609 head->next = new_first;
612#if defined(RTEMS_DEBUG)
613 _Chain_Set_off_chain( old_first );
633static inline Chain_Node *_Chain_Get_unprotected(
637 if ( !_Chain_Is_empty(the_chain))
638 return _Chain_Get_first_unprotected(the_chain);
656static inline void _Chain_Insert_unprotected(
663 _Assert( _Chain_Is_node_off_chain( the_node ) );
665 the_node->previous = after_node;
666 before_node = after_node->
next;
667 after_node->
next = the_node;
668 the_node->next = before_node;
683static inline void _Chain_Append_unprotected(
691 _Assert( _Chain_Is_node_off_chain( the_node ) );
693 tail = _Chain_Tail( the_chain );
696 the_node->next = tail;
698 old_last->
next = the_node;
699 the_node->previous = old_last;
714static inline void _Chain_Append_if_is_off_chain_unprotected(
719 if ( _Chain_Is_node_off_chain( the_node ) ) {
720 _Chain_Append_unprotected( the_chain, the_node );
735static inline void _Chain_Prepend_unprotected(
740 _Chain_Insert_unprotected(_Chain_Head(the_chain), the_node);
757static inline bool _Chain_Append_with_empty_check_unprotected(
762 bool was_empty = _Chain_Is_empty( the_chain );
764 _Chain_Append_unprotected( the_chain, the_node );
783static inline bool _Chain_Prepend_with_empty_check_unprotected(
788 bool was_empty = _Chain_Is_empty( the_chain );
790 _Chain_Prepend_unprotected( the_chain, the_node );
813static inline bool _Chain_Get_with_empty_check_unprotected(
818 bool is_empty_now =
true;
823 if ( old_first != tail ) {
826 head->next = new_first;
829 *the_node = old_first;
831 is_empty_now = new_first == tail;
868static inline void _Chain_Insert_ordered_unprotected(
875 const Chain_Node *tail = _Chain_Immutable_tail( the_chain );
876 Chain_Node *previous = _Chain_Head( the_chain );
879 while ( next != tail && !( *order )( key, to_insert, next ) ) {
881 next = _Chain_Next( next );
884 _Chain_Insert_unprotected( previous, to_insert );
949#define CHAIN_ITERATOR_REGISTRY_INITIALIZER( name ) \
950 { CHAIN_INITIALIZER_EMPTY( name.Iterators ) }
957static inline void _Chain_Iterator_registry_initialize(
961 _Chain_Initialize_empty( &the_registry->Iterators );
976static inline void _Chain_Iterator_registry_update(
984 iter_node = _Chain_Head( &the_registry->Iterators );
985 iter_tail = _Chain_Tail( &the_registry->Iterators );
987 while ( ( iter_node = _Chain_Next( iter_node ) ) != iter_tail ) {
992 if ( iter->
position == the_node_to_extract ) {
994 iter->
position = _Chain_Previous( the_node_to_extract );
996 iter->
position = _Chain_Next( the_node_to_extract );
1065static inline void _Chain_Iterator_initialize(
1073 _Chain_Append_unprotected(
1074 &the_registry->Iterators,
1081 the_iterator->
position = _Chain_Head( the_chain );
1083 the_iterator->
position = _Chain_Tail( the_chain );
1097static inline Chain_Node *_Chain_Iterator_next(
1102 return _Chain_Next( the_iterator->
position );
1104 return _Chain_Previous( the_iterator->
position );
1114static inline void _Chain_Iterator_set_position(
1129static 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:847
Chain_Iterator_direction
The chain iterator direction.
Definition: chainimpl.h:890
@ CHAIN_ITERATOR_BACKWARD
Iteration from tail to head.
Definition: chainimpl.h:899
@ CHAIN_ITERATOR_FORWARD
Iteration from head to tail.
Definition: chainimpl.h:894
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:940
A chain iterator which is updated during node extraction if it is properly registered.
Definition: chainimpl.h:908
Chain_Node * position
The current position of this iterator.
Definition: chainimpl.h:931
Chain_Node Registry_node
Node for registration.
Definition: chainimpl.h:914
Chain_Iterator_direction direction
The direction of this iterator.
Definition: chainimpl.h:921
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