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

5
Last change on this file since 12dccfe was 12dccfe, checked in by Sebastian Huber <sebastian.huber@…>, on 01/09/19 at 15:14:05

Remove superfluous "All rights reserved."

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