FreeRTOS Tetris
list.h
1 /*
2  FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
3  All rights reserved
4 
5  VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
6 
7  This file is part of the FreeRTOS distribution.
8 
9  FreeRTOS is free software; you can redistribute it and/or modify it under
10  the terms of the GNU General Public License (version 2) as published by the
11  Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
12 
13  ***************************************************************************
14  >>! NOTE: The modification to the GPL is included to allow you to !<<
15  >>! distribute a combined work that includes FreeRTOS without being !<<
16  >>! obliged to provide the source code for proprietary components !<<
17  >>! outside of the FreeRTOS kernel. !<<
18  ***************************************************************************
19 
20  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
21  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22  FOR A PARTICULAR PURPOSE. Full license text is available on the following
23  link: http://www.freertos.org/a00114.html
24 
25  ***************************************************************************
26  * *
27  * FreeRTOS provides completely free yet professionally developed, *
28  * robust, strictly quality controlled, supported, and cross *
29  * platform software that is more than just the market leader, it *
30  * is the industry's de facto standard. *
31  * *
32  * Help yourself get started quickly while simultaneously helping *
33  * to support the FreeRTOS project by purchasing a FreeRTOS *
34  * tutorial book, reference manual, or both: *
35  * http://www.FreeRTOS.org/Documentation *
36  * *
37  ***************************************************************************
38 
39  http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
40  the FAQ page "My application does not run, what could be wrong?". Have you
41  defined configASSERT()?
42 
43  http://www.FreeRTOS.org/support - In return for receiving this top quality
44  embedded software for free we request you assist our global community by
45  participating in the support forum.
46 
47  http://www.FreeRTOS.org/training - Investing in training allows your team to
48  be as productive as possible as early as possible. Now you can receive
49  FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
50  Ltd, and the world's leading authority on the world's leading RTOS.
51 
52  http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
53  including FreeRTOS+Trace - an indispensable productivity tool, a DOS
54  compatible FAT file system, and our tiny thread aware UDP/IP stack.
55 
56  http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
57  Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
58 
59  http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
60  Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
61  licenses offer ticketed support, indemnification and commercial middleware.
62 
63  http://www.SafeRTOS.com - High Integrity Systems also provide a safety
64  engineered and independently SIL3 certified version for use in safety and
65  mission critical applications that require provable dependability.
66 
67  1 tab == 4 spaces!
68 */
69 
70 /*
71  * This is the list implementation used by the scheduler. While it is tailored
72  * heavily for the schedulers needs, it is also available for use by
73  * application code.
74  *
75  * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
76  * numeric value (xItemValue). Most of the time the lists are sorted in
77  * descending item value order.
78  *
79  * Lists are created already containing one list item. The value of this
80  * item is the maximum possible that can be stored, it is therefore always at
81  * the end of the list and acts as a marker. The list member pxHead always
82  * points to this marker - even though it is at the tail of the list. This
83  * is because the tail contains a wrap back pointer to the true head of
84  * the list.
85  *
86  * In addition to it's value, each list item contains a pointer to the next
87  * item in the list (pxNext), a pointer to the list it is in (pxContainer)
88  * and a pointer to back to the object that contains it. These later two
89  * pointers are included for efficiency of list manipulation. There is
90  * effectively a two way link between the object containing the list item and
91  * the list item itself.
92  *
93  *
94  * \page ListIntroduction List Implementation
95  * \ingroup FreeRTOSIntro
96  */
97 
98 #ifndef INC_FREERTOS_H
99 #error FreeRTOS.h must be included before list.h
100 #endif
101 
102 #ifndef LIST_H
103 #define LIST_H
104 
105 /*
106  * The list structure members are modified from within interrupts, and therefore
107  * by rights should be declared volatile. However, they are only modified in a
108  * functionally atomic way (within critical sections of with the scheduler
109  * suspended) and are either passed by reference into a function or indexed via
110  * a volatile variable. Therefore, in all use cases tested so far, the volatile
111  * qualifier can be omitted in order to provide a moderate performance
112  * improvement without adversely affecting functional behaviour. The assembly
113  * instructions generated by the IAR, ARM and GCC compilers when the respective
114  * compiler's options were set for maximum optimisation has been inspected and
115  * deemed to be as intended. That said, as compiler technology advances, and
116  * especially if aggressive cross module optimisation is used (a use case that
117  * has not been exercised to any great extend) then it is feasible that the
118  * volatile qualifier will be needed for correct optimisation. It is expected
119  * that a compiler removing essential code because, without the volatile
120  * qualifier on the list structure members and with aggressive cross module
121  * optimisation, the compiler deemed the code unnecessary will result in
122  * complete and obvious failure of the scheduler. If this is ever experienced
123  * then the volatile qualifier can be inserted in the relevant places within the
124  * list structures by simply defining configLIST_VOLATILE to volatile in
125  * FreeRTOSConfig.h (as per the example at the bottom of this comment block).
126  * If configLIST_VOLATILE is not defined then the preprocessor directives below
127  * will simply #define configLIST_VOLATILE away completely.
128  *
129  * To use volatile list structure members then add the following line to
130  * FreeRTOSConfig.h (without the quotes):
131  * "#define configLIST_VOLATILE volatile"
132  */
133 #ifndef configLIST_VOLATILE
134 #define configLIST_VOLATILE
135 #endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
136 
137 #ifdef __cplusplus
138 extern "C" {
139 #endif
140 
141 /* Macros that can be used to place known values within the list structures,
142 then check that the known values do not get corrupted during the execution of
143 the application. These may catch the list data structures being overwritten in
144 memory. They will not catch data errors caused by incorrect configuration or
145 use of FreeRTOS.*/
146 #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
147 /* Define the macros to do nothing. */
148 #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
149 #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
150 #define listFIRST_LIST_INTEGRITY_CHECK_VALUE
151 #define listSECOND_LIST_INTEGRITY_CHECK_VALUE
152 #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
153 #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
154 #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
155 #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
156 #define listTEST_LIST_ITEM_INTEGRITY( pxItem )
157 #define listTEST_LIST_INTEGRITY( pxList )
158 #else
159 /* Define macros that add new members into the list structures. */
160 #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;
161 #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;
162 #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;
163 #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;
164 
165 /* Define macros that set the new structure members to known values. */
166 #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
167 #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
168 #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
169 #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
170 
171 /* Define macros that will assert if one of the structure members does not
172 contain its expected value. */
173 #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
174 #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
175 #endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
176 
177 
178 /*
179  * Definition of the only type of object that a list can contain.
180  */
181 struct xLIST_ITEM {
182  listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
183  configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
184  struct xLIST_ITEM *configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
185  struct xLIST_ITEM *configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
186  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. */
187  void *configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
188  listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
189 };
190 typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
191 
193  listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
194  configLIST_VOLATILE TickType_t xItemValue;
195  struct xLIST_ITEM *configLIST_VOLATILE pxNext;
196  struct xLIST_ITEM *configLIST_VOLATILE pxPrevious;
197 };
198 typedef struct xMINI_LIST_ITEM MiniListItem_t;
199 
200 /*
201  * Definition of the type of queue used by the scheduler.
202  */
203 typedef struct xLIST {
204  listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
205  configLIST_VOLATILE UBaseType_t uxNumberOfItems;
206  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 (). */
207  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. */
208  listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
209 } List_t;
210 
211 /*
212  * Access macro to set the owner of a list item. The owner of a list item
213  * is the object (usually a TCB) that contains the list item.
214  *
215  * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
216  * \ingroup LinkedList
217  */
218 #define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
219 
220 /*
221  * Access macro to get the owner of a list item. The owner of a list item
222  * is the object (usually a TCB) that contains the list item.
223  *
224  * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
225  * \ingroup LinkedList
226  */
227 #define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
228 
229 /*
230  * Access macro to set the value of the list item. In most cases the value is
231  * used to sort the list in descending order.
232  *
233  * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
234  * \ingroup LinkedList
235  */
236 #define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
237 
238 /*
239  * Access macro to retrieve the value of the list item. The value can
240  * represent anything - for example the priority of a task, or the time at
241  * which a task should be unblocked.
242  *
243  * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
244  * \ingroup LinkedList
245  */
246 #define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
247 
248 /*
249  * Access macro to retrieve the value of the list item at the head of a given
250  * list.
251  *
252  * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
253  * \ingroup LinkedList
254  */
255 #define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
256 
257 /*
258  * Return the list item at the head of the list.
259  *
260  * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
261  * \ingroup LinkedList
262  */
263 #define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
264 
265 /*
266  * Return the list item at the head of the list.
267  *
268  * \page listGET_NEXT listGET_NEXT
269  * \ingroup LinkedList
270  */
271 #define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
272 
273 /*
274  * Return the list item that marks the end of the list
275  *
276  * \page listGET_END_MARKER listGET_END_MARKER
277  * \ingroup LinkedList
278  */
279 #define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
280 
281 /*
282  * Access macro to determine if a list contains any items. The macro will
283  * only have the value true if the list is empty.
284  *
285  * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
286  * \ingroup LinkedList
287  */
288 #define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
289 
290 /*
291  * Access macro to return the number of items in the list.
292  */
293 #define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
294 
295 /*
296  * Access function to obtain the owner of the next entry in a list.
297  *
298  * The list member pxIndex is used to walk through a list. Calling
299  * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
300  * and returns that entry's pxOwner parameter. Using multiple calls to this
301  * function it is therefore possible to move through every item contained in
302  * a list.
303  *
304  * The pxOwner parameter of a list item is a pointer to the object that owns
305  * the list item. In the scheduler this is normally a task control block.
306  * The pxOwner parameter effectively creates a two way link between the list
307  * item and its owner.
308  *
309  * @param pxTCB pxTCB is set to the address of the owner of the next list item.
310  * @param pxList The list from which the next item owner is to be returned.
311  *
312  * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
313  * \ingroup LinkedList
314  */
315 #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
316  { \
317  List_t * const pxConstList = ( pxList ); \
318  /* Increment the index to the next item and return the item, ensuring */ \
319  /* we don't return the marker used at the end of the list. */ \
320  ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
321  if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
322  { \
323  ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
324  } \
325  ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
326  }
327 
328 
329 /*
330  * Access function to obtain the owner of the first entry in a list. Lists
331  * are normally sorted in ascending item value order.
332  *
333  * This function returns the pxOwner member of the first item in the list.
334  * The pxOwner parameter of a list item is a pointer to the object that owns
335  * the list item. In the scheduler this is normally a task control block.
336  * The pxOwner parameter effectively creates a two way link between the list
337  * item and its owner.
338  *
339  * @param pxList The list from which the owner of the head item is to be
340  * returned.
341  *
342  * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
343  * \ingroup LinkedList
344  */
345 #define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
346 
347 /*
348  * Check to see if a list item is within a list. The list item maintains a
349  * "container" pointer that points to the list it is in. All this macro does
350  * is check to see if the container and the list match.
351  *
352  * @param pxList The list we want to know if the list item is within.
353  * @param pxListItem The list item we want to know if is in the list.
354  * @return pdTRUE if the list item is in the list, otherwise pdFALSE.
355  */
356 #define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
357 
358 /*
359  * Return the list a list item is contained within (referenced from).
360  *
361  * @param pxListItem The list item being queried.
362  * @return A pointer to the List_t object that references the pxListItem
363  */
364 #define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
365 
366 /*
367  * This provides a crude means of knowing if a list has been initialised, as
368  * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
369  * function.
370  */
371 #define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
372 
373 /*
374  * Must be called before a list is used! This initialises all the members
375  * of the list structure and inserts the xListEnd item into the list as a
376  * marker to the back of the list.
377  *
378  * @param pxList Pointer to the list being initialised.
379  *
380  * \page vListInitialise vListInitialise
381  * \ingroup LinkedList
382  */
383 void vListInitialise(List_t *const pxList) PRIVILEGED_FUNCTION;
384 
385 /*
386  * Must be called before a list item is used. This sets the list container to
387  * null so the item does not think that it is already contained in a list.
388  *
389  * @param pxItem Pointer to the list item being initialised.
390  *
391  * \page vListInitialiseItem vListInitialiseItem
392  * \ingroup LinkedList
393  */
394 void vListInitialiseItem(ListItem_t *const pxItem) PRIVILEGED_FUNCTION;
395 
396 /*
397  * Insert a list item into a list. The item will be inserted into the list in
398  * a position determined by its item value (descending item value order).
399  *
400  * @param pxList The list into which the item is to be inserted.
401  *
402  * @param pxNewListItem The item that is to be placed in the list.
403  *
404  * \page vListInsert vListInsert
405  * \ingroup LinkedList
406  */
407 void vListInsert(List_t *const pxList, ListItem_t *const pxNewListItem) PRIVILEGED_FUNCTION;
408 
409 /*
410  * Insert a list item into a list. The item will be inserted in a position
411  * such that it will be the last item within the list returned by multiple
412  * calls to listGET_OWNER_OF_NEXT_ENTRY.
413  *
414  * The list member pxIndex is used to walk through a list. Calling
415  * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
416  * Placing an item in a list using vListInsertEnd effectively places the item
417  * in the list position pointed to by pxIndex. This means that every other
418  * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
419  * the pxIndex parameter again points to the item being inserted.
420  *
421  * @param pxList The list into which the item is to be inserted.
422  *
423  * @param pxNewListItem The list item to be inserted into the list.
424  *
425  * \page vListInsertEnd vListInsertEnd
426  * \ingroup LinkedList
427  */
428 void vListInsertEnd(List_t *const pxList, ListItem_t *const pxNewListItem) PRIVILEGED_FUNCTION;
429 
430 /*
431  * Remove an item from a list. The list item has a pointer to the list that
432  * it is in, so only the list item need be passed into the function.
433  *
434  * @param uxListRemove The item to be removed. The item will remove itself from
435  * the list pointed to by it's pxContainer parameter.
436  *
437  * @return The number of items that remain in the list after the list item has
438  * been removed.
439  *
440  * \page uxListRemove uxListRemove
441  * \ingroup LinkedList
442  */
443 UBaseType_t uxListRemove(ListItem_t *const pxItemToRemove) PRIVILEGED_FUNCTION;
444 
445 #ifdef __cplusplus
446 }
447 #endif
448 
449 #endif
450 
xLIST_ITEM
Definition: list.h:181
TickType_t
uint32_t TickType_t
FreeRTOS definition for a single tick.
Definition: portmacro.h:98
xMINI_LIST_ITEM
Definition: list.h:192
UBaseType_t
unsigned long UBaseType_t
FreeRTOS definition for unsigned long ints.
Definition: portmacro.h:92
xLIST
Definition: list.h:203