source: rtems/cpukit/score/include/rtems/score/chainimpl.h @ 993f5ac

4.115
Last change on this file since 993f5ac was 4cd55724, checked in by Sebastian Huber <sebastian.huber@…>, on 07/26/14 at 10:52:22

Delete unused *_Is_null() functions

  • Property mode set to 100644
File size: 24.0 KB
Line 
1/**
2 * @file
3 *
4 * @brief Chain Handler API
5 */
6
7/*
8 *  Copyright (c) 2010 embedded brains GmbH.
9 *
10 *  COPYRIGHT (c) 1989-2006.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_CHAINIMPL_H
19#define _RTEMS_SCORE_CHAINIMPL_H
20
21#include <rtems/score/chain.h>
22#include <rtems/score/address.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/**
29 * @addtogroup ScoreChain
30 */
31/**@{**/
32
33/**
34 *  @brief Chain initializer for an empty chain with designator @a name.
35 */
36#define CHAIN_INITIALIZER_EMPTY(name) \
37  { { { &(name).Tail.Node, NULL }, &(name).Head.Node } }
38
39/**
40 *  @brief Chain initializer for a chain with one @a node.
41 *
42 *  @see CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN().
43 */
44#define CHAIN_INITIALIZER_ONE_NODE( node ) \
45  { { { (node), NULL }, (node) } }
46
47/**
48 *  @brief Chain node initializer for a @a chain containing exactly this node.
49 *
50 *  @see CHAIN_INITIALIZER_ONE_NODE().
51 */
52#define CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
53  { &(chain)->Tail.Node, &(chain)->Head.Node }
54
55/**
56 *  @brief Chain definition for an empty chain with designator @a name.
57 */
58#define CHAIN_DEFINE_EMPTY(name) \
59  Chain_Control name = CHAIN_INITIALIZER_EMPTY(name)
60
61/**
62 *  @brief Initialize a chain header.
63 *
64 *  This routine initializes @a the_chain structure to manage the
65 *  contiguous array of @a number_nodes nodes which starts at
66 *  @a starting_address.  Each node is of @a node_size bytes.
67 *
68 *  @param[in] the_chain specifies the chain to initialize
69 *  @param[in] starting_address is the starting address of the array
70 *         of elements
71 *  @param[in] number_nodes is the numebr of nodes that will be in the chain
72 *  @param[in] node_size is the size of each node
73 */
74void _Chain_Initialize(
75  Chain_Control *the_chain,
76  void          *starting_address,
77  size_t         number_nodes,
78  size_t         node_size
79);
80
81/**
82 *  @brief Extract the specified node from a chain.
83 *
84 *  This routine extracts @a the_node from the chain on which it resides.
85 *  It disables interrupts to ensure the atomicity of the extract operation.
86 *
87 *  @param[in] the_node is the node to be extracted
88 *
89 *  - INTERRUPT LATENCY:
90 *    + single case
91 */
92void _Chain_Extract(
93  Chain_Node *the_node
94);
95
96/**
97 *  @brief Obtain the first node on a chain.
98 *
99 *  This function removes the first node from @a the_chain and returns
100 *  a pointer to that node.  If @a the_chain is empty, then NULL is returned.
101 *
102 *  @retval This method returns a pointer a node.  If a node was removed,
103 *          then a pointer to that node is returned.  If @a the_chain was
104 *          empty, then NULL is returned.
105 *
106 *  @note It disables interrupts to ensure the atomicity of the get operation.
107 */
108Chain_Node *_Chain_Get(
109  Chain_Control *the_chain
110);
111
112/**
113 *  @brief Insert a node on a chain.
114 *
115 *  This routine inserts @a the_node on a chain immediately following
116 *  @a after_node.
117 *
118 *  @param[in] after_node is the pointer to the node in chain to be
119 *             inserted after
120 *  @param[in] the_node is the pointer to the node to be inserted
121 *
122 *  @note It disables interrupts to ensure the atomicity
123 *  of the insert operation.
124 *
125 *  - INTERRUPT LATENCY:
126 *    + single case
127 */
128void _Chain_Insert(
129  Chain_Node *after_node,
130  Chain_Node *the_node
131);
132
133/**
134 *  @brief Append a node on the end of a chain.
135 *
136 *  This routine appends @a the_node onto the end of @a the_chain.
137 *
138 *  @note It disables interrupts to ensure the atomicity of the
139 *  append operation.
140 */
141void _Chain_Append(
142  Chain_Control *the_chain,
143  Chain_Node    *the_node
144);
145
146/**
147 * @brief Append a node and check if the chain was empty before.
148 *
149 * This routine appends the_node onto the end of the_chain.
150 *
151 * @param[in] the_chain is the chain to be operated upon.
152 * @param[in] the_node is the node to be appended.
153 *
154 * @note It disables interrupts to ensure the atomicity of the append
155 * operation.
156 *
157 * @retval true The chain was empty before.
158 * @retval false The chain contained at least one node before.
159 */
160bool _Chain_Append_with_empty_check(
161  Chain_Control *the_chain,
162  Chain_Node    *the_node
163);
164
165/**
166 * @brief Prepend a node and check if the chain was empty before.
167 *
168 * This routine prepends the_node onto the front of the_chain.
169 *
170 * @param[in] the_chain is the chain to be operated upon.
171 * @param[in] the_node is the node to be prepended.
172 *
173 * @note It disables interrupts to ensure the atomicity of the append
174 * operation.
175 *
176 * @retval true The chain was empty before.
177 * @retval false The chain contained at least one node before.
178 */
179bool _Chain_Prepend_with_empty_check(
180  Chain_Control *the_chain,
181  Chain_Node    *the_node
182);
183
184/**
185 * @brief Get the first node and check if the chain is empty afterwards.
186 *
187 * This function removes the first node from the_chain and returns
188 * a pointer to that node in @a the_node.  If the_chain is empty, then NULL is
189 * returned.
190 *
191 * @param[in] the_chain is the chain to attempt to get the first node from.
192 * @param[out] the_node is the first node on the chain or NULL if the chain is
193 * empty.
194 *
195 * @note It disables interrupts to ensure the atomicity of the append
196 * operation.
197 *
198 * @retval true The chain is empty now.
199 * @retval false The chain contains at least one node now.
200 *
201 *  - INTERRUPT LATENCY:
202 *    + single case
203 */
204bool _Chain_Get_with_empty_check(
205  Chain_Control *the_chain,
206  Chain_Node **the_node
207);
208
209/**
210 * @brief Returns the node count of the chain.
211 *
212 * @param[in] chain The chain.
213 *
214 * @note It does NOT disable interrupts to ensure the atomicity of the
215 * operation.
216 *
217 * @retval The node count of the chain.
218 */
219size_t _Chain_Node_count_unprotected( const Chain_Control *chain );
220
221/**
222 * @brief Set off chain.
223 *
224 * This function sets the next field of the @a node to NULL indicating the @a
225 * node is not part of a chain.
226 *
227 * @param[in] node the node set to off chain.
228 */
229RTEMS_INLINE_ROUTINE void _Chain_Set_off_chain(
230  Chain_Node *node
231)
232{
233  node->next = NULL;
234}
235
236/**
237 * @brief Is the node off chain.
238 *
239 * This function returns true if the @a node is not on a chain.  A @a node is
240 * off chain if the next field is set to NULL.
241 *
242 * @param[in] node is the node off chain.
243 *
244 * @retval true The @a node is off chain.
245 * @retval false The @a node is not off chain.
246 */
247RTEMS_INLINE_ROUTINE bool _Chain_Is_node_off_chain(
248  const Chain_Node *node
249)
250{
251  return node->next == NULL;
252}
253
254/**
255 * @brief Are two nodes equal.
256 *
257 * This function returns true if @a left and @a right are equal,
258 * and false otherwise.
259 *
260 * @param[in] left is the node on the left hand side of the comparison.
261 * @param[in] right is the node on the left hand side of the comparison.
262 *
263 * @retval true @a left and @a right are equal.
264 * @retval false @a left and @a right are not equal.
265 */
266RTEMS_INLINE_ROUTINE bool _Chain_Are_nodes_equal(
267  const Chain_Node *left,
268  const Chain_Node *right
269)
270{
271  return left == right;
272}
273
274/**
275 * @brief Is the chain node pointer NULL.
276 *
277 * This function returns true if the_node is NULL and false otherwise.
278 *
279 * @param[in] the_node is the node pointer to check.
280 *
281 * @retval true @a the_node is @c NULL.
282 * @retval false @a the_node is not @c NULL.
283 */
284RTEMS_INLINE_ROUTINE bool _Chain_Is_null_node(
285  const Chain_Node *the_node
286)
287{
288  return (the_node == NULL);
289}
290
291/**
292 * @brief Return pointer to chain head.
293 *
294 * This function returns a pointer to the head node on the chain.
295 *
296 * @param[in] the_chain is the chain to be operated upon.
297 *
298 * @return This method returns the permanent head node of the chain.
299 */
300RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Head(
301  Chain_Control *the_chain
302)
303{
304  return &the_chain->Head.Node;
305}
306
307/**
308 * @brief Return pointer to immutable chain head.
309 *
310 * This function returns a pointer to the head node on the chain.
311 *
312 * @param[in] the_chain is the chain to be operated upon.
313 *
314 * @return This method returns the permanent head node of the chain.
315 */
316RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_head(
317  const Chain_Control *the_chain
318)
319{
320  return &the_chain->Head.Node;
321}
322
323/**
324 * @brief Return pointer to chain tail.
325 *
326 * This function returns a pointer to the tail node on the chain.
327 *
328 * @param[in] the_chain is the chain to be operated upon.
329 *
330 * @return This method returns the permanent tail node of the chain.
331 */
332RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Tail(
333  Chain_Control *the_chain
334)
335{
336  return &the_chain->Tail.Node;
337}
338
339/**
340 * @brief Return pointer to immutable chain tail.
341 *
342 * This function returns a pointer to the tail node on the chain.
343 *
344 * @param[in] the_chain is the chain to be operated upon.
345 *
346 * @return This method returns the permanent tail node of the chain.
347 */
348RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_tail(
349  const Chain_Control *the_chain
350)
351{
352  return &the_chain->Tail.Node;
353}
354
355/**
356 * @brief Return pointer to chain's first node.
357 *
358 * This function returns a pointer to the first node on the chain after the
359 * head.
360 *
361 * @param[in] the_chain is the chain to be operated upon.
362 *
363 * @return This method returns the first node of the chain.
364 */
365RTEMS_INLINE_ROUTINE Chain_Node *_Chain_First(
366  Chain_Control *the_chain
367)
368{
369  return _Chain_Head( the_chain )->next;
370}
371
372/**
373 * @brief Return pointer to immutable chain's first node.
374 *
375 * This function returns a pointer to the first node on the chain after the
376 * head.
377 *
378 * @param[in] the_chain is the chain to be operated upon.
379 *
380 * @return This method returns the first node of the chain.
381 */
382RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_first(
383  const Chain_Control *the_chain
384)
385{
386  return _Chain_Immutable_head( the_chain )->next;
387}
388
389/**
390 * @brief Return pointer to chain's last node.
391 *
392 * This function returns a pointer to the last node on the chain just before
393 * the tail.
394 *
395 * @param[in] the_chain is the chain to be operated upon.
396 *
397 * @return This method returns the last node of the chain.
398 */
399RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Last(
400  Chain_Control *the_chain
401)
402{
403  return _Chain_Tail( the_chain )->previous;
404}
405
406/**
407 * @brief Return pointer to immutable chain's last node.
408 *
409 * This function returns a pointer to the last node on the chain just before
410 * the tail.
411 *
412 * @param[in] the_chain is the chain to be operated upon.
413 *
414 * @return This method returns the last node of the chain.
415 */
416RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_last(
417  const Chain_Control *the_chain
418)
419{
420  return _Chain_Immutable_tail( the_chain )->previous;
421}
422
423/**
424 * @brief Return pointer the next node from this node.
425 *
426 * This function returns a pointer to the next node after this node.
427 *
428 * @param[in] the_node is the node to be operated upon.
429 *
430 * @return This method returns the next node on the chain.
431 */
432RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Next(
433  Chain_Node *the_node
434)
435{
436  return the_node->next;
437}
438
439/**
440 * @brief Return pointer the immutable next node from this node.
441 *
442 * This function returns a pointer to the next node after this node.
443 *
444 * @param[in] the_node is the node to be operated upon.
445 *
446 * @return This method returns the next node on the chain.
447 */
448RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_next(
449  const Chain_Node *the_node
450)
451{
452  return the_node->next;
453}
454
455/**
456 * @brief Return pointer the previous node from this node.
457 *
458 * This function returns a pointer to the previous node on this chain.
459 *
460 * @param[in] the_node is the node to be operated upon.
461 *
462 * @return This method returns the previous node on the chain.
463 */
464RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Previous(
465  Chain_Node *the_node
466)
467{
468  return the_node->previous;
469}
470
471/**
472 * @brief Return pointer the immutable previous node from this node.
473 *
474 * This function returns a pointer to the previous node on this chain.
475 *
476 * @param[in] the_node is the node to be operated upon.
477 *
478 * @return This method returns the previous node on the chain.
479 */
480RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_previous(
481  const Chain_Node *the_node
482)
483{
484  return the_node->previous;
485}
486
487/**
488 * @brief Is the chain empty.
489 *
490 * This function returns true if there a no nodes on @a the_chain and
491 * false otherwise.
492 *
493 * @param[in] the_chain is the chain to be operated upon.
494 *
495 * @retval true There are no nodes on @a the_chain.
496 * @retval false There are nodes on @a the_chain.
497 */
498RTEMS_INLINE_ROUTINE bool _Chain_Is_empty(
499  const Chain_Control *the_chain
500)
501{
502  return _Chain_Immutable_first( the_chain )
503    == _Chain_Immutable_tail( the_chain );
504}
505
506/**
507 * @brief Is this the first node on the chain.
508 *
509 * This function returns true if the_node is the first node on a chain and
510 * false otherwise.
511 *
512 * @param[in] the_node is the node the caller wants to know if it is
513 *            the first node on a chain.
514 *
515 * @retval true @a the_node is the first node on a chain.
516 * @retval false @a the_node is not the first node on a chain.
517 */
518RTEMS_INLINE_ROUTINE bool _Chain_Is_first(
519  const Chain_Node *the_node
520)
521{
522  return (the_node->previous->previous == NULL);
523}
524
525/**
526 * @brief Is this the last node on the chain.
527 *
528 * This function returns true if @a the_node is the last node on a chain and
529 * false otherwise.
530 *
531 * @param[in] the_node is the node to check as the last node.
532 *
533 * @retval true @a the_node is the last node on a chain.
534 * @retval false @a the_node is not the last node on a chain.
535 */
536RTEMS_INLINE_ROUTINE bool _Chain_Is_last(
537  const Chain_Node *the_node
538)
539{
540  return (the_node->next->next == NULL);
541}
542
543/**
544 * @brief Does this chain have only one node.
545 *
546 * This function returns true if there is only one node on @a the_chain and
547 * false otherwise.
548 *
549 * @param[in] the_chain is the chain to be operated upon.
550 *
551 * @return This function returns true if there is only one node on
552 *         @a the_chain and false otherwise.
553 *
554 * @retval true There is only one node on @a the_chain.
555 * @retval false There is more than one node on @a the_chain.
556 */
557RTEMS_INLINE_ROUTINE bool _Chain_Has_only_one_node(
558  const Chain_Control *the_chain
559)
560{
561  return _Chain_Immutable_first( the_chain )
562    == _Chain_Immutable_last( the_chain );
563}
564
565/**
566 * @brief Is this node the chain head.
567 *
568 * This function returns true if @a the_node is the head of @a the_chain and
569 * false otherwise.
570 *
571 * @param[in] the_chain is the chain to be operated upon.
572 * @param[in] the_node is the node to check for being the Chain Head.
573 *
574 * @retval true @a the_node is the head of @a the_chain.
575 * @retval false @a the_node is not the head of @a the_chain.
576 */
577RTEMS_INLINE_ROUTINE bool _Chain_Is_head(
578  const Chain_Control *the_chain,
579  const Chain_Node    *the_node
580)
581{
582  return (the_node == _Chain_Immutable_head( the_chain ));
583}
584
585/**
586 * @brief Is this node the chail tail.
587 *
588 * This function returns true if @a the_node is the tail of @a the_chain and
589 * false otherwise.
590 *
591 * @param[in] the_chain is the chain to be operated upon.
592 * @param[in] the_node is the node to check for being the Chain Tail.
593 *
594 * @retval true @a the_node is the tail of @a the_chain.
595 * @retval false @a the_node is not the tail of @a the_chain.
596 */
597RTEMS_INLINE_ROUTINE bool _Chain_Is_tail(
598  const Chain_Control *the_chain,
599  const Chain_Node    *the_node
600)
601{
602  return (the_node == _Chain_Immutable_tail( the_chain ));
603}
604
605/**
606 * @brief Initialize this chain as empty.
607 *
608 * This routine initializes the specified chain to contain zero nodes.
609 *
610 * @param[in] the_chain is the chain to be initialized.
611 */
612RTEMS_INLINE_ROUTINE void _Chain_Initialize_empty(
613  Chain_Control *the_chain
614)
615{
616  Chain_Node *head = _Chain_Head( the_chain );
617  Chain_Node *tail = _Chain_Tail( the_chain );
618
619  head->next = tail;
620  head->previous = NULL;
621  tail->previous = head;
622}
623
624/**
625 * @brief Extract this node (unprotected).
626 *
627 * This routine extracts the_node from the chain on which it resides.
628 * It does NOT disable interrupts to ensure the atomicity of the
629 * extract operation.
630 *
631 * @param[in] the_node is the node to be extracted.
632 */
633RTEMS_INLINE_ROUTINE void _Chain_Extract_unprotected(
634  Chain_Node *the_node
635)
636{
637  Chain_Node *next;
638  Chain_Node *previous;
639
640  next           = the_node->next;
641  previous       = the_node->previous;
642  next->previous = previous;
643  previous->next = next;
644}
645
646/**
647 * @brief Get the first node (unprotected).
648 *
649 * This function removes the first node from the_chain and returns
650 * a pointer to that node.  It does NOT disable interrupts to ensure
651 * the atomicity of the get operation.
652 *
653 * @param[in] the_chain is the chain to attempt to get the first node from.
654 *
655 * @return This method returns the first node on the chain even if it is
656 *         the Chain Tail.
657 *
658 * @note This routine assumes that there is at least one node on the chain
659 *       and always returns a node even if it is the Chain Tail.
660 */
661RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_first_unprotected(
662  Chain_Control *the_chain
663)
664{
665  Chain_Node *head = _Chain_Head( the_chain );
666  Chain_Node *old_first = head->next;
667  Chain_Node *new_first = old_first->next;
668
669  head->next = new_first;
670  new_first->previous = head;
671
672  return old_first;
673}
674
675/**
676 * @brief Get the first node (unprotected).
677 *
678 * This function removes the first node from the_chain and returns
679 * a pointer to that node.  If the_chain is empty, then NULL is returned.
680 *
681 * @param[in] the_chain is the chain to attempt to get the first node from.
682 *
683 * @return This method returns the first node on the chain or NULL if the
684 *         chain is empty.
685 *
686 * @note It does NOT disable interrupts to ensure the atomicity of the
687 *       get operation.
688 */
689RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_unprotected(
690  Chain_Control *the_chain
691)
692{
693  if ( !_Chain_Is_empty(the_chain))
694    return _Chain_Get_first_unprotected(the_chain);
695  else
696    return NULL;
697}
698
699/**
700 * @brief Insert a node (unprotected).
701 *
702 * This routine inserts the_node on a chain immediately following
703 * after_node.
704 *
705 * @param[in] after_node is the node which will precede @a the_node on the
706 *            chain.
707 * @param[in] the_node is the node to be inserted.
708 *
709 * @note It does NOT disable interrupts to ensure the atomicity
710 *       of the extract operation.
711 */
712RTEMS_INLINE_ROUTINE void _Chain_Insert_unprotected(
713  Chain_Node *after_node,
714  Chain_Node *the_node
715)
716{
717  Chain_Node *before_node;
718
719  the_node->previous    = after_node;
720  before_node           = after_node->next;
721  after_node->next      = the_node;
722  the_node->next        = before_node;
723  before_node->previous = the_node;
724}
725
726/**
727 * @brief Append a node (unprotected).
728 *
729 * This routine appends the_node onto the end of the_chain.
730 *
731 * @param[in] the_chain is the chain to be operated upon.
732 * @param[in] the_node is the node to be appended.
733 *
734 * @note It does NOT disable interrupts to ensure the atomicity of the
735 *       append operation.
736 */
737RTEMS_INLINE_ROUTINE void _Chain_Append_unprotected(
738  Chain_Control *the_chain,
739  Chain_Node    *the_node
740)
741{
742  Chain_Node *tail = _Chain_Tail( the_chain );
743  Chain_Node *old_last = tail->previous;
744
745  the_node->next = tail;
746  tail->previous = the_node;
747  old_last->next = the_node;
748  the_node->previous = old_last;
749}
750
751/**
752 * @brief Append a node on the end of a chain if the node is in the off chain
753 * state (unprotected).
754 *
755 * @note It does NOT disable interrupts to ensure the atomicity of the
756 *       append operation.
757 *
758 * @see _Chain_Append_unprotected() and _Chain_Is_node_off_chain().
759 */
760RTEMS_INLINE_ROUTINE void _Chain_Append_if_is_off_chain_unprotected(
761  Chain_Control *the_chain,
762  Chain_Node    *the_node
763)
764{
765  if ( _Chain_Is_node_off_chain( the_node ) ) {
766    _Chain_Append_unprotected( the_chain, the_node );
767  }
768}
769
770/**
771 * @brief Prepend a node (unprotected).
772 *
773 * This routine prepends the_node onto the front of the_chain.
774 *
775 * @param[in] the_chain is the chain to be operated upon.
776 * @param[in] the_node is the node to be prepended.
777 *
778 * @note It does NOT disable interrupts to ensure the atomicity of the
779 *       prepend operation.
780 */
781RTEMS_INLINE_ROUTINE void _Chain_Prepend_unprotected(
782  Chain_Control *the_chain,
783  Chain_Node    *the_node
784)
785{
786  _Chain_Insert_unprotected(_Chain_Head(the_chain), the_node);
787}
788
789/**
790 * @brief Prepend a node (protected).
791 *
792 * This routine prepends the_node onto the front of the_chain.
793 *
794 * @param[in] the_chain is the chain to be operated upon.
795 * @param[in] the_node is the node to be prepended.
796 *
797 * @note It disables interrupts to ensure the atomicity of the
798 *       prepend operation.
799 */
800RTEMS_INLINE_ROUTINE void _Chain_Prepend(
801  Chain_Control *the_chain,
802  Chain_Node    *the_node
803)
804{
805  _Chain_Insert(_Chain_Head(the_chain), the_node);
806}
807
808/**
809 * @brief Append a node and check if the chain was empty before (unprotected).
810 *
811 * This routine appends the_node onto the end of the_chain.
812 *
813 * @param[in] the_chain is the chain to be operated upon.
814 * @param[in] the_node is the node to be appended.
815 *
816 * @note It does NOT disable interrupts to ensure the atomicity of the
817 *       append operation.
818 *
819 * @retval true The chain was empty before.
820 * @retval false The chain contained at least one node before.
821 */
822RTEMS_INLINE_ROUTINE bool _Chain_Append_with_empty_check_unprotected(
823  Chain_Control *the_chain,
824  Chain_Node    *the_node
825)
826{
827  bool was_empty = _Chain_Is_empty( the_chain );
828
829  _Chain_Append_unprotected( the_chain, the_node );
830
831  return was_empty;
832}
833
834/**
835 * @brief Prepend a node and check if the chain was empty before (unprotected).
836 *
837 * This routine prepends the_node onto the front of the_chain.
838 *
839 * @param[in] the_chain is the chain to be operated upon.
840 * @param[in] the_node is the node to be prepended.
841 *
842 * @note It does NOT disable interrupts to ensure the atomicity of the
843 *       prepend operation.
844 *
845 * @retval true The chain was empty before.
846 * @retval false The chain contained at least one node before.
847 */
848RTEMS_INLINE_ROUTINE bool _Chain_Prepend_with_empty_check_unprotected(
849  Chain_Control *the_chain,
850  Chain_Node    *the_node
851)
852{
853  bool was_empty = _Chain_Is_empty( the_chain );
854
855  _Chain_Prepend_unprotected( the_chain, the_node );
856
857  return was_empty;
858}
859
860/**
861 * @brief Get the first node and check if the chain is empty afterwards
862 * (unprotected).
863 *
864 * This function removes the first node from the_chain and returns
865 * a pointer to that node in @a the_node.  If the_chain is empty, then NULL is
866 * returned.
867 *
868 * @param[in] the_chain is the chain to attempt to get the first node from.
869 * @param[out] the_node is the first node on the chain or NULL if the chain is
870 * empty.
871 *
872 * @note It does NOT disable interrupts to ensure the atomicity of the
873 *       get operation.
874 *
875 * @retval true The chain is empty now.
876 * @retval false The chain contains at least one node now.
877 */
878RTEMS_INLINE_ROUTINE bool _Chain_Get_with_empty_check_unprotected(
879  Chain_Control *the_chain,
880  Chain_Node **the_node
881)
882{
883  bool is_empty_now = true;
884  Chain_Node *head = _Chain_Head( the_chain );
885  Chain_Node *tail = _Chain_Tail( the_chain );
886  Chain_Node *old_first = head->next;
887
888  if ( old_first != tail ) {
889    Chain_Node *new_first = old_first->next;
890
891    head->next = new_first;
892    new_first->previous = head;
893
894    *the_node = old_first;
895
896    is_empty_now = new_first == tail;
897  } else
898    *the_node = NULL;
899
900  return is_empty_now;
901}
902
903/**
904 * @brief Chain node order.
905 *
906 * @param[in] left The left node.
907 * @param[in] right The right node.
908 *
909 * @retval true According to the order the left node precedes the right node.
910 * @retval false Otherwise.
911 */
912typedef bool ( *Chain_Node_order )(
913  const Chain_Node *left,
914  const Chain_Node *right
915);
916
917/**
918 * @brief Inserts a node into the chain according to the order relation.
919 *
920 * After the operation the chain contains the node to insert and the order
921 * relation holds for all nodes from the head up to the inserted node.  Nodes
922 * after the inserted node are not moved.
923 *
924 * @param[in,out] chain The chain.
925 * @param[in,out] to_insert The node to insert.
926 * @param[in] order The order relation.
927 */
928RTEMS_INLINE_ROUTINE void _Chain_Insert_ordered_unprotected(
929  Chain_Control *chain,
930  Chain_Node *to_insert,
931  Chain_Node_order order
932)
933{
934  const Chain_Node *tail = _Chain_Immutable_tail( chain );
935  Chain_Node *next = _Chain_First( chain );
936
937  while ( next != tail && !( *order )( to_insert, next ) ) {
938    next = _Chain_Next( next );
939  }
940
941  _Chain_Insert_unprotected( _Chain_Previous( next ), to_insert );
942}
943
944/** @} */
945
946#ifdef __cplusplus
947}
948#endif
949
950#endif
951/* end of include file */
Note: See TracBrowser for help on using the repository browser.