source: rtems-docs/c-user/chains.rst @ 42d50d7

5
Last change on this file since 42d50d7 was 4da4a15, checked in by Chris Johns <chrisj@…>, on 11/09/16 at 00:42:10

c-user: Fix header levels. Minor fixes.

  • Property mode set to 100644
File size: 19.4 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. COMMENT: Copyright 2014 Gedare Bloom.
4.. COMMENT: All rights reserved.
5
6Chains
7******
8
9.. index:: chains
10
11Introduction
12============
13
14The Chains API is an interface to the Super Core (score) chain
15implementation. The Super Core uses chains for all list type functions. This
16includes wait queues and task queues. The Chains API provided by RTEMS is:
17
18- rtems_chain_initialize_ - initialize the chain with nodes
19
20- rtems_chain_initialize_empty_ - initialize the chain as empty
21
22- rtems_chain_is_null_node_ - Is the node NULL ?
23
24- rtems_chain_head_ - Return the chain's head
25
26- rtems_chain_tail_ - Return the chain's tail
27
28- rtems_chain_are_nodes_equal_ - Are the node's equal ?
29
30- rtems_chain_is_empty_ - Is the chain empty ?
31
32- rtems_chain_is_first_ - Is the Node the first in the chain ?
33
34- rtems_chain_is_last_ - Is the Node the last in the chain ?
35
36- rtems_chain_has_only_one_node_ - Does the node have one node ?
37
38- rtems_chain_node_count_unprotected_ - Returns the node count of the chain (unprotected)
39
40- rtems_chain_is_head_ - Is the node the head ?
41
42- rtems_chain_is_tail_ - Is the node the tail ?
43
44- rtems_chain_extract_ - Extract the node from the chain
45
46- rtems_chain_extract_unprotected_ - Extract the node from the chain (unprotected)
47
48- rtems_chain_get_ - Return the first node on the chain
49
50- rtems_chain_get_unprotected_ - Return the first node on the chain (unprotected)
51
52- rtems_chain_insert_ - Insert the node into the chain
53
54- rtems_chain_insert_unprotected_ - Insert the node into the chain (unprotected)
55
56- rtems_chain_append_ - Append the node to chain
57
58- rtems_chain_append_unprotected_ - Append the node to chain (unprotected)
59
60- rtems_chain_prepend_ - Prepend the node to the end of the chain
61
62- rtems_chain_prepend_unprotected_ - Prepend the node to chain (unprotected)
63
64Background
65==========
66
67The Chains API maps to the Super Core Chains API. Chains are implemented as a
68double linked list of nodes anchored to a control node. The list starts at the
69control node and is terminated at the control node. A node has previous and
70next pointers. Being a double linked list nodes can be inserted and removed
71without the need to travse the chain.
72
73Chains have a small memory footprint and can be used in interrupt service
74routines and are thread safe in a multi-threaded environment. The directives
75list which operations disable interrupts.
76
77Chains are very useful in Board Support packages and applications.
78
79Nodes
80-----
81
82A chain is made up from nodes that orginate from a chain control object. A node
83is of type ``rtems_chain_node``. The node is designed to be part of a user data
84structure and a cast is used to move from the node address to the user data
85structure address. For example:
86
87.. code-block:: c
88
89    typedef struct foo
90    {
91        rtems_chain_node node;
92        int              bar;
93    } foo;
94
95creates a type ``foo`` that can be placed on a chain. To get the foo structure
96from the list you perform the following:
97
98.. code-block:: c
99
100    foo* get_foo(rtems_chain_control* control)
101    {
102        return (foo*) rtems_chain_get(control);
103    }
104
105The node is placed at the start of the user's structure to allow the node
106address on the chain to be easly cast to the user's structure address.
107
108Controls
109--------
110
111A chain is anchored with a control object. Chain control provide the user with
112access to the nodes on the chain. The control is head of the node.
113
114.. code-block:: c
115
116    [Control]
117    first ------------------------>
118    permanent_null <--------------- [NODE]
119    last ------------------------->
120
121The implementation does not require special checks for manipulating the first
122and last nodes on the chain. To accomplish this the ``rtems_chain_control``
123structure is treated as two overlapping ``rtems_chain_node`` structures.  The
124permanent head of the chain overlays a node structure on the first and
125``permanent_null`` fields.  The ``permanent_tail`` of the chain overlays a node
126structure on the ``permanent_null`` and ``last`` elements of the structure.
127
128Operations
129==========
130
131Multi-threading
132---------------
133
134Chains are designed to be used in a multi-threading environment. The directives
135list which operations mask interrupts. Chains supports tasks and interrupt
136service routines appending and extracting nodes with out the need for extra
137locks. Chains how-ever cannot insure the integrity of a chain for all
138operations. This is the responsibility of the user. For example an interrupt
139service routine extracting nodes while a task is iterating over the chain can
140have unpredictable results.
141
142Creating a Chain
143----------------
144
145To create a chain you need to declare a chain control then add nodes
146to the control. Consider a user structure and chain control:
147
148.. code-block:: c
149
150    typedef struct foo
151    {
152        rtems_chain_node node;
153        uint8_t char*    data;
154    } foo;
155    rtems_chain_control chain;
156
157Add nodes with the following code:
158
159.. code-block:: c
160
161    rtems_chain_initialize_empty (&chain);
162
163    for (i = 0; i < count; i++)
164    {
165        foo* bar = malloc (sizeof (foo));
166        if (!bar)
167            return -1;
168        bar->data = malloc (size);
169        rtems_chain_append (&chain, &bar->node);
170    }
171
172The chain is initialized and the nodes allocated and appended to the
173chain. This is an example of a pool of buffers.
174
175Iterating a Chain
176-----------------
177.. index:: chain iterate
178
179Iterating a chain is a common function. The example shows how to iterate the
180buffer pool chain created in the last section to find buffers starting with a
181specific string. If the buffer is located it is extracted from the chain and
182placed on another chain:
183
184.. code-block:: c
185
186    void foobar (const char*          match,
187                 rtems_chain_control* chain,
188                 rtems_chain_control* out)
189    {
190        rtems_chain_node* node;
191        foo*              bar;
192
193        rtems_chain_initialize_empty (out);
194
195        node = chain->first;
196        while (!rtems_chain_is_tail (chain, node))
197        {
198            bar = (foo*) node;
199            rtems_chain_node* next_node = node->next;
200            if (strcmp (match, bar->data) == 0)
201            {
202                rtems_chain_extract (node);
203                rtems_chain_append (out, node);
204            }
205            node = next_node;
206        }
207    }
208
209Directives
210==========
211
212The section details the Chains directives.
213
214.. COMMENT: Initialize this Chain With Nodes
215
216.. raw:: latex
217
218   \clearpage
219
220.. _rtems_chain_initialize:
221
222Initialize Chain With Nodes
223---------------------------
224.. index:: chain initialize
225.. index:: rtems_chain_initialize
226
227CALLING SEQUENCE:
228    .. code-block:: c
229
230        void rtems_chain_initialize(
231            rtems_chain_control *the_chain,
232            void                *starting_address,
233            size_t               number_nodes,
234            size_t               node_size
235        )
236
237RETURNS:
238    Returns nothing.
239
240DESCRIPTION:
241    This function take in a pointer to a chain control and initializes it to
242    contain a set of chain nodes.  The chain will contain ``number_nodes``
243    chain nodes from the memory pointed to by ``start_address``.  Each node is
244    assumed to be ``node_size`` bytes.
245
246NOTES:
247    This call will discard any nodes on the chain.
248
249    This call does NOT inititialize any user data on each node.
250
251.. COMMENT: Initialize this Chain as Empty
252
253.. raw:: latex
254
255   \clearpage
256
257.. _rtems_chain_initialize_empty:
258
259Initialize Empty
260----------------
261.. index:: chain initialize empty
262.. index:: rtems_chain_initialize_empty
263
264CALLING SEQUENCE:
265    .. code-block:: c
266
267        void rtems_chain_initialize_empty(
268            rtems_chain_control *the_chain
269        );
270
271RETURNS:
272    Returns nothing.
273
274DESCRIPTION:
275    This function take in a pointer to a chain control and initializes it to
276    empty.
277
278NOTES:
279    This call will discard any nodes on the chain.
280
281.. raw:: latex
282
283   \clearpage
284
285.. _rtems_chain_is_null_node:
286
287Is Null Node ?
288--------------
289.. index:: chain is node null
290.. index:: rtems_chain_is_null_node
291
292CALLING SEQUENCE:
293    .. code-block:: c
294
295        bool rtems_chain_is_null_node(
296            const rtems_chain_node *the_node
297        );
298
299RETURNS:
300    Returns ``true`` is the node point is NULL and ``false`` if the node is not
301    NULL.
302
303DESCRIPTION:
304    Tests the node to see if it is a NULL returning ``true`` if a null.
305
306.. raw:: latex
307
308   \clearpage
309
310.. _rtems_chain_head:
311
312Head
313----
314.. index:: chain get head
315.. index:: rtems_chain_head
316
317CALLING SEQUENCE:
318    .. code-block:: c
319
320        rtems_chain_node *rtems_chain_head(
321            rtems_chain_control *the_chain
322        )
323
324RETURNS:
325    Returns the permanent head node of the chain.
326
327DESCRIPTION:
328    This function returns a pointer to the first node on the chain.
329
330.. raw:: latex
331
332   \clearpage
333
334.. _rtems_chain_tail:
335
336Tail
337----
338.. index:: chain get tail
339.. index:: rtems_chain_tail
340
341CALLING SEQUENCE:
342    .. code-block:: c
343
344        rtems_chain_node *rtems_chain_tail(
345            rtems_chain_control *the_chain
346        );
347
348RETURNS:
349    Returns the permanent tail node of the chain.
350
351DESCRIPTION:
352    This function returns a pointer to the last node on the chain.
353
354.. raw:: latex
355
356   \clearpage
357
358.. _rtems_chain_are_nodes_equal:
359
360Are Two Nodes Equal ?
361---------------------
362.. index:: chare are nodes equal
363.. index:: rtems_chain_are_nodes_equal
364
365CALLING SEQUENCE:
366    .. code-block:: c
367
368        bool rtems_chain_are_nodes_equal(
369            const rtems_chain_node *left,
370            const rtems_chain_node *right
371        );
372
373RETURNS:
374    This function returns ``true`` if the left node and the right node are
375    equal, and ``false`` otherwise.
376
377DESCRIPTION:
378    This function returns ``true`` if the left node and the right node are
379    equal, and ``false`` otherwise.
380
381.. raw:: latex
382
383   \clearpage
384
385.. _rtems_chain_is_empty:
386
387Is the Chain Empty
388------------------
389.. index:: chain is chain empty
390.. index:: rtems_chain_is_empty
391
392CALLING SEQUENCE:
393    .. code-block:: c
394
395        bool rtems_chain_is_empty(
396            rtems_chain_control *the_chain
397        );
398
399RETURNS:
400    This function returns ``true`` if there a no nodes on the chain and
401    ``false`` otherwise.
402
403DESCRIPTION:
404    This function returns ``true`` if there a no nodes on the chain and
405    ``false`` otherwise.
406
407.. raw:: latex
408
409   \clearpage
410
411.. _rtems_chain_is_first:
412
413Is this the First Node on the Chain ?
414-------------------------------------
415.. index:: chain is node the first
416.. index:: rtems_chain_is_first
417
418CALLING SEQUENCE:
419    .. code-block:: c
420
421        bool rtems_chain_is_first(
422            const rtems_chain_node *the_node
423        );
424
425RETURNS:
426    This function returns ``true`` if the node is the first node on a chain and
427    ``false`` otherwise.
428
429DESCRIPTION:
430    This function returns ``true`` if the node is the first node on a chain and
431    ``false`` otherwise.
432
433.. raw:: latex
434
435   \clearpage
436
437.. _rtems_chain_is_last:
438
439Is this the Last Node on the Chain ?
440------------------------------------
441.. index:: chain is node the last
442.. index:: rtems_chain_is_last
443
444CALLING SEQUENCE:
445    .. code-block:: c
446
447        bool rtems_chain_is_last(
448            const rtems_chain_node *the_node
449        );
450
451RETURNS:
452    This function returns ``true`` if the node is the last node on a chain and
453    ``false`` otherwise.
454
455DESCRIPTION:
456    This function returns ``true`` if the node is the last node on a chain and
457    ``false`` otherwise.
458
459.. raw:: latex
460
461   \clearpage
462
463.. _rtems_chain_has_only_one_node:
464
465Does this Chain have only One Node ?
466------------------------------------
467.. index:: chain only one node
468.. index:: rtems_chain_has_only_one_node
469
470CALLING SEQUENCE:
471    .. code-block:: c
472
473        bool rtems_chain_has_only_one_node(
474            const rtems_chain_control *the_chain
475        );
476
477RETURNS:
478    This function returns ``true`` if there is only one node on the chain and
479    ``false`` otherwise.
480
481DESCRIPTION:
482    This function returns ``true`` if there is only one node on the chain and
483    ``false`` otherwise.
484
485.. raw:: latex
486
487   \clearpage
488
489.. _rtems_chain_node_count_unprotected:
490
491Returns the node count of the chain (unprotected)
492-------------------------------------------------
493.. index:: chain only one node
494.. index:: rtems_chain_node_count_unprotected
495
496CALLING SEQUENCE:
497    .. code-block:: c
498
499        size_t rtems_chain_node_count_unprotected(
500            const rtems_chain_control *the_chain
501        );
502
503RETURNS:
504    This function returns the node count of the chain.
505
506DESCRIPTION:
507    This function returns the node count of the chain.
508
509.. raw:: latex
510
511   \clearpage
512
513.. _rtems_chain_is_head:
514
515Is this Node the Chain Head ?
516-----------------------------
517.. index:: chain is node the head
518.. index:: rtems_chain_is_head
519
520CALLING SEQUENCE:
521    .. code-block:: c
522
523        bool rtems_chain_is_head(
524            rtems_chain_control    *the_chain,
525            rtems_const chain_node *the_node
526        );
527
528RETURNS:
529    This function returns ``true`` if the node is the head of the chain and
530    ``false`` otherwise.
531
532DESCRIPTION:
533    This function returns ``true`` if the node is the head of the chain and
534    ``false`` otherwise.
535
536.. raw:: latex
537
538   \clearpage
539
540.. _rtems_chain_is_tail:
541
542Is this Node the Chain Tail ?
543-----------------------------
544.. index:: chain is node the tail
545.. index:: rtems_chain_is_tail
546
547CALLING SEQUENCE:
548    .. code-block:: c
549
550        bool rtems_chain_is_tail(
551            rtems_chain_control    *the_chain,
552            const rtems_chain_node *the_node
553        )
554
555RETURNS:
556    This function returns ``true`` if the node is the tail of the chain and
557    ``false`` otherwise.
558
559DESCRIPTION:
560    This function returns ``true`` if the node is the tail of the chain and
561    ``false`` otherwise.
562
563.. raw:: latex
564
565   \clearpage
566
567.. _rtems_chain_extract:
568
569Extract a Node
570--------------
571.. index:: chain extract a node
572.. index:: rtems_chain_extract
573
574CALLING SEQUENCE:
575    .. code-block:: c
576
577        void rtems_chain_extract(
578            rtems_chain_node *the_node
579        );
580
581RETURNS:
582    Returns nothing.
583
584DESCRIPTION:
585    This routine extracts the node from the chain on which it resides.
586
587NOTES:
588    Interrupts are disabled while extracting the node to ensure the atomicity
589    of the operation.
590
591    Use ``rtems_chain_extract_unprotected`` to avoid disabling of interrupts.
592
593.. raw:: latex
594
595   \clearpage
596
597.. _rtems_chain_extract_unprotected:
598
599Extract a Node (unprotected)
600----------------------------
601.. index:: chain extract a node unprotected
602.. index:: rtems_chain_extract_unprotected
603
604CALLING SEQUENCE:
605    .. code-block:: c
606
607        void rtems_chain_extract_unprotected(
608            rtems_chain_node *the_node
609        );
610
611RETURNS:
612    Returns nothing.
613
614DESCRIPTION:
615    This routine extracts the node from the chain on which it resides.
616
617NOTES:
618    The function does nothing to ensure the atomicity of the operation.
619
620.. raw:: latex
621
622   \clearpage
623
624.. _rtems_chain_get:
625
626Get the First Node
627------------------
628.. index:: chain get first node
629.. index:: rtems_chain_get
630
631CALLING SEQUENCE:
632    .. code-block:: c
633
634        rtems_chain_node *rtems_chain_get(
635            rtems_chain_control *the_chain
636        );
637
638RETURNS:
639    Returns a pointer a node. If a node was removed, then a pointer to that
640    node is returned. If the chain was empty, then ``NULL`` is returned.
641
642DESCRIPTION:
643    This function removes the first node from the chain and returns a pointer
644    to that node.  If the chain is empty, then ``NULL`` is returned.
645
646NOTES:
647    Interrupts are disabled while obtaining the node to ensure the atomicity of
648    the operation.
649
650    Use ``rtems_chain_get_unprotected()`` to avoid disabling of interrupts.
651
652.. raw:: latex
653
654   \clearpage
655
656.. _rtems_chain_get_unprotected:
657
658Get the First Node (unprotected)
659--------------------------------
660.. index:: chain get first node
661.. index:: rtems_chain_get_unprotected
662
663CALLING SEQUENCE:
664    .. code-block:: c
665
666        rtems_chain_node *rtems_chain_get_unprotected(
667            rtems_chain_control *the_chain
668        );
669
670RETURNS:
671    A pointer to the former first node is returned.
672
673DESCRIPTION:
674    Removes the first node from the chain and returns a pointer to it.  In case
675    the chain was empty, then the results are unpredictable.
676
677NOTES:
678    The function does nothing to ensure the atomicity of the operation.
679
680.. raw:: latex
681
682   \clearpage
683
684.. _rtems_chain_insert:
685
686Insert a Node
687-------------
688.. index:: chain insert a node
689.. index:: rtems_chain_insert
690
691CALLING SEQUENCE:
692    .. code-block:: c
693
694        void rtems_chain_insert(
695            rtems_chain_node *after_node,
696            rtems_chain_node *the_node
697        );
698
699RETURNS:
700    Returns nothing.
701
702DESCRIPTION:
703    This routine inserts a node on a chain immediately following the specified
704    node.
705
706NOTES:
707    Interrupts are disabled during the insert to ensure the atomicity of the
708    operation.
709
710    Use ``rtems_chain_insert_unprotected()`` to avoid disabling of interrupts.
711
712.. raw:: latex
713
714   \clearpage
715
716.. _rtems_chain_insert_unprotected:
717
718Insert a Node (unprotected)
719---------------------------
720.. index:: chain insert a node unprotected
721.. index:: rtems_chain_insert_unprotected
722
723CALLING SEQUENCE:
724    .. code-block:: c
725
726        void rtems_chain_insert_unprotected(
727            rtems_chain_node *after_node,
728            rtems_chain_node *the_node
729        );
730
731RETURNS:
732    Returns nothing.
733
734DESCRIPTION:
735    This routine inserts a node on a chain immediately following the specified
736    node.
737
738NOTES:
739    The function does nothing to ensure the atomicity of the operation.
740
741.. raw:: latex
742
743   \clearpage
744
745.. _rtems_chain_append:
746
747Append a Node
748-------------
749.. index:: chain append a node
750.. index:: rtems_chain_append
751
752CALLING SEQUENCE:
753    .. code-block:: c
754
755        void rtems_chain_append(
756            rtems_chain_control *the_chain,
757            rtems_chain_node    *the_node
758        );
759
760RETURNS:
761    Returns nothing.
762
763DESCRIPTION:
764    This routine appends a node to the end of a chain.
765
766NOTES:
767    Interrupts are disabled during the append to ensure the atomicity of the
768    operation.
769
770    Use ``rtems_chain_append_unprotected`` to avoid disabling of interrupts.
771
772.. raw:: latex
773
774   \clearpage
775
776.. _rtems_chain_append_unprotected:
777
778Append a Node (unprotected)
779---------------------------
780.. index:: chain append a node unprotected
781.. index:: rtems_chain_append_unprotected
782
783CALLING SEQUENCE:
784    .. code-block:: c
785
786        void rtems_chain_append_unprotected(
787            rtems_chain_control *the_chain,
788            rtems_chain_node    *the_node
789        );
790
791RETURNS:
792    Returns nothing.
793
794DESCRIPTION:
795    This routine appends a node to the end of a chain.
796
797NOTES:
798    The function does nothing to ensure the atomicity of the operation.
799
800.. raw:: latex
801
802   \clearpage
803
804.. _rtems_chain_prepend:
805
806Prepend a Node
807--------------
808.. index:: prepend node
809.. index:: rtems_chain_prepend
810
811CALLING SEQUENCE:
812    .. code-block:: c
813
814        void rtems_chain_prepend(
815            rtems_chain_control *the_chain,
816            rtems_chain_node    *the_node
817        );
818
819RETURNS:
820    Returns nothing.
821
822DESCRIPTION:
823    This routine prepends a node to the front of the chain.
824
825NOTES:
826    Interrupts are disabled during the prepend to ensure the atomicity of the
827    operation.
828
829    Use ``rtems_chain_prepend_unprotected`` to avoid disabling of interrupts.
830
831.. raw:: latex
832
833   \clearpage
834
835.. _rtems_chain_prepend_unprotected:
836
837Prepend a Node (unprotected)
838----------------------------
839.. index:: prepend node unprotected
840.. index:: rtems_chain_prepend_unprotected
841
842CALLING SEQUENCE:
843    .. code-block:: c
844
845        void rtems_chain_prepend_unprotected(
846            rtems_chain_control *the_chain,
847            rtems_chain_node    *the_node
848        );
849
850RETURNS:
851    Returns nothing.
852
853DESCRIPTION:
854    This routine prepends a node to the front of the chain.
855
856NOTES:
857    The function does nothing to ensure the atomicity of the operation.
Note: See TracBrowser for help on using the repository browser.