]> git.sur5r.net Git - freertos/blob - Source/include/list.h
First version under SVN is V4.0.1
[freertos] / Source / include / list.h
1 /*\r
2         FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS distribution.\r
5 \r
6         FreeRTOS is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section\r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26         ***************************************************************************\r
27         See http://www.FreeRTOS.org for documentation, latest information, license\r
28         and contact details.  Please ensure to read the configuration and relevant\r
29         port sections of the online documentation.\r
30         ***************************************************************************\r
31 */\r
32 \r
33 /*\r
34  * This is the list implementation used by the scheduler.  While it is tailored\r
35  * heavily for the schedulers needs, it is also available for use by\r
36  * application code.\r
37  *\r
38  * xLists can only store pointers to xListItems.  Each xListItem contains a\r
39  * numeric value (xItemValue).  Most of the time the lists are sorted in\r
40  * descending item value order.\r
41  *\r
42  * Lists are created already containing one list item.  The value of this\r
43  * item is the maximum possible that can be stored, it is therefore always at\r
44  * the end of the list and acts as a marker.  The list member pxHead always\r
45  * points to this marker - even though it is at the tail of the list.  This\r
46  * is because the tail contains a wrap back pointer to the true head of\r
47  * the list.\r
48  *\r
49  * In addition to it's value, each list item contains a pointer to the next\r
50  * item in the list (pxNext), a pointer to the list it is in (pxContainer)\r
51  * and a pointer to back to the object that contains it.  These later two\r
52  * pointers are included for efficiency of list manipulation.  There is\r
53  * effectively a two way link between the object containing the list item and\r
54  * the list item itself.\r
55  *\r
56  *\r
57  * \page ListIntroduction List Implementation\r
58  * \ingroup FreeRTOSIntro\r
59  */\r
60 \r
61 \r
62 #ifndef LIST_H\r
63 #define LIST_H\r
64 \r
65 /*\r
66  * Definition of the only type of object that a list can contain.\r
67  */\r
68 struct xLIST_ITEM\r
69 {\r
70         portTickType xItemValue;                                /*< The value being listed.  In most cases this is used to sort the list in descending order. */\r
71         volatile struct xLIST_ITEM * pxNext;    /*< Pointer to the next xListItem in the list. */\r
72         volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */\r
73         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
74         void * pvContainer;                                             /*< Pointer to the list in which this list item is placed (if any). */\r
75 };\r
76 typedef struct xLIST_ITEM xListItem;            /* For some reason lint wants this as two separate definitions. */\r
77 \r
78 struct xMINI_LIST_ITEM\r
79 {\r
80         portTickType xItemValue;\r
81         volatile struct xLIST_ITEM *pxNext;\r
82         volatile struct xLIST_ITEM *pxPrevious;\r
83 };\r
84 typedef struct xMINI_LIST_ITEM xMiniListItem;\r
85 \r
86 /*\r
87  * Definition of the type of queue used by the scheduler.\r
88  */\r
89 typedef struct xLIST\r
90 {\r
91         volatile unsigned portBASE_TYPE uxNumberOfItems;\r
92         volatile xListItem * pxIndex;                   /*< Used to walk through the list.  Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */\r
93         volatile xMiniListItem 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
94 } xList;\r
95 \r
96 /*\r
97  * Access macro to set the owner of a list item.  The owner of a list item\r
98  * is the object (usually a TCB) that contains the list item.\r
99  *\r
100  * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER\r
101  * \ingroup LinkedList\r
102  */\r
103 #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )          ( pxListItem )->pvOwner = ( void * ) pxOwner\r
104 \r
105 /*\r
106  * Access macro to set the value of the list item.  In most cases the value is\r
107  * used to sort the list in descending order.\r
108  *\r
109  * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE\r
110  * \ingroup LinkedList\r
111  */\r
112 #define listSET_LIST_ITEM_VALUE( pxListItem, xValue )           ( pxListItem )->xItemValue = xValue\r
113 \r
114 /*\r
115  * Access macro the retrieve the value of the list item.  The value can\r
116  * represent anything - for example a the priority of a task, or the time at\r
117  * which a task should be unblocked.\r
118  *\r
119  * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
120  * \ingroup LinkedList\r
121  */\r
122 #define listGET_LIST_ITEM_VALUE( pxListItem )                           ( ( pxListItem )->xItemValue )\r
123 \r
124 /*\r
125  * Access macro to determine if a list contains any items.  The macro will\r
126  * only have the value true if the list is empty.\r
127  *\r
128  * \page listLIST_IS_EMPTY listLIST_IS_EMPTY\r
129  * \ingroup LinkedList\r
130  */\r
131 #define listLIST_IS_EMPTY( pxList )                             ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )\r
132 \r
133 /*\r
134  * Access macro to return the number of items in the list.\r
135  */\r
136 #define listCURRENT_LIST_LENGTH( pxList )               ( ( pxList )->uxNumberOfItems )\r
137 \r
138 /*\r
139  * Access function to obtain the owner of the next entry in a list.\r
140  *\r
141  * The list member pxIndex is used to walk through a list.  Calling\r
142  * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list\r
143  * and returns that entries pxOwner parameter.  Using multiple calls to this\r
144  * function it is therefore possible to move through every item contained in\r
145  * a list.\r
146  *\r
147  * The pxOwner parameter of a list item is a pointer to the object that owns\r
148  * the list item.  In the scheduler this is normally a task control block.\r
149  * The pxOwner parameter effectively creates a two way link between the list\r
150  * item and its owner.\r
151  *\r
152  * @param pxList The list from which the next item owner is to be returned.\r
153  *\r
154  * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY\r
155  * \ingroup LinkedList\r
156  */\r
157 #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )                                                                    \\r
158         /* Increment the index to the next item and return the item, ensuring */                        \\r
159         /* we don't return the marker used at the end of the list.  */                                          \\r
160         ( pxList )->pxIndex = ( pxList )->pxIndex->pxNext;                                                                      \\r
161         if( ( pxList )->pxIndex == ( xListItem * ) &( ( pxList )->xListEnd ) )                          \\r
162         {                                                                                                                                                                       \\r
163                 ( pxList )->pxIndex = ( pxList )->pxIndex->pxNext;                                                              \\r
164         }                                                                                                                                                                       \\r
165         pxTCB = ( pxList )->pxIndex->pvOwner\r
166 \r
167 \r
168 /*\r
169  * Access function to obtain the owner of the first entry in a list.  Lists\r
170  * are normally sorted in ascending item value order.\r
171  *\r
172  * This function returns the pxOwner member of the first item in the list.\r
173  * The pxOwner parameter of a list item is a pointer to the object that owns\r
174  * the list item.  In the scheduler this is normally a task control block.\r
175  * The pxOwner parameter effectively creates a two way link between the list\r
176  * item and its owner.\r
177  *\r
178  * @param pxList The list from which the owner of the head item is to be\r
179  * returned.\r
180  *\r
181  * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY\r
182  * \ingroup LinkedList\r
183  */\r
184 #define listGET_OWNER_OF_HEAD_ENTRY( pxList )  ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) )\r
185 \r
186 /*\r
187  * Check to see if a list item is within a list.  The list item maintains a\r
188  * "container" pointer that points to the list it is in.  All this macro does\r
189  * is check to see if the container and the list match.\r
190  *\r
191  * @param pxList The list we want to know if the list item is within.\r
192  * @param pxListItem The list item we want to know if is in the list.\r
193  * @return pdTRUE is the list item is in the list, otherwise pdFALSE.\r
194  * pointer against\r
195  */\r
196 #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList )\r
197 \r
198 /*\r
199  * Must be called before a list is used!  This initialises all the members\r
200  * of the list structure and inserts the xListEnd item into the list as a\r
201  * marker to the back of the list.\r
202  *\r
203  * @param pxList Pointer to the list being initialised.\r
204  *\r
205  * \page vListInitialise vListInitialise\r
206  * \ingroup LinkedList\r
207  */\r
208 void vListInitialise( xList *pxList );\r
209 \r
210 /*\r
211  * Must be called before a list item is used.  This sets the list container to\r
212  * null so the item does not think that it is already contained in a list.\r
213  *\r
214  * @param pxItem Pointer to the list item being initialised.\r
215  *\r
216  * \page vListInitialiseItem vListInitialiseItem\r
217  * \ingroup LinkedList\r
218  */\r
219 void vListInitialiseItem( xListItem *pxItem );\r
220 \r
221 /*\r
222  * Insert a list item into a list.  The item will be inserted into the list in\r
223  * a position determined by its item value (descending item value order).\r
224  *\r
225  * @param pxList The list into which the item is to be inserted.\r
226  *\r
227  * @param pxNewListItem The item to that is to be placed in the list.\r
228  *\r
229  * \page vListInsert vListInsert\r
230  * \ingroup LinkedList\r
231  */\r
232 void vListInsert( xList *pxList, xListItem *pxNewListItem );\r
233 \r
234 /*\r
235  * Insert a list item into a list.  The item will be inserted in a position\r
236  * such that it will be the last item within the list returned by multiple\r
237  * calls to listGET_OWNER_OF_NEXT_ENTRY.\r
238  *\r
239  * The list member pvIndex is used to walk through a list.  Calling\r
240  * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.\r
241  * Placing an item in a list using vListInsertEnd effectively places the item\r
242  * in the list position pointed to by pvIndex.  This means that every other\r
243  * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before\r
244  * the pvIndex parameter again points to the item being inserted.\r
245  *\r
246  * @param pxList The list into which the item is to be inserted.\r
247  *\r
248  * @param pxNewListItem The list item to be inserted into the list.\r
249  *\r
250  * \page vListInsertEnd vListInsertEnd\r
251  * \ingroup LinkedList\r
252  */\r
253 void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );\r
254 \r
255 /*\r
256  * Remove an item from a list.  The list item has a pointer to the list that\r
257  * it is in, so only the list item need be passed into the function.\r
258  *\r
259  * @param vListRemove The item to be removed.  The item will remove itself from\r
260  * the list pointed to by it's pxContainer parameter.\r
261  *\r
262  * \page vListRemove vListRemove\r
263  * \ingroup LinkedList\r
264  */\r
265 void vListRemove( xListItem *pxItemToRemove );\r
266 \r
267 \r
268 \r
269 #endif\r
270 \r