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