source: rtems/cpukit/sapi/include/rtems/chain.h @ 3cdda03

5
Last change on this file since 3cdda03 was d995a263, checked in by Sebastian Huber <sebastian.huber@…>, on 04/04/16 at 07:37:15

score: Delete _Chain_Append()

This function is not used in the score.

Update #2555.

  • Property mode set to 100644
File size: 19.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Chain API
5 */
6
7/*
8 *  Copyright (c) 2010-2014 embedded brains GmbH.
9 *
10 *  COPYRIGHT (c) 1989-2008.
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_CHAIN_H
19#define _RTEMS_CHAIN_H
20
21#include <rtems/score/chainimpl.h>
22#include <rtems/rtems/event.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/**
29 * @defgroup ClassicChains Chains
30 *
31 * @ingroup ClassicRTEMS
32 *
33 * @brief Chain API
34 */
35/**@{**/
36
37typedef Chain_Node rtems_chain_node;
38
39typedef Chain_Control rtems_chain_control;
40
41/**
42 *  @brief Chain initializer for an empty chain with designator @a name.
43 */
44#define RTEMS_CHAIN_INITIALIZER_EMPTY( name ) \
45  CHAIN_INITIALIZER_EMPTY( name )
46
47/**
48 *  @brief Chain initializer for a chain with one @a node.
49 *
50 *  @see RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN().
51 */
52#define RTEMS_CHAIN_INITIALIZER_ONE_NODE( node ) \
53  CHAIN_INITIALIZER_ONE_NODE( node )
54
55/**
56 *  @brief Chain node initializer for a @a chain containing exactly this node.
57 *
58 *  @see RTEMS_CHAIN_INITIALIZER_ONE_NODE().
59 */
60#define RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
61  CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain )
62
63/**
64 *  @brief Chain definition for an empty chain with designator @a name.
65 */
66#define RTEMS_CHAIN_DEFINE_EMPTY( name ) \
67  rtems_chain_control name = RTEMS_CHAIN_INITIALIZER_EMPTY( name )
68
69/**
70 * @brief Appends the @a node to the @a chain and sends the @a events to the
71 * @a task if the @a chain was empty before the append.
72 *
73 * @see rtems_chain_append_with_empty_check() and rtems_event_send().
74 *
75 * @retval RTEMS_SUCCESSFUL Successful operation.
76 * @retval RTEMS_INVALID_ID No such task.
77 */
78rtems_status_code rtems_chain_append_with_notification(
79  rtems_chain_control *chain,
80  rtems_chain_node *node,
81  rtems_id task,
82  rtems_event_set events
83);
84
85/**
86 * @brief Prepends the @a node to the @a chain and sends the @a events to the
87 * @a task if the @a chain was empty before the prepend.
88 *
89 * @see rtems_chain_prepend_with_empty_check() and rtems_event_send().
90 *
91 * @retval RTEMS_SUCCESSFUL Successful operation.
92 * @retval RTEMS_INVALID_ID No such task.
93 */
94rtems_status_code rtems_chain_prepend_with_notification(
95  rtems_chain_control *chain,
96  rtems_chain_node *node,
97  rtems_id task,
98  rtems_event_set events
99);
100
101/**
102 * @brief Gets the first @a node of the @a chain and sends the @a events to the
103 * @a task if the @a chain is empty after the get.
104 *
105 * @see rtems_chain_get_with_empty_check() and rtems_event_send().
106 *
107 * @retval RTEMS_SUCCESSFUL Successful operation.
108 * @retval RTEMS_INVALID_ID No such task.
109 */
110rtems_status_code rtems_chain_get_with_notification(
111  rtems_chain_control *chain,
112  rtems_id task,
113  rtems_event_set events,
114  rtems_chain_node **node
115);
116
117/**
118 * @brief Gets the first @a node of the @a chain and sends the @a events to the
119 * @a task if the @a chain is empty afterwards.
120 *
121 * @see rtems_chain_get() and rtems_event_receive().
122 *
123 * @retval RTEMS_SUCCESSFUL Successful operation.
124 * @retval RTEMS_TIMEOUT Timeout.
125 */
126rtems_status_code rtems_chain_get_with_wait(
127  rtems_chain_control *chain,
128  rtems_event_set events,
129  rtems_interval timeout,
130  rtems_chain_node **node
131);
132
133/**
134 * @brief Initialize a chain Header.
135 *
136 * This routine initializes @a the_chain structure to manage the
137 * contiguous array of @a number_nodes nodes which starts at
138 * @a starting_address.  Each node is of @a node_size bytes.
139 *
140 * @param[in] the_chain specifies the chain to initialize
141 * @param[in] starting_address is the starting address of the array
142 *        of elements
143 * @param[in] number_nodes is the number of nodes that will be in the chain
144 * @param[in] node_size is the size of each node
145 */
146RTEMS_INLINE_ROUTINE void rtems_chain_initialize(
147  rtems_chain_control *the_chain,
148  void                *starting_address,
149  size_t               number_nodes,
150  size_t               node_size
151)
152{
153  _Chain_Initialize(
154    the_chain,
155    starting_address,
156    number_nodes,
157    node_size
158  );
159}
160
161/**
162 * @brief Initialize this chain as empty.
163 *
164 * This routine initializes the specified chain to contain zero nodes.
165 *
166 * @param[in] the_chain is the chain to be initialized.
167 */
168RTEMS_INLINE_ROUTINE void rtems_chain_initialize_empty(
169  rtems_chain_control *the_chain
170)
171{
172  _Chain_Initialize_empty( the_chain );
173}
174
175/**
176 * @brief Set off chain.
177 *
178 * This function sets the next and previous fields of the @a node to NULL
179 * indicating the @a node is not part of a chain.
180 *
181 * @param[in] node the node set to off chain.
182 */
183RTEMS_INLINE_ROUTINE void rtems_chain_set_off_chain(
184  rtems_chain_node *node
185)
186{
187  _Chain_Set_off_chain( node );
188}
189
190/**
191 * @brief Is the node off chain.
192 *
193 * This function returns true if the @a node is not on a chain. A @a node is
194 * off chain if the next and previous fields are set to NULL.
195 *
196 * @param[in] node is the node off chain.
197 *
198 * @retval true The node is off chain.
199 * @retval false The node is not off chain.
200 */
201RTEMS_INLINE_ROUTINE bool rtems_chain_is_node_off_chain(
202  const rtems_chain_node *node
203)
204{
205  return _Chain_Is_node_off_chain( node );
206}
207
208/**
209 * @brief Is the chain node pointer NULL.
210 *
211 * This function returns true if the_node is NULL and false otherwise.
212 *
213 * @param[in] the_node is the node pointer to check.
214 *
215 * @retval true The chain node pointer is NULL.
216 * @retval false The chain node pointer is not NULL.
217 */
218RTEMS_INLINE_ROUTINE bool rtems_chain_is_null_node(
219  const rtems_chain_node *the_node
220)
221{
222  return _Chain_Is_null_node( the_node );
223}
224
225/**
226 * @brief Return pointer to Chain Head
227 *
228 * This function returns a pointer to the first node on the chain.
229 *
230 * @param[in] the_chain is the chain to be operated upon.
231 *
232 * @return This method returns the permanent node of the chain.
233 */
234RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_head(
235  rtems_chain_control *the_chain
236)
237{
238  return _Chain_Head( the_chain );
239}
240
241/**
242 * @brief Return pointer to immutable Chain Head
243 *
244 * This function returns a pointer to the head node on the chain.
245 *
246 * @param[in] the_chain is the chain to be operated upon.
247 *
248 * @return This method returns the permanent head node of the chain.
249 */
250RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_head(
251  const rtems_chain_control *the_chain
252)
253{
254  return _Chain_Immutable_head( the_chain );
255}
256
257/**
258 * @brief Return pointer to Chain Tail
259 *
260 * This function returns a pointer to the tail node on the chain.
261 *
262 * @param[in] the_chain is the chain to be operated upon.
263 *
264 * @return This method returns the permanent tail node of the chain.
265 */
266RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_tail(
267  rtems_chain_control *the_chain
268)
269{
270  return _Chain_Tail( the_chain );
271}
272
273/**
274 * @brief Return pointer to immutable Chain Tail
275 *
276 * This function returns a pointer to the tail node on the chain.
277 *
278 * @param[in] the_chain is the chain to be operated upon.
279 *
280 * @return This method returns the permanent tail node of the chain.
281 */
282RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_tail(
283  const rtems_chain_control *the_chain
284)
285{
286  return _Chain_Immutable_tail( the_chain );
287}
288
289/**
290 * @brief Return pointer to Chain's First node after the permanent head.
291 *
292 * This function returns a pointer to the first node on the chain after the
293 * head.
294 *
295 * @param[in] the_chain is the chain to be operated upon.
296 *
297 * @return This method returns the first node of the chain.
298 */
299RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_first(
300  rtems_chain_control *the_chain
301)
302{
303  return _Chain_First( the_chain );
304}
305
306/**
307 * @brief Return pointer to immutable Chain's First node
308 *
309 * This function returns a pointer to the first node on the chain after the
310 * head.
311 *
312 * @param[in] the_chain is the chain to be operated upon.
313 *
314 * @return This method returns the first node of the chain.
315 */
316RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_first(
317  const rtems_chain_control *the_chain
318)
319{
320  return _Chain_Immutable_first( the_chain );
321}
322
323/**
324 * @brief Return pointer to Chain's Last node before the permanent tail.
325 *
326 * This function returns a pointer to the last node on the chain just before
327 * the tail.
328 *
329 * @param[in] the_chain is the chain to be operated upon.
330 *
331 * @return This method returns the last node of the chain.
332 */
333RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_last(
334  rtems_chain_control *the_chain
335)
336{
337  return _Chain_Last( the_chain );
338}
339
340/**
341 * @brief Return pointer to immutable Chain's Last node
342 *
343 * This function returns a pointer to the last node on the chain just before
344 * the tail.
345 *
346 * @param[in] the_chain is the chain to be operated upon.
347 *
348 * @return This method returns the last node of the chain.
349 */
350RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_last(
351  const rtems_chain_control *the_chain
352)
353{
354  return _Chain_Immutable_last( the_chain );
355}
356
357/**
358 * @brief Return pointer the next node from this node
359 *
360 * This function returns a pointer to the next node after this node.
361 *
362 * @param[in] the_node is the node to be operated upon.
363 *
364 * @return This method returns the next node on the chain.
365 */
366RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_next(
367  rtems_chain_node *the_node
368)
369{
370  return _Chain_Next( the_node );
371}
372
373/**
374 * @brief Return pointer the immutable next node from this node
375 *
376 * This function returns a pointer to the next node after this node.
377 *
378 * @param[in] the_node is the node to be operated upon.
379 *
380 * @return This method returns the next node on the chain.
381 */
382RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_next(
383  const rtems_chain_node *the_node
384)
385{
386  return _Chain_Immutable_next( the_node );
387}
388
389/**
390 * @brief Return pointer the previous node from this node
391 *
392 * This function returns a pointer to the previous node on this chain.
393 *
394 * @param[in] the_node is the node to be operated upon.
395 *
396 * @return This method returns the previous node on the chain.
397 */
398RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_previous(
399  rtems_chain_node *the_node
400)
401{
402  return _Chain_Previous( the_node );
403}
404
405/**
406 * @brief Return pointer the immutable previous node from this node.
407 *
408 * This function returns a pointer to the previous node on this chain.
409 *
410 * @param[in] the_node is the node to be operated upon.
411 *
412 * @return This method returns the previous node on the chain.
413 */
414RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_previous(
415  const rtems_chain_node *the_node
416)
417{
418  return _Chain_Immutable_previous( the_node );
419}
420
421/**
422 * @brief Are Two nodes equal.
423 *
424 * This function returns true if @a left and @a right are equal,
425 * and false otherwise.
426 *
427 * @param[in] left is the node on the left hand side of the comparison.
428 * @param[in] right is the node on the left hand side of the comparison.
429 *
430 * @retval true @a left is equal to @a right.
431 * @retval false @a left is not equal to @a right
432 */
433RTEMS_INLINE_ROUTINE bool rtems_chain_are_nodes_equal(
434  const rtems_chain_node *left,
435  const rtems_chain_node *right
436)
437{
438  return _Chain_Are_nodes_equal( left, right );
439}
440
441/**
442 * @brief Is the chain empty
443 *
444 * This function returns true if there a no nodes on @a the_chain and
445 * false otherwise.
446 *
447 * @param[in] the_chain is the chain to be operated upon.
448 *
449 * @retval true The chain is empty.
450 * @retval false The chain is not empty.
451 */
452RTEMS_INLINE_ROUTINE bool rtems_chain_is_empty(
453  const rtems_chain_control *the_chain
454)
455{
456  return _Chain_Is_empty( the_chain );
457}
458
459/**
460 * @brief Is this the first node on the chain.
461 *
462 * This function returns true if the_node is the first node on a chain and
463 * false otherwise.
464 *
465 * @param[in] the_node is the node the caller wants to know if it is
466 *            the first node on a chain.
467 *
468 * @retval true @a the_node is the first node on a chain.
469 * @retval false @a the_node is not the first node on a chain.
470 */
471RTEMS_INLINE_ROUTINE bool rtems_chain_is_first(
472  const rtems_chain_node *the_node
473)
474{
475  return _Chain_Is_first( the_node );
476}
477
478/**
479 * @brief Is this the last node on the chain.
480 *
481 * This function returns true if @a the_node is the last node on a chain and
482 * false otherwise.
483 *
484 * @param[in] the_node is the node to check as the last node.
485 *
486 * @retval true @a the_node is the last node on a chain.
487 * @retval false @a the_node is not the last node on a chain
488 */
489RTEMS_INLINE_ROUTINE bool rtems_chain_is_last(
490  const rtems_chain_node *the_node
491)
492{
493  return _Chain_Is_last( the_node );
494}
495
496/**
497 * @brief Does this chain have only one node.
498 *
499 * This function returns true if there is only one node on @a the_chain and
500 * false otherwise.
501 *
502 * @param[in] the_chain is the chain to be operated upon.
503 *
504 * @retval true The chain has only one node.
505 * @retval false The chain has more than one nodes.
506 */
507RTEMS_INLINE_ROUTINE bool rtems_chain_has_only_one_node(
508  const rtems_chain_control *the_chain
509)
510{
511  return _Chain_Has_only_one_node( the_chain );
512}
513
514/**
515 * @brief Is this node the chain head.
516 *
517 * This function returns true if @a the_node is the head of the_chain and
518 * false otherwise.
519 *
520 * @param[in] the_chain is the chain to be operated upon.
521 * @param[in] the_node is the node to check for being the Chain Head.
522 *
523 * @retval true @a the_node is the head of @a the_chain.
524 * @retval false @a the_node is not the head of @a the_chain.
525 */
526RTEMS_INLINE_ROUTINE bool rtems_chain_is_head(
527  const rtems_chain_control *the_chain,
528  const rtems_chain_node *the_node
529)
530{
531  return _Chain_Is_head( the_chain, the_node );
532}
533
534/**
535 * @brief Is this node the chain tail.
536 *
537 * This function returns true if the_node is the tail of the_chain and
538 * false otherwise.
539 *
540 * @param[in] the_chain is the chain to be operated upon.
541 * @param[in] the_node is the node to check for being the Chain Tail.
542 *
543 * @retval true @a the_node is the tail of @a the_chain.
544 * @retval false @a the_node is not the tail of @a the_chain.
545 */
546RTEMS_INLINE_ROUTINE bool rtems_chain_is_tail(
547  const rtems_chain_control *the_chain,
548  const rtems_chain_node *the_node
549)
550{
551  return _Chain_Is_tail( the_chain, the_node );
552}
553
554/**
555 * @brief Extract the specified node from a chain.
556 *
557 * This routine extracts @a the_node from the chain on which it resides.
558 * It disables interrupts to ensure the atomicity of the
559 * extract operation.
560 *
561 * @arg the_node specifies the node to extract
562 */
563void rtems_chain_extract(
564  rtems_chain_node *the_node
565);
566
567/**
568 * @brief Extract the specified node from a chain (unprotected).
569 *
570 * This routine extracts @a the_node from the chain on which it resides.
571 *
572 * NOTE: It does NOT disable interrupts to ensure the atomicity of the
573 * append operation.
574 */
575RTEMS_INLINE_ROUTINE void rtems_chain_extract_unprotected(
576  rtems_chain_node *the_node
577)
578{
579  _Chain_Extract_unprotected( the_node );
580}
581
582/**
583 * @brief Obtain the first node on a chain.
584 *
585 * This function removes the first node from @a the_chain and returns
586 * a pointer to that node.  If @a the_chain is empty, then NULL is returned.
587 *
588 * @return This method returns a pointer a node.  If a node was removed,
589 *         then a pointer to that node is returned.  If @a the_chain was
590 *         empty, then NULL is returned.
591 *
592 *  NOTE: It disables interrupts to ensure the atomicity of the get operation.
593 */
594rtems_chain_node *rtems_chain_get(
595  rtems_chain_control *the_chain
596);
597
598/**
599 * @brief See _Chain_Get_unprotected().
600 */
601RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get_unprotected(
602  rtems_chain_control *the_chain
603)
604{
605  return _Chain_Get_unprotected( the_chain );
606}
607
608/**
609 * @brief See _Chain_Get_first_unprotected().
610 */
611RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get_first_unprotected(
612  rtems_chain_control *the_chain
613)
614{
615  return _Chain_Get_first_unprotected( the_chain );
616}
617
618/**
619 * @brief Insert a node on a chain
620 *
621 * This routine inserts @a the_node on a chain immediately following
622 * @a after_node. 
623 *
624 * NOTE: It disables interrupts to ensure the atomicity
625 * of the extract operation.
626 */
627void rtems_chain_insert(
628  rtems_chain_node *after_node,
629  rtems_chain_node *the_node
630);
631
632/**
633 * @brief See _Chain_Insert_unprotected().
634 */
635RTEMS_INLINE_ROUTINE void rtems_chain_insert_unprotected(
636  rtems_chain_node *after_node,
637  rtems_chain_node *the_node
638)
639{
640  _Chain_Insert_unprotected( after_node, the_node );
641}
642
643/**
644 * @brief Append a node on the end of a chain.
645 *
646 * This routine appends @a the_node onto the end of @a the_chain.
647 *
648 * NOTE: It disables interrupts to ensure the atomicity of the
649 * append operation.
650 */
651void rtems_chain_append(
652  rtems_chain_control *the_chain,
653  rtems_chain_node    *the_node
654);
655
656/**
657 * @brief Append a node on the end of a chain (unprotected).
658 *
659 * This routine appends @a the_node onto the end of @a the_chain.
660 *
661 * NOTE: It does NOT disable interrupts to ensure the atomicity of the
662 * append operation.
663 */
664RTEMS_INLINE_ROUTINE void rtems_chain_append_unprotected(
665  rtems_chain_control *the_chain,
666  rtems_chain_node    *the_node
667)
668{
669  _Chain_Append_unprotected( the_chain, the_node );
670}
671
672/**
673 * @brief Prepend a node.
674 *
675 * This routine prepends the_node onto the front of the_chain.
676 *
677 * @param[in] the_chain is the chain to be operated upon.
678 * @param[in] the_node is the node to be prepended.
679 *
680 * NOTE: It disables interrupts to ensure the atomicity of the
681 *       prepend operation.
682 */
683void rtems_chain_prepend(
684  rtems_chain_control *the_chain,
685  rtems_chain_node    *the_node
686);
687
688/**
689 * @brief Prepend a node (unprotected).
690 *
691 * This routine prepends the_node onto the front of the_chain.
692 *
693 * @param[in] the_chain is the chain to be operated upon.
694 * @param[in] the_node is the node to be prepended.
695 *
696 * NOTE: It does NOT disable interrupts to ensure the atomicity of the
697 *       prepend operation.
698 */
699RTEMS_INLINE_ROUTINE void rtems_chain_prepend_unprotected(
700  rtems_chain_control *the_chain,
701  rtems_chain_node    *the_node
702)
703{
704  _Chain_Prepend_unprotected( the_chain, the_node );
705}
706
707/**
708 * @brief Checks if the @a chain is empty and appends the @a node.
709 *
710 * Interrupts are disabled to ensure the atomicity of the operation.
711 *
712 * @retval true The chain was empty before the append.
713 * @retval false The chain contained at least one node before the append.
714 */
715bool rtems_chain_append_with_empty_check(
716  rtems_chain_control *chain,
717  rtems_chain_node *node
718);
719
720/**
721 * @brief Checks if the @a chain is empty and prepends the @a node.
722 *
723 * Interrupts are disabled to ensure the atomicity of the operation.
724 *
725 * @retval true The chain was empty before the prepend.
726 * @retval false The chain contained at least one node before the prepend.
727 */
728bool rtems_chain_prepend_with_empty_check(
729  rtems_chain_control *chain,
730  rtems_chain_node *node
731);
732
733/**
734 * @brief Tries to get the first @a node and check if the @a chain is empty
735 * afterwards.
736 *
737 * This function removes the first node from the @a chain and returns a pointer
738 * to that node in @a node.  If the @a chain is empty, then @c NULL is returned.
739 *
740 * Interrupts are disabled to ensure the atomicity of the operation.
741 *
742 * @retval true The chain is empty after the node removal.
743 * @retval false The chain contained at least one node after the node removal.
744 */
745bool rtems_chain_get_with_empty_check(
746  rtems_chain_control *chain,
747  rtems_chain_node **node
748);
749
750/**
751 * @brief Returns the node count of the chain.
752 *
753 * @param[in] chain The chain.
754 *
755 * @note It does NOT disable interrupts to ensure the atomicity of the
756 * operation.
757 *
758 * @return The node count of the chain.
759 */
760RTEMS_INLINE_ROUTINE size_t rtems_chain_node_count_unprotected(
761  const rtems_chain_control *chain
762)
763{
764  return _Chain_Node_count_unprotected( chain );
765}
766
767/** @} */
768
769#ifdef __cplusplus
770}
771#endif
772
773#endif
774/* end of include file */
Note: See TracBrowser for help on using the repository browser.