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

5
Last change on this file since c65aeed was 3384994, checked in by Chris Johns <chrisj@…>, on 11/13/17 at 02:25:18

Clean up sphinx warnings.

  • Fix minor formatting issues.
  • Fix reference the gloassary TLS using ':term:'.
  • Make sure nothing is between an anchor and the heading where ':ref:' references the anchor. This meant moving all the recently added '.. index::' entries.

Update #3232.
Update #3229.

  • 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
6.. index:: chains
7
8Chains
9******
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
175.. index:: chain iterate
176
177Iterating a Chain
178-----------------
179
180Iterating a chain is a common function. The example shows how to iterate the
181buffer pool chain created in the last section to find buffers starting with a
182specific string. If the buffer is located it is extracted from the chain and
183placed on another chain:
184
185.. code-block:: c
186
187    void foobar (const char*          match,
188                 rtems_chain_control* chain,
189                 rtems_chain_control* out)
190    {
191        rtems_chain_node* node;
192        foo*              bar;
193
194        rtems_chain_initialize_empty (out);
195
196        node = chain->first;
197        while (!rtems_chain_is_tail (chain, node))
198        {
199            bar = (foo*) node;
200            rtems_chain_node* next_node = node->next;
201            if (strcmp (match, bar->data) == 0)
202            {
203                rtems_chain_extract (node);
204                rtems_chain_append (out, node);
205            }
206            node = next_node;
207        }
208    }
209
210Directives
211==========
212
213The section details the Chains directives.
214
215.. COMMENT: Initialize this Chain With Nodes
216
217.. raw:: latex
218
219   \clearpage
220
221.. _rtems_chain_initialize:
222
223.. index:: chain initialize
224.. index:: rtems_chain_initialize
225
226Initialize Chain With Nodes
227---------------------------
228
229CALLING SEQUENCE:
230    .. code-block:: c
231
232        void rtems_chain_initialize(
233            rtems_chain_control *the_chain,
234            void                *starting_address,
235            size_t               number_nodes,
236            size_t               node_size
237        )
238
239RETURNS:
240    Returns nothing.
241
242DESCRIPTION:
243    This function take in a pointer to a chain control and initializes it to
244    contain a set of chain nodes.  The chain will contain ``number_nodes``
245    chain nodes from the memory pointed to by ``start_address``.  Each node is
246    assumed to be ``node_size`` bytes.
247
248NOTES:
249    This call will discard any nodes on the chain.
250
251    This call does NOT inititialize any user data on each node.
252
253.. COMMENT: Initialize this Chain as Empty
254
255.. raw:: latex
256
257   \clearpage
258
259.. _rtems_chain_initialize_empty:
260
261.. index:: chain initialize empty
262.. index:: rtems_chain_initialize_empty
263
264Initialize Empty
265----------------
266
267CALLING SEQUENCE:
268    .. code-block:: c
269
270        void rtems_chain_initialize_empty(
271            rtems_chain_control *the_chain
272        );
273
274RETURNS:
275    Returns nothing.
276
277DESCRIPTION:
278    This function take in a pointer to a chain control and initializes it to
279    empty.
280
281NOTES:
282    This call will discard any nodes on the chain.
283
284.. raw:: latex
285
286   \clearpage
287
288.. _rtems_chain_is_null_node:
289
290.. index:: chain is node null
291.. index:: rtems_chain_is_null_node
292
293Is Null Node ?
294--------------
295
296CALLING SEQUENCE:
297    .. code-block:: c
298
299        bool rtems_chain_is_null_node(
300            const rtems_chain_node *the_node
301        );
302
303RETURNS:
304    Returns ``true`` is the node point is NULL and ``false`` if the node is not
305    NULL.
306
307DESCRIPTION:
308    Tests the node to see if it is a NULL returning ``true`` if a null.
309
310.. raw:: latex
311
312   \clearpage
313
314.. _rtems_chain_head:
315
316.. index:: chain get head
317.. index:: rtems_chain_head
318
319Head
320----
321
322CALLING SEQUENCE:
323    .. code-block:: c
324
325        rtems_chain_node *rtems_chain_head(
326            rtems_chain_control *the_chain
327        )
328
329RETURNS:
330    Returns the permanent head node of the chain.
331
332DESCRIPTION:
333    This function returns a pointer to the first node on the chain.
334
335.. raw:: latex
336
337   \clearpage
338
339.. _rtems_chain_tail:
340
341.. index:: chain get tail
342.. index:: rtems_chain_tail
343
344Tail
345----
346
347CALLING SEQUENCE:
348    .. code-block:: c
349
350        rtems_chain_node *rtems_chain_tail(
351            rtems_chain_control *the_chain
352        );
353
354RETURNS:
355    Returns the permanent tail node of the chain.
356
357DESCRIPTION:
358    This function returns a pointer to the last node on the chain.
359
360.. raw:: latex
361
362   \clearpage
363
364.. _rtems_chain_are_nodes_equal:
365
366.. index:: chare are nodes equal
367.. index:: rtems_chain_are_nodes_equal
368
369Are Two Nodes Equal ?
370---------------------
371
372CALLING SEQUENCE:
373    .. code-block:: c
374
375        bool rtems_chain_are_nodes_equal(
376            const rtems_chain_node *left,
377            const rtems_chain_node *right
378        );
379
380RETURNS:
381    This function returns ``true`` if the left node and the right node are
382    equal, and ``false`` otherwise.
383
384DESCRIPTION:
385    This function returns ``true`` if the left node and the right node are
386    equal, and ``false`` otherwise.
387
388.. raw:: latex
389
390   \clearpage
391
392.. _rtems_chain_is_empty:
393
394.. index:: chain is chain empty
395.. index:: rtems_chain_is_empty
396
397Is the Chain Empty
398------------------
399
400CALLING SEQUENCE:
401    .. code-block:: c
402
403        bool rtems_chain_is_empty(
404            rtems_chain_control *the_chain
405        );
406
407RETURNS:
408    This function returns ``true`` if there a no nodes on the chain and
409    ``false`` otherwise.
410
411DESCRIPTION:
412    This function returns ``true`` if there a no nodes on the chain and
413    ``false`` otherwise.
414
415.. raw:: latex
416
417   \clearpage
418
419.. _rtems_chain_is_first:
420
421.. index:: chain is node the first
422.. index:: rtems_chain_is_first
423
424Is this the First Node on the Chain ?
425-------------------------------------
426
427CALLING SEQUENCE:
428    .. code-block:: c
429
430        bool rtems_chain_is_first(
431            const rtems_chain_node *the_node
432        );
433
434RETURNS:
435    This function returns ``true`` if the node is the first node on a chain and
436    ``false`` otherwise.
437
438DESCRIPTION:
439    This function returns ``true`` if the node is the first node on a chain and
440    ``false`` otherwise.
441
442.. raw:: latex
443
444   \clearpage
445
446.. _rtems_chain_is_last:
447
448.. index:: chain is node the last
449.. index:: rtems_chain_is_last
450
451Is this the Last Node on the Chain ?
452------------------------------------
453
454CALLING SEQUENCE:
455    .. code-block:: c
456
457        bool rtems_chain_is_last(
458            const rtems_chain_node *the_node
459        );
460
461RETURNS:
462    This function returns ``true`` if the node is the last node on a chain and
463    ``false`` otherwise.
464
465DESCRIPTION:
466    This function returns ``true`` if the node is the last node on a chain and
467    ``false`` otherwise.
468
469.. raw:: latex
470
471   \clearpage
472
473.. _rtems_chain_has_only_one_node:
474
475.. index:: chain only one node
476.. index:: rtems_chain_has_only_one_node
477
478Does this Chain have only One Node ?
479------------------------------------
480
481CALLING SEQUENCE:
482    .. code-block:: c
483
484        bool rtems_chain_has_only_one_node(
485            const rtems_chain_control *the_chain
486        );
487
488RETURNS:
489    This function returns ``true`` if there is only one node on the chain and
490    ``false`` otherwise.
491
492DESCRIPTION:
493    This function returns ``true`` if there is only one node on the chain and
494    ``false`` otherwise.
495
496.. raw:: latex
497
498   \clearpage
499
500.. _rtems_chain_node_count_unprotected:
501
502.. index:: chain only one node
503.. index:: rtems_chain_node_count_unprotected
504
505Returns the node count of the chain (unprotected)
506-------------------------------------------------
507
508CALLING SEQUENCE:
509    .. code-block:: c
510
511        size_t rtems_chain_node_count_unprotected(
512            const rtems_chain_control *the_chain
513        );
514
515RETURNS:
516    This function returns the node count of the chain.
517
518DESCRIPTION:
519    This function returns the node count of the chain.
520
521.. raw:: latex
522
523   \clearpage
524
525.. _rtems_chain_is_head:
526
527.. index:: chain is node the head
528.. index:: rtems_chain_is_head
529
530Is this Node the Chain Head ?
531-----------------------------
532
533CALLING SEQUENCE:
534    .. code-block:: c
535
536        bool rtems_chain_is_head(
537            rtems_chain_control    *the_chain,
538            rtems_const chain_node *the_node
539        );
540
541RETURNS:
542    This function returns ``true`` if the node is the head of the chain and
543    ``false`` otherwise.
544
545DESCRIPTION:
546    This function returns ``true`` if the node is the head of the chain and
547    ``false`` otherwise.
548
549.. raw:: latex
550
551   \clearpage
552
553.. _rtems_chain_is_tail:
554
555.. index:: chain is node the tail
556.. index:: rtems_chain_is_tail
557
558Is this Node the Chain Tail ?
559-----------------------------
560
561CALLING SEQUENCE:
562    .. code-block:: c
563
564        bool rtems_chain_is_tail(
565            rtems_chain_control    *the_chain,
566            const rtems_chain_node *the_node
567        )
568
569RETURNS:
570    This function returns ``true`` if the node is the tail of the chain and
571    ``false`` otherwise.
572
573DESCRIPTION:
574    This function returns ``true`` if the node is the tail of the chain and
575    ``false`` otherwise.
576
577.. raw:: latex
578
579   \clearpage
580
581.. _rtems_chain_extract:
582
583.. index:: chain extract a node
584.. index:: rtems_chain_extract
585
586Extract a Node
587--------------
588
589CALLING SEQUENCE:
590    .. code-block:: c
591
592        void rtems_chain_extract(
593            rtems_chain_node *the_node
594        );
595
596RETURNS:
597    Returns nothing.
598
599DESCRIPTION:
600    This routine extracts the node from the chain on which it resides.
601
602NOTES:
603    Interrupts are disabled while extracting the node to ensure the atomicity
604    of the operation.
605
606    Use ``rtems_chain_extract_unprotected`` to avoid disabling of interrupts.
607
608.. raw:: latex
609
610   \clearpage
611
612.. _rtems_chain_extract_unprotected:
613
614.. index:: chain extract a node unprotected
615.. index:: rtems_chain_extract_unprotected
616
617Extract a Node (unprotected)
618----------------------------
619
620CALLING SEQUENCE:
621    .. code-block:: c
622
623        void rtems_chain_extract_unprotected(
624            rtems_chain_node *the_node
625        );
626
627RETURNS:
628    Returns nothing.
629
630DESCRIPTION:
631    This routine extracts the node from the chain on which it resides.
632
633NOTES:
634    The function does nothing to ensure the atomicity of the operation.
635
636.. raw:: latex
637
638   \clearpage
639
640.. _rtems_chain_get:
641
642.. index:: chain get first node
643.. index:: rtems_chain_get
644
645Get the First Node
646------------------
647
648CALLING SEQUENCE:
649    .. code-block:: c
650
651        rtems_chain_node *rtems_chain_get(
652            rtems_chain_control *the_chain
653        );
654
655RETURNS:
656    Returns a pointer a node. If a node was removed, then a pointer to that
657    node is returned. If the chain was empty, then ``NULL`` is returned.
658
659DESCRIPTION:
660    This function removes the first node from the chain and returns a pointer
661    to that node.  If the chain is empty, then ``NULL`` is returned.
662
663NOTES:
664    Interrupts are disabled while obtaining the node to ensure the atomicity of
665    the operation.
666
667    Use ``rtems_chain_get_unprotected()`` to avoid disabling of interrupts.
668
669.. raw:: latex
670
671   \clearpage
672
673.. _rtems_chain_get_unprotected:
674
675.. index:: chain get first node
676.. index:: rtems_chain_get_unprotected
677
678Get the First Node (unprotected)
679--------------------------------
680
681CALLING SEQUENCE:
682    .. code-block:: c
683
684        rtems_chain_node *rtems_chain_get_unprotected(
685            rtems_chain_control *the_chain
686        );
687
688RETURNS:
689    A pointer to the former first node is returned.
690
691DESCRIPTION:
692    Removes the first node from the chain and returns a pointer to it.  In case
693    the chain was empty, then the results are unpredictable.
694
695NOTES:
696    The function does nothing to ensure the atomicity of the operation.
697
698.. raw:: latex
699
700   \clearpage
701
702.. _rtems_chain_insert:
703
704.. index:: chain insert a node
705.. index:: rtems_chain_insert
706
707Insert a Node
708-------------
709
710CALLING SEQUENCE:
711    .. code-block:: c
712
713        void rtems_chain_insert(
714            rtems_chain_node *after_node,
715            rtems_chain_node *the_node
716        );
717
718RETURNS:
719    Returns nothing.
720
721DESCRIPTION:
722    This routine inserts a node on a chain immediately following the specified
723    node.
724
725NOTES:
726    Interrupts are disabled during the insert to ensure the atomicity of the
727    operation.
728
729    Use ``rtems_chain_insert_unprotected()`` to avoid disabling of interrupts.
730
731.. raw:: latex
732
733   \clearpage
734
735.. _rtems_chain_insert_unprotected:
736
737.. index:: chain insert a node unprotected
738.. index:: rtems_chain_insert_unprotected
739
740Insert a Node (unprotected)
741---------------------------
742
743CALLING SEQUENCE:
744    .. code-block:: c
745
746        void rtems_chain_insert_unprotected(
747            rtems_chain_node *after_node,
748            rtems_chain_node *the_node
749        );
750
751RETURNS:
752    Returns nothing.
753
754DESCRIPTION:
755    This routine inserts a node on a chain immediately following the specified
756    node.
757
758NOTES:
759    The function does nothing to ensure the atomicity of the operation.
760
761.. raw:: latex
762
763   \clearpage
764
765.. _rtems_chain_append:
766
767.. index:: chain append a node
768.. index:: rtems_chain_append
769
770Append a Node
771-------------
772
773CALLING SEQUENCE:
774    .. code-block:: c
775
776        void rtems_chain_append(
777            rtems_chain_control *the_chain,
778            rtems_chain_node    *the_node
779        );
780
781RETURNS:
782    Returns nothing.
783
784DESCRIPTION:
785    This routine appends a node to the end of a chain.
786
787NOTES:
788    Interrupts are disabled during the append to ensure the atomicity of the
789    operation.
790
791    Use ``rtems_chain_append_unprotected`` to avoid disabling of interrupts.
792
793.. raw:: latex
794
795   \clearpage
796
797.. _rtems_chain_append_unprotected:
798
799.. index:: chain append a node unprotected
800.. index:: rtems_chain_append_unprotected
801
802Append a Node (unprotected)
803---------------------------
804
805CALLING SEQUENCE:
806    .. code-block:: c
807
808        void rtems_chain_append_unprotected(
809            rtems_chain_control *the_chain,
810            rtems_chain_node    *the_node
811        );
812
813RETURNS:
814    Returns nothing.
815
816DESCRIPTION:
817    This routine appends a node to the end of a chain.
818
819NOTES:
820    The function does nothing to ensure the atomicity of the operation.
821
822.. raw:: latex
823
824   \clearpage
825
826.. _rtems_chain_prepend:
827
828.. index:: prepend node
829.. index:: rtems_chain_prepend
830
831Prepend a Node
832--------------
833
834CALLING SEQUENCE:
835    .. code-block:: c
836
837        void rtems_chain_prepend(
838            rtems_chain_control *the_chain,
839            rtems_chain_node    *the_node
840        );
841
842RETURNS:
843    Returns nothing.
844
845DESCRIPTION:
846    This routine prepends a node to the front of the chain.
847
848NOTES:
849    Interrupts are disabled during the prepend to ensure the atomicity of the
850    operation.
851
852    Use ``rtems_chain_prepend_unprotected`` to avoid disabling of interrupts.
853
854.. raw:: latex
855
856   \clearpage
857
858.. _rtems_chain_prepend_unprotected:
859
860.. index:: prepend node unprotected
861.. index:: rtems_chain_prepend_unprotected
862
863Prepend a Node (unprotected)
864----------------------------
865
866CALLING SEQUENCE:
867    .. code-block:: c
868
869        void rtems_chain_prepend_unprotected(
870            rtems_chain_control *the_chain,
871            rtems_chain_node    *the_node
872        );
873
874RETURNS:
875    Returns nothing.
876
877DESCRIPTION:
878    This routine prepends a node to the front of the chain.
879
880NOTES:
881    The function does nothing to ensure the atomicity of the operation.
Note: See TracBrowser for help on using the repository browser.