]> begriffs open source - freertos/blob - include/list.h
Add a cap to the queue locks (#435)
[freertos] / include / list.h
1 /*\r
2  * FreeRTOS Kernel <DEVELOPMENT BRANCH>\r
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * SPDX-License-Identifier: MIT\r
6  *\r
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
8  * this software and associated documentation files (the "Software"), to deal in\r
9  * the Software without restriction, including without limitation the rights to\r
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
11  * the Software, and to permit persons to whom the Software is furnished to do so,\r
12  * subject to the following conditions:\r
13  *\r
14  * The above copyright notice and this permission notice shall be included in all\r
15  * copies or substantial portions of the Software.\r
16  *\r
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
23  *\r
24  * https://www.FreeRTOS.org\r
25  * https://github.com/FreeRTOS\r
26  *\r
27  */\r
28 \r
29 /*\r
30  * This is the list implementation used by the scheduler.  While it is tailored\r
31  * heavily for the schedulers needs, it is also available for use by\r
32  * application code.\r
33  *\r
34  * list_ts can only store pointers to list_item_ts.  Each ListItem_t contains a\r
35  * numeric value (xItemValue).  Most of the time the lists are sorted in\r
36  * ascending item value order.\r
37  *\r
38  * Lists are created already containing one list item.  The value of this\r
39  * item is the maximum possible that can be stored, it is therefore always at\r
40  * the end of the list and acts as a marker.  The list member pxHead always\r
41  * points to this marker - even though it is at the tail of the list.  This\r
42  * is because the tail contains a wrap back pointer to the true head of\r
43  * the list.\r
44  *\r
45  * In addition to it's value, each list item contains a pointer to the next\r
46  * item in the list (pxNext), a pointer to the list it is in (pxContainer)\r
47  * and a pointer to back to the object that contains it.  These later two\r
48  * pointers are included for efficiency of list manipulation.  There is\r
49  * effectively a two way link between the object containing the list item and\r
50  * the list item itself.\r
51  *\r
52  *\r
53  * \page ListIntroduction List Implementation\r
54  * \ingroup FreeRTOSIntro\r
55  */\r
56 \r
57 \r
58 #ifndef LIST_H\r
59 #define LIST_H\r
60 \r
61 #ifndef INC_FREERTOS_H\r
62     #error "FreeRTOS.h must be included before list.h"\r
63 #endif\r
64 \r
65 /*\r
66  * The list structure members are modified from within interrupts, and therefore\r
67  * by rights should be declared volatile.  However, they are only modified in a\r
68  * functionally atomic way (within critical sections of with the scheduler\r
69  * suspended) and are either passed by reference into a function or indexed via\r
70  * a volatile variable.  Therefore, in all use cases tested so far, the volatile\r
71  * qualifier can be omitted in order to provide a moderate performance\r
72  * improvement without adversely affecting functional behaviour.  The assembly\r
73  * instructions generated by the IAR, ARM and GCC compilers when the respective\r
74  * compiler's options were set for maximum optimisation has been inspected and\r
75  * deemed to be as intended.  That said, as compiler technology advances, and\r
76  * especially if aggressive cross module optimisation is used (a use case that\r
77  * has not been exercised to any great extend) then it is feasible that the\r
78  * volatile qualifier will be needed for correct optimisation.  It is expected\r
79  * that a compiler removing essential code because, without the volatile\r
80  * qualifier on the list structure members and with aggressive cross module\r
81  * optimisation, the compiler deemed the code unnecessary will result in\r
82  * complete and obvious failure of the scheduler.  If this is ever experienced\r
83  * then the volatile qualifier can be inserted in the relevant places within the\r
84  * list structures by simply defining configLIST_VOLATILE to volatile in\r
85  * FreeRTOSConfig.h (as per the example at the bottom of this comment block).\r
86  * If configLIST_VOLATILE is not defined then the preprocessor directives below\r
87  * will simply #define configLIST_VOLATILE away completely.\r
88  *\r
89  * To use volatile list structure members then add the following line to\r
90  * FreeRTOSConfig.h (without the quotes):\r
91  * "#define configLIST_VOLATILE volatile"\r
92  */\r
93 #ifndef configLIST_VOLATILE\r
94     #define configLIST_VOLATILE\r
95 #endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */\r
96 \r
97 /* *INDENT-OFF* */\r
98 #ifdef __cplusplus\r
99     extern "C" {\r
100 #endif\r
101 /* *INDENT-ON* */\r
102 \r
103 /* Macros that can be used to place known values within the list structures,\r
104  * then check that the known values do not get corrupted during the execution of\r
105  * the application.   These may catch the list data structures being overwritten in\r
106  * memory.  They will not catch data errors caused by incorrect configuration or\r
107  * use of FreeRTOS.*/\r
108 #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )\r
109     /* Define the macros to do nothing. */\r
110     #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE\r
111     #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE\r
112     #define listFIRST_LIST_INTEGRITY_CHECK_VALUE\r
113     #define listSECOND_LIST_INTEGRITY_CHECK_VALUE\r
114     #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )\r
115     #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )\r
116     #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )\r
117     #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )\r
118     #define listTEST_LIST_ITEM_INTEGRITY( pxItem )\r
119     #define listTEST_LIST_INTEGRITY( pxList )\r
120 #else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */\r
121     /* Define macros that add new members into the list structures. */\r
122     #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE     TickType_t xListItemIntegrityValue1;\r
123     #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE    TickType_t xListItemIntegrityValue2;\r
124     #define listFIRST_LIST_INTEGRITY_CHECK_VALUE          TickType_t xListIntegrityValue1;\r
125     #define listSECOND_LIST_INTEGRITY_CHECK_VALUE         TickType_t xListIntegrityValue2;\r
126 \r
127 /* Define macros that set the new structure members to known values. */\r
128     #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )     ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE\r
129     #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )    ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE\r
130     #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )              ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE\r
131     #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )              ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE\r
132 \r
133 /* Define macros that will assert if one of the structure members does not\r
134  * contain its expected value. */\r
135     #define listTEST_LIST_ITEM_INTEGRITY( pxItem )                      configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )\r
136     #define listTEST_LIST_INTEGRITY( pxList )                           configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )\r
137 #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */\r
138 \r
139 \r
140 /*\r
141  * Definition of the only type of object that a list can contain.\r
142  */\r
143 struct xLIST;\r
144 struct xLIST_ITEM\r
145 {\r
146     listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
147     configLIST_VOLATILE TickType_t xItemValue;          /*< The value being listed.  In most cases this is used to sort the list in ascending order. */\r
148     struct xLIST_ITEM * configLIST_VOLATILE pxNext;     /*< Pointer to the next ListItem_t in the list. */\r
149     struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */\r
150     void * pvOwner;                                     /*< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */\r
151     struct xLIST * configLIST_VOLATILE pxContainer;     /*< Pointer to the list in which this list item is placed (if any). */\r
152     listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE          /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
153 };\r
154 typedef struct xLIST_ITEM ListItem_t;                   /* For some reason lint wants this as two separate definitions. */\r
155 \r
156 struct xMINI_LIST_ITEM\r
157 {\r
158     listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
159     configLIST_VOLATILE TickType_t xItemValue;\r
160     struct xLIST_ITEM * configLIST_VOLATILE pxNext;\r
161     struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;\r
162 };\r
163 typedef struct xMINI_LIST_ITEM MiniListItem_t;\r
164 \r
165 /*\r
166  * Definition of the type of queue used by the scheduler.\r
167  */\r
168 typedef struct xLIST\r
169 {\r
170     listFIRST_LIST_INTEGRITY_CHECK_VALUE      /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
171     volatile UBaseType_t uxNumberOfItems;\r
172     ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */\r
173     MiniListItem_t xListEnd;                  /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */\r
174     listSECOND_LIST_INTEGRITY_CHECK_VALUE     /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
175 } List_t;\r
176 \r
177 /*\r
178  * Access macro to set the owner of a list item.  The owner of a list item\r
179  * is the object (usually a TCB) that contains the list item.\r
180  *\r
181  * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER\r
182  * \ingroup LinkedList\r
183  */\r
184 #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )    ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )\r
185 \r
186 /*\r
187  * Access macro to get the owner of a list item.  The owner of a list item\r
188  * is the object (usually a TCB) that contains the list item.\r
189  *\r
190  * \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER\r
191  * \ingroup LinkedList\r
192  */\r
193 #define listGET_LIST_ITEM_OWNER( pxListItem )             ( ( pxListItem )->pvOwner )\r
194 \r
195 /*\r
196  * Access macro to set the value of the list item.  In most cases the value is\r
197  * used to sort the list in ascending order.\r
198  *\r
199  * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE\r
200  * \ingroup LinkedList\r
201  */\r
202 #define listSET_LIST_ITEM_VALUE( pxListItem, xValue )     ( ( pxListItem )->xItemValue = ( xValue ) )\r
203 \r
204 /*\r
205  * Access macro to retrieve the value of the list item.  The value can\r
206  * represent anything - for example the priority of a task, or the time at\r
207  * which a task should be unblocked.\r
208  *\r
209  * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
210  * \ingroup LinkedList\r
211  */\r
212 #define listGET_LIST_ITEM_VALUE( pxListItem )             ( ( pxListItem )->xItemValue )\r
213 \r
214 /*\r
215  * Access macro to retrieve the value of the list item at the head of a given\r
216  * list.\r
217  *\r
218  * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
219  * \ingroup LinkedList\r
220  */\r
221 #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )        ( ( ( pxList )->xListEnd ).pxNext->xItemValue )\r
222 \r
223 /*\r
224  * Return the list item at the head of the list.\r
225  *\r
226  * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY\r
227  * \ingroup LinkedList\r
228  */\r
229 #define listGET_HEAD_ENTRY( pxList )                      ( ( ( pxList )->xListEnd ).pxNext )\r
230 \r
231 /*\r
232  * Return the next list item.\r
233  *\r
234  * \page listGET_NEXT listGET_NEXT\r
235  * \ingroup LinkedList\r
236  */\r
237 #define listGET_NEXT( pxListItem )                        ( ( pxListItem )->pxNext )\r
238 \r
239 /*\r
240  * Return the list item that marks the end of the list\r
241  *\r
242  * \page listGET_END_MARKER listGET_END_MARKER\r
243  * \ingroup LinkedList\r
244  */\r
245 #define listGET_END_MARKER( pxList )                      ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )\r
246 \r
247 /*\r
248  * Access macro to determine if a list contains any items.  The macro will\r
249  * only have the value true if the list is empty.\r
250  *\r
251  * \page listLIST_IS_EMPTY listLIST_IS_EMPTY\r
252  * \ingroup LinkedList\r
253  */\r
254 #define listLIST_IS_EMPTY( pxList )                       ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )\r
255 \r
256 /*\r
257  * Access macro to return the number of items in the list.\r
258  */\r
259 #define listCURRENT_LIST_LENGTH( pxList )                 ( ( pxList )->uxNumberOfItems )\r
260 \r
261 /*\r
262  * Access function to obtain the owner of the next entry in a list.\r
263  *\r
264  * The list member pxIndex is used to walk through a list.  Calling\r
265  * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list\r
266  * and returns that entry's pxOwner parameter.  Using multiple calls to this\r
267  * function it is therefore possible to move through every item contained in\r
268  * a list.\r
269  *\r
270  * The pxOwner parameter of a list item is a pointer to the object that owns\r
271  * the list item.  In the scheduler this is normally a task control block.\r
272  * The pxOwner parameter effectively creates a two way link between the list\r
273  * item and its owner.\r
274  *\r
275  * @param pxTCB pxTCB is set to the address of the owner of the next list item.\r
276  * @param pxList The list from which the next item owner is to be returned.\r
277  *\r
278  * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY\r
279  * \ingroup LinkedList\r
280  */\r
281 #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )                                           \\r
282     {                                                                                          \\r
283         List_t * const pxConstList = ( pxList );                                               \\r
284         /* Increment the index to the next item and return the item, ensuring */               \\r
285         /* we don't return the marker used at the end of the list.  */                         \\r
286         ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                           \\r
287         if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \\r
288         {                                                                                      \\r
289             ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                       \\r
290         }                                                                                      \\r
291         ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;                                         \\r
292     }\r
293 \r
294 /*\r
295  * Version of uxListRemove() that does not return a value.  Provided as a slight\r
296  * optimisation for xTaskIncrementTick() by being inline.\r
297  *\r
298  * Remove an item from a list.  The list item has a pointer to the list that\r
299  * it is in, so only the list item need be passed into the function.\r
300  *\r
301  * @param uxListRemove The item to be removed.  The item will remove itself from\r
302  * the list pointed to by it's pxContainer parameter.\r
303  *\r
304  * @return The number of items that remain in the list after the list item has\r
305  * been removed.\r
306  *\r
307  * \page listREMOVE_ITEM listREMOVE_ITEM\r
308  * \ingroup LinkedList\r
309  */\r
310 #define listREMOVE_ITEM( pxItemToRemove ) \\r
311     {                                     \\r
312         /* The list item knows which list it is in.  Obtain the list from the list \\r
313          * item. */                                                              \\r
314         List_t * const pxList = ( pxItemToRemove )->pxContainer;                 \\r
315                                                                                  \\r
316         ( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \\r
317         ( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext;     \\r
318         /* Make sure the index is left pointing to a valid item. */              \\r
319         if( pxList->pxIndex == ( pxItemToRemove ) )                              \\r
320         {                                                                        \\r
321             pxList->pxIndex = ( pxItemToRemove )->pxPrevious;                    \\r
322         }                                                                        \\r
323                                                                                  \\r
324         ( pxItemToRemove )->pxContainer = NULL;                                  \\r
325         ( pxList->uxNumberOfItems )--;                                           \\r
326     }\r
327 \r
328 /*\r
329  * Inline version of vListInsertEnd() to provide slight optimisation for\r
330  * xTaskIncrementTick().\r
331  *\r
332  * Insert a list item into a list.  The item will be inserted in a position\r
333  * such that it will be the last item within the list returned by multiple\r
334  * calls to listGET_OWNER_OF_NEXT_ENTRY.\r
335  *\r
336  * The list member pxIndex is used to walk through a list.  Calling\r
337  * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.\r
338  * Placing an item in a list using vListInsertEnd effectively places the item\r
339  * in the list position pointed to by pxIndex.  This means that every other\r
340  * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before\r
341  * the pxIndex parameter again points to the item being inserted.\r
342  *\r
343  * @param pxList The list into which the item is to be inserted.\r
344  *\r
345  * @param pxNewListItem The list item to be inserted into the list.\r
346  *\r
347  * \page listINSERT_END listINSERT_END\r
348  * \ingroup LinkedList\r
349  */\r
350 #define listINSERT_END( pxList, pxNewListItem )           \\r
351     {                                                     \\r
352         ListItem_t * const pxIndex = ( pxList )->pxIndex; \\r
353                                                           \\r
354         /* Only effective when configASSERT() is also defined, these tests may catch \\r
355          * the list data structures being overwritten in memory.  They will not catch \\r
356          * data errors caused by incorrect configuration or use of FreeRTOS. */ \\r
357         listTEST_LIST_INTEGRITY( ( pxList ) );                                  \\r
358         listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) );                      \\r
359                                                                                 \\r
360         /* Insert a new list item into ( pxList ), but rather than sort the list, \\r
361          * makes the new list item the last item to be removed by a call to \\r
362          * listGET_OWNER_OF_NEXT_ENTRY(). */                 \\r
363         ( pxNewListItem )->pxNext = pxIndex;                 \\r
364         ( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \\r
365                                                              \\r
366         pxIndex->pxPrevious->pxNext = ( pxNewListItem );     \\r
367         pxIndex->pxPrevious = ( pxNewListItem );             \\r
368                                                              \\r
369         /* Remember which list the item is in. */            \\r
370         ( pxNewListItem )->pxContainer = ( pxList );         \\r
371                                                              \\r
372         ( ( pxList )->uxNumberOfItems )++;                   \\r
373     }\r
374 \r
375 /*\r
376  * Access function to obtain the owner of the first entry in a list.  Lists\r
377  * are normally sorted in ascending item value order.\r
378  *\r
379  * This function returns the pxOwner member of the first item in the list.\r
380  * The pxOwner parameter of a list item is a pointer to the object that owns\r
381  * the list item.  In the scheduler this is normally a task control block.\r
382  * The pxOwner parameter effectively creates a two way link between the list\r
383  * item and its owner.\r
384  *\r
385  * @param pxList The list from which the owner of the head item is to be\r
386  * returned.\r
387  *\r
388  * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY\r
389  * \ingroup LinkedList\r
390  */\r
391 #define listGET_OWNER_OF_HEAD_ENTRY( pxList )            ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner )\r
392 \r
393 /*\r
394  * Check to see if a list item is within a list.  The list item maintains a\r
395  * "container" pointer that points to the list it is in.  All this macro does\r
396  * is check to see if the container and the list match.\r
397  *\r
398  * @param pxList The list we want to know if the list item is within.\r
399  * @param pxListItem The list item we want to know if is in the list.\r
400  * @return pdTRUE if the list item is in the list, otherwise pdFALSE.\r
401  */\r
402 #define listIS_CONTAINED_WITHIN( pxList, pxListItem )    ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )\r
403 \r
404 /*\r
405  * Return the list a list item is contained within (referenced from).\r
406  *\r
407  * @param pxListItem The list item being queried.\r
408  * @return A pointer to the List_t object that references the pxListItem\r
409  */\r
410 #define listLIST_ITEM_CONTAINER( pxListItem )            ( ( pxListItem )->pxContainer )\r
411 \r
412 /*\r
413  * This provides a crude means of knowing if a list has been initialised, as\r
414  * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()\r
415  * function.\r
416  */\r
417 #define listLIST_IS_INITIALISED( pxList )                ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )\r
418 \r
419 /*\r
420  * Must be called before a list is used!  This initialises all the members\r
421  * of the list structure and inserts the xListEnd item into the list as a\r
422  * marker to the back of the list.\r
423  *\r
424  * @param pxList Pointer to the list being initialised.\r
425  *\r
426  * \page vListInitialise vListInitialise\r
427  * \ingroup LinkedList\r
428  */\r
429 void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;\r
430 \r
431 /*\r
432  * Must be called before a list item is used.  This sets the list container to\r
433  * null so the item does not think that it is already contained in a list.\r
434  *\r
435  * @param pxItem Pointer to the list item being initialised.\r
436  *\r
437  * \page vListInitialiseItem vListInitialiseItem\r
438  * \ingroup LinkedList\r
439  */\r
440 void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;\r
441 \r
442 /*\r
443  * Insert a list item into a list.  The item will be inserted into the list in\r
444  * a position determined by its item value (ascending item value order).\r
445  *\r
446  * @param pxList The list into which the item is to be inserted.\r
447  *\r
448  * @param pxNewListItem The item that is to be placed in the list.\r
449  *\r
450  * \page vListInsert vListInsert\r
451  * \ingroup LinkedList\r
452  */\r
453 void vListInsert( List_t * const pxList,\r
454                   ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;\r
455 \r
456 /*\r
457  * Insert a list item into a list.  The item will be inserted in a position\r
458  * such that it will be the last item within the list returned by multiple\r
459  * calls to listGET_OWNER_OF_NEXT_ENTRY.\r
460  *\r
461  * The list member pxIndex is used to walk through a list.  Calling\r
462  * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.\r
463  * Placing an item in a list using vListInsertEnd effectively places the item\r
464  * in the list position pointed to by pxIndex.  This means that every other\r
465  * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before\r
466  * the pxIndex parameter again points to the item being inserted.\r
467  *\r
468  * @param pxList The list into which the item is to be inserted.\r
469  *\r
470  * @param pxNewListItem The list item to be inserted into the list.\r
471  *\r
472  * \page vListInsertEnd vListInsertEnd\r
473  * \ingroup LinkedList\r
474  */\r
475 void vListInsertEnd( List_t * const pxList,\r
476                      ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;\r
477 \r
478 /*\r
479  * Remove an item from a list.  The list item has a pointer to the list that\r
480  * it is in, so only the list item need be passed into the function.\r
481  *\r
482  * @param uxListRemove The item to be removed.  The item will remove itself from\r
483  * the list pointed to by it's pxContainer parameter.\r
484  *\r
485  * @return The number of items that remain in the list after the list item has\r
486  * been removed.\r
487  *\r
488  * \page uxListRemove uxListRemove\r
489  * \ingroup LinkedList\r
490  */\r
491 UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;\r
492 \r
493 /* *INDENT-OFF* */\r
494 #ifdef __cplusplus\r
495     }\r
496 #endif\r
497 /* *INDENT-ON* */\r
498 \r
499 #endif /* ifndef LIST_H */\r