source: rtems/cpukit/sapi/include/rtems/chain.h @ 23de794d

4.11
Last change on this file since 23de794d was 23de794d, checked in by Sebastian Huber <sebastian.huber@…>, on Aug 26, 2013 at 12:27:52 PM

score: Add and use CHAIN_INITIALIZER_ONE_NODE().

Add and use CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN(),
RTEMS_CHAIN_INITIALIZER_ONE_NODE() and
RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN().

  • Property mode set to 100644
File size: 19.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Chain API
5 */
6
7/*
8 *  Copyright (c) 2010 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.com/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  CHAIN_DEFINE_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( the_chain, starting_address, number_nodes, node_size );
154}
155
156/**
157 * @brief Initialize this chain as empty.
158 *
159 * This routine initializes the specified chain to contain zero nodes.
160 *
161 * @param[in] the_chain is the chain to be initialized.
162 */
163RTEMS_INLINE_ROUTINE void rtems_chain_initialize_empty(
164  rtems_chain_control *the_chain
165)
166{
167  _Chain_Initialize_empty( the_chain );
168}
169
170/**
171 * @brief Set off chain.
172 *
173 * This function sets the next and previous fields of the @a node to NULL
174 * indicating the @a node is not part of a chain.
175 *
176 * @param[in] node the node set to off chain.
177 */
178RTEMS_INLINE_ROUTINE void rtems_chain_set_off_chain(
179  rtems_chain_node *node
180)
181{
182  _Chain_Set_off_chain( node );
183}
184
185/**
186 * @brief Is the node off chain.
187 *
188 * This function returns true if the @a node is not on a chain. A @a node is
189 * off chain if the next and previous fields are set to NULL.
190 *
191 * @param[in] node is the node off chain.
192 *
193 * @retval true The node is off chain.
194 * @retval false The node is not off chain.
195 */
196RTEMS_INLINE_ROUTINE bool rtems_chain_is_node_off_chain(
197  const rtems_chain_node *node
198)
199{
200  return _Chain_Is_node_off_chain( node );
201}
202
203/**
204 * @brief Is the chain node pointer NULL.
205 *
206 * This function returns true if the_node is NULL and false otherwise.
207 *
208 * @param[in] the_node is the node pointer to check.
209 *
210 * @retval true The chain node pointer is NULL.
211 * @retval false The chain node pointer is not NULL.
212 */
213RTEMS_INLINE_ROUTINE bool rtems_chain_is_null_node(
214  const rtems_chain_node *the_node
215)
216{
217  return _Chain_Is_null_node( the_node );
218}
219
220/**
221 * @brief Return pointer to Chain Head
222 *
223 * This function returns a pointer to the first node on the chain.
224 *
225 * @param[in] the_chain is the chain to be operated upon.
226 *
227 * @return This method returns the permanent node of the chain.
228 */
229RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_head(
230  rtems_chain_control *the_chain
231)
232{
233  return _Chain_Head( the_chain );
234}
235
236/**
237 * @brief Return pointer to immutable Chain Head
238 *
239 * This function returns a pointer to the head node on the chain.
240 *
241 * @param[in] the_chain is the chain to be operated upon.
242 *
243 * @return This method returns the permanent head node of the chain.
244 */
245RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_head(
246  const rtems_chain_control *the_chain
247)
248{
249  return _Chain_Immutable_head( the_chain );
250}
251
252/**
253 * @brief Return pointer to Chain Tail
254 *
255 * This function returns a pointer to the tail node on the chain.
256 *
257 * @param[in] the_chain is the chain to be operated upon.
258 *
259 * @return This method returns the permanent tail node of the chain.
260 */
261RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_tail(
262  rtems_chain_control *the_chain
263)
264{
265  return _Chain_Tail( the_chain );
266}
267
268/**
269 * @brief Return pointer to immutable Chain Tail
270 *
271 * This function returns a pointer to the tail node on the chain.
272 *
273 * @param[in] the_chain is the chain to be operated upon.
274 *
275 * @return This method returns the permanent tail node of the chain.
276 */
277RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_tail(
278  const rtems_chain_control *the_chain
279)
280{
281  return _Chain_Immutable_tail( the_chain );
282}
283
284/**
285 * @brief Return pointer to Chain's First node after the permanent head.
286 *
287 * This function returns a pointer to the first node on the chain after the
288 * head.
289 *
290 * @param[in] the_chain is the chain to be operated upon.
291 *
292 * @return This method returns the first node of the chain.
293 */
294RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_first(
295  rtems_chain_control *the_chain
296)
297{
298  return _Chain_First( the_chain );
299}
300
301/**
302 * @brief Return pointer to immutable Chain's First node
303 *
304 * This function returns a pointer to the first node on the chain after the
305 * head.
306 *
307 * @param[in] the_chain is the chain to be operated upon.
308 *
309 * @return This method returns the first node of the chain.
310 */
311RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_first(
312  const rtems_chain_control *the_chain
313)
314{
315  return _Chain_Immutable_first( the_chain );
316}
317
318/**
319 * @brief Return pointer to Chain's Last node before the permanent tail.
320 *
321 * This function returns a pointer to the last node on the chain just before
322 * the tail.
323 *
324 * @param[in] the_chain is the chain to be operated upon.
325 *
326 * @return This method returns the last node of the chain.
327 */
328RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_last(
329  rtems_chain_control *the_chain
330)
331{
332  return _Chain_Last( the_chain );
333}
334
335/**
336 * @brief Return pointer to immutable Chain's Last node
337 *
338 * This function returns a pointer to the last node on the chain just before
339 * the tail.
340 *
341 * @param[in] the_chain is the chain to be operated upon.
342 *
343 * @return This method returns the last node of the chain.
344 */
345RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_last(
346  const rtems_chain_control *the_chain
347)
348{
349  return _Chain_Immutable_last( the_chain );
350}
351
352/**
353 * @brief Return pointer the next node from this node
354 *
355 * This function returns a pointer to the next node after this node.
356 *
357 * @param[in] the_node is the node to be operated upon.
358 *
359 * @return This method returns the next node on the chain.
360 */
361RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_next(
362  rtems_chain_node *the_node
363)
364{
365  return _Chain_Next( the_node );
366}
367
368/**
369 * @brief Return pointer the immutable next node from this node
370 *
371 * This function returns a pointer to the next node after this node.
372 *
373 * @param[in] the_node is the node to be operated upon.
374 *
375 * @return This method returns the next node on the chain.
376 */
377RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_next(
378  const rtems_chain_node *the_node
379)
380{
381  return _Chain_Immutable_next( the_node );
382}
383
384/**
385 * @brief Return pointer the previous node from this node
386 *
387 * This function returns a pointer to the previous node on this chain.
388 *
389 * @param[in] the_node is the node to be operated upon.
390 *
391 * @return This method returns the previous node on the chain.
392 */
393RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_previous(
394  rtems_chain_node *the_node
395)
396{
397  return _Chain_Previous( the_node );
398}
399
400/**
401 * @brief Return pointer the immutable previous node from this node.
402 *
403 * This function returns a pointer to the previous node on this chain.
404 *
405 * @param[in] the_node is the node to be operated upon.
406 *
407 * @return This method returns the previous node on the chain.
408 */
409RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_previous(
410  const rtems_chain_node *the_node
411)
412{
413  return _Chain_Immutable_previous( the_node );
414}
415
416/**
417 * @brief Are Two nodes equal.
418 *
419 * This function returns true if @a left and @a right are equal,
420 * and false otherwise.
421 *
422 * @param[in] left is the node on the left hand side of the comparison.
423 * @param[in] right is the node on the left hand side of the comparison.
424 *
425 * @retval true @a left is equal to @a right.
426 * @retval false @a left is not equal to @a right
427 */
428RTEMS_INLINE_ROUTINE bool rtems_chain_are_nodes_equal(
429  const rtems_chain_node *left,
430  const rtems_chain_node *right
431)
432{
433  return _Chain_Are_nodes_equal( left, right );
434}
435
436/**
437 * @brief Is the chain empty
438 *
439 * This function returns true if there a no nodes on @a the_chain and
440 * false otherwise.
441 *
442 * @param[in] the_chain is the chain to be operated upon.
443 *
444 * @retval true The chain is empty.
445 * @retval false The chain is not empty.
446 */
447RTEMS_INLINE_ROUTINE bool rtems_chain_is_empty(
448  const rtems_chain_control *the_chain
449)
450{
451  return _Chain_Is_empty( the_chain );
452}
453
454/**
455 * @brief Is this the first node on the chain.
456 *
457 * This function returns true if the_node is the first node on a chain and
458 * false otherwise.
459 *
460 * @param[in] the_node is the node the caller wants to know if it is
461 *            the first node on a chain.
462 *
463 * @retval true @a the_node is the first node on a chain.
464 * @retval false @a the_node is not the first node on a chain.
465 */
466RTEMS_INLINE_ROUTINE bool rtems_chain_is_first(
467  const rtems_chain_node *the_node
468)
469{
470  return _Chain_Is_first( the_node );
471}
472
473/**
474 * @brief Is this the last node on the chain.
475 *
476 * This function returns true if @a the_node is the last node on a chain and
477 * false otherwise.
478 *
479 * @param[in] the_node is the node to check as the last node.
480 *
481 * @retval true @a the_node is the last node on a chain.
482 * @retval false @a the_node is not the last node on a chain
483 */
484RTEMS_INLINE_ROUTINE bool rtems_chain_is_last(
485  const rtems_chain_node *the_node
486)
487{
488  return _Chain_Is_last( the_node );
489}
490
491/**
492 * @brief Does this chain have only one node.
493 *
494 * This function returns true if there is only one node on @a the_chain and
495 * false otherwise.
496 *
497 * @param[in] the_chain is the chain to be operated upon.
498 *
499 * @retval true The chain has only one node.
500 * @retval false The chain has more than one nodes.
501 */
502RTEMS_INLINE_ROUTINE bool rtems_chain_has_only_one_node(
503  const rtems_chain_control *the_chain
504)
505{
506  return _Chain_Has_only_one_node( the_chain );
507}
508
509/**
510 * @brief Is this node the chain head.
511 *
512 * This function returns true if @a the_node is the head of the_chain and
513 * false otherwise.
514 *
515 * @param[in] the_chain is the chain to be operated upon.
516 * @param[in] the_node is the node to check for being the Chain Head.
517 *
518 * @retval true @a the_node is the head of @a the_chain.
519 * @retval false @a the_node is not the head of @a the_chain.
520 */
521RTEMS_INLINE_ROUTINE bool rtems_chain_is_head(
522  const rtems_chain_control *the_chain,
523  const rtems_chain_node *the_node
524)
525{
526  return _Chain_Is_head( the_chain, the_node );
527}
528
529/**
530 * @brief Is this node the chain tail.
531 *
532 * This function returns true if the_node is the tail of the_chain and
533 * false otherwise.
534 *
535 * @param[in] the_chain is the chain to be operated upon.
536 * @param[in] the_node is the node to check for being the Chain Tail.
537 *
538 * @retval true @a the_node is the tail of @a the_chain.
539 * @retval false @a the_node is not the tail of @a the_chain.
540 */
541RTEMS_INLINE_ROUTINE bool rtems_chain_is_tail(
542  const rtems_chain_control *the_chain,
543  const rtems_chain_node *the_node
544)
545{
546  return _Chain_Is_tail( the_chain, the_node );
547}
548
549/**
550 * @brief Extract the specified node from a chain.
551 *
552 * This routine extracts @a the_node from the chain on which it resides.
553 * It disables interrupts to ensure the atomicity of the
554 * extract operation.
555 *
556 * @arg the_node specifies the node to extract
557 */
558RTEMS_INLINE_ROUTINE void rtems_chain_extract(
559  rtems_chain_node *the_node
560)
561{
562  _Chain_Extract( the_node );
563}
564
565/**
566 * @brief Extract the specified node from a chain (unprotected).
567 *
568 * This routine extracts @a the_node from the chain on which it resides.
569 *
570 * NOTE: It does NOT disable interrupts to ensure the atomicity of the
571 * append operation.
572 */
573RTEMS_INLINE_ROUTINE void rtems_chain_extract_unprotected(
574  rtems_chain_node *the_node
575)
576{
577  _Chain_Extract_unprotected( the_node );
578}
579
580/**
581 * @brief Obtain the first node on a chain.
582 *
583 * This function removes the first node from @a the_chain and returns
584 * a pointer to that node.  If @a the_chain is empty, then NULL is returned.
585 *
586 * @return This method returns a pointer a node.  If a node was removed,
587 *         then a pointer to that node is returned.  If @a the_chain was
588 *         empty, then NULL is returned.
589 *
590 *  NOTE: It disables interrupts to ensure the atomicity of the get operation.
591 */
592RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get(
593  rtems_chain_control *the_chain
594)
595{
596  return _Chain_Get( the_chain );
597}
598
599/**
600 * @brief See _Chain_Get_unprotected().
601 */
602RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get_unprotected(
603  rtems_chain_control *the_chain
604)
605{
606  return _Chain_Get_unprotected( the_chain );
607}
608
609/**
610 * @brief Insert a node on a chain
611 *
612 * This routine inserts @a the_node on a chain immediately following
613 * @a after_node. 
614 *
615 * NOTE: It disables interrupts to ensure the atomicity
616 * of the extract operation.
617 */
618RTEMS_INLINE_ROUTINE void rtems_chain_insert(
619  rtems_chain_node *after_node,
620  rtems_chain_node *the_node
621)
622{
623  _Chain_Insert( after_node, the_node );
624}
625
626/**
627 * @brief See _Chain_Insert_unprotected().
628 */
629RTEMS_INLINE_ROUTINE void rtems_chain_insert_unprotected(
630  rtems_chain_node *after_node,
631  rtems_chain_node *the_node
632)
633{
634  _Chain_Insert_unprotected( after_node, the_node );
635}
636
637/**
638 * @brief Append a node on the end of a chain.
639 *
640 * This routine appends @a the_node onto the end of @a the_chain.
641 *
642 * NOTE: It disables interrupts to ensure the atomicity of the
643 * append operation.
644 */
645RTEMS_INLINE_ROUTINE void rtems_chain_append(
646  rtems_chain_control *the_chain,
647  rtems_chain_node    *the_node
648)
649{
650  _Chain_Append( the_chain, the_node );
651}
652
653/**
654 * @brief Append a node on the end of a chain (unprotected).
655 *
656 * This routine appends @a the_node onto the end of @a the_chain.
657 *
658 * NOTE: It does NOT disable interrupts to ensure the atomicity of the
659 * append operation.
660 */
661RTEMS_INLINE_ROUTINE void rtems_chain_append_unprotected(
662  rtems_chain_control *the_chain,
663  rtems_chain_node    *the_node
664)
665{
666  _Chain_Append_unprotected( the_chain, the_node );
667}
668
669/**
670 * @brief Prepend a node.
671 *
672 * This routine prepends the_node onto the front of the_chain.
673 *
674 * @param[in] the_chain is the chain to be operated upon.
675 * @param[in] the_node is the node to be prepended.
676 *
677 * NOTE: It disables interrupts to ensure the atomicity of the
678 *       prepend operation.
679 */
680RTEMS_INLINE_ROUTINE void rtems_chain_prepend(
681  rtems_chain_control *the_chain,
682  rtems_chain_node    *the_node
683)
684{
685  _Chain_Prepend( the_chain, 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 */
715RTEMS_INLINE_ROUTINE bool rtems_chain_append_with_empty_check(
716  rtems_chain_control *chain,
717  rtems_chain_node *node
718)
719{
720  return _Chain_Append_with_empty_check( chain, node );
721}
722
723/**
724 * @brief Checks if the @a chain is empty and prepends the @a node.
725 *
726 * Interrupts are disabled to ensure the atomicity of the operation.
727 *
728 * @retval true The chain was empty before the prepend.
729 * @retval false The chain contained at least one node before the prepend.
730 */
731RTEMS_INLINE_ROUTINE bool rtems_chain_prepend_with_empty_check(
732  rtems_chain_control *chain,
733  rtems_chain_node *node
734)
735{
736  return _Chain_Prepend_with_empty_check( chain, node );
737}
738
739/**
740 * @brief Tries to get the first @a node and check if the @a chain is empty
741 * afterwards.
742 *
743 * This function removes the first node from the @a chain and returns a pointer
744 * to that node in @a node.  If the @a chain is empty, then @c NULL is returned.
745 *
746 * Interrupts are disabled to ensure the atomicity of the operation.
747 *
748 * @retval true The chain is empty after the node removal.
749 * @retval false The chain contained at least one node after the node removal.
750 */
751RTEMS_INLINE_ROUTINE bool rtems_chain_get_with_empty_check(
752  rtems_chain_control *chain,
753  rtems_chain_node **node
754)
755{
756  return _Chain_Get_with_empty_check( chain, node );
757}
758
759/**
760 * @brief Returns the node count of the chain.
761 *
762 * @param[in] chain The chain.
763 *
764 * @note It does NOT disable interrupts to ensure the atomicity of the
765 * operation.
766 *
767 * @return The node count of the chain.
768 */
769RTEMS_INLINE_ROUTINE size_t rtems_chain_node_count_unprotected(
770  const rtems_chain_control *chain
771)
772{
773  return _Chain_Node_count_unprotected( chain );
774}
775
776/** @} */
777
778#ifdef __cplusplus
779}
780#endif
781
782#endif
783/* end of include file */
Note: See TracBrowser for help on using the repository browser.