source: rtems/doc/user/chains.t @ aa47302

5
Last change on this file since aa47302 was aa47302, checked in by Sebastian Huber <sebastian.huber@…>, on 11/03/15 at 10:10:21

sapi: Add rtems_chain_get_first_unprotected()

Close #2459.

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