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

4.9
Last change on this file since b8b0920 was b8b0920, checked in by Joel Sherrill <joel.sherrill@…>, on 11/13/08 at 15:10:15

2008-11-13 Joel Sherrill <joel.sherrill@…>

PR 1336/cpukit

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