]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_MPU_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/component/lists/generic_list.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / CORTEX_MPU_M33F_NXP_LPC55S69_MCUXpresso / NXP_Code / component / lists / generic_list.c
1 /*\r
2  * Copyright 2018-2019 NXP\r
3  * All rights reserved.\r
4  *\r
5  *\r
6  * SPDX-License-Identifier: BSD-3-Clause\r
7  */\r
8 \r
9 /*! *********************************************************************************\r
10 *************************************************************************************\r
11 * Include\r
12 *************************************************************************************\r
13 ********************************************************************************** */\r
14 #include "fsl_common.h"\r
15 #include "generic_list.h"\r
16 \r
17 static list_status_t LIST_Scan(list_handle_t list, list_element_handle_t newElement)\r
18 {\r
19     list_element_handle_t element = list->head;\r
20 \r
21     while (element != NULL)\r
22     {\r
23         if (element == newElement)\r
24         {\r
25             return kLIST_DuplicateError;\r
26         }\r
27         element = element->next;\r
28     }\r
29     return kLIST_Ok;\r
30 }\r
31 \r
32 /*! *********************************************************************************\r
33 *************************************************************************************\r
34 * Public functions\r
35 *************************************************************************************\r
36 ********************************************************************************** */\r
37 /*! *********************************************************************************\r
38  * \brief     Initialises the list descriptor.\r
39  *\r
40  * \param[in] list - LIST_ handle to init.\r
41  *            max - Maximum number of elements in list. 0 for unlimited.\r
42  *\r
43  * \return void.\r
44  *\r
45  * \pre\r
46  *\r
47  * \post\r
48  *\r
49  * \remarks\r
50  *\r
51  ********************************************************************************** */\r
52 void LIST_Init(list_handle_t list, uint32_t max)\r
53 {\r
54     list->head = NULL;\r
55     list->tail = NULL;\r
56     list->max  = (uint16_t)max;\r
57     list->size = 0;\r
58 }\r
59 \r
60 /*! *********************************************************************************\r
61  * \brief     Gets the list that contains the given element.\r
62  *\r
63  * \param[in] element - Handle of the element.\r
64  *\r
65  * \return NULL if element is orphan.\r
66  *         Handle of the list the element is inserted into.\r
67  *\r
68  * \pre\r
69  *\r
70  * \post\r
71  *\r
72  * \remarks\r
73  *\r
74  ********************************************************************************** */\r
75 list_handle_t LIST_GetList(list_element_handle_t element)\r
76 {\r
77     return element->list;\r
78 }\r
79 \r
80 /*! *********************************************************************************\r
81  * \brief     Links element to the tail of the list.\r
82  *\r
83  * \param[in] list - ID of list to insert into.\r
84  *            element - element to add\r
85  *\r
86  * \return kLIST_Full if list is full.\r
87  *         kLIST_Ok if insertion was successful.\r
88  *\r
89  * \pre\r
90  *\r
91  * \post\r
92  *\r
93  * \remarks\r
94  *\r
95  ********************************************************************************** */\r
96 list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element)\r
97 {\r
98     uint32_t regPrimask = DisableGlobalIRQ();\r
99 \r
100     if ((list->max != 0U) && (list->max == list->size))\r
101     {\r
102         EnableGlobalIRQ(regPrimask);\r
103         return kLIST_Full;\r
104     }\r
105 \r
106     if (kLIST_DuplicateError == LIST_Scan(list, element))\r
107     {\r
108         EnableGlobalIRQ(regPrimask);\r
109         return kLIST_DuplicateError;\r
110     }\r
111 \r
112     if (list->size == 0U)\r
113     {\r
114         list->head = element;\r
115     }\r
116     else\r
117     {\r
118         list->tail->next = element;\r
119     }\r
120     element->prev = list->tail;\r
121     element->next = NULL;\r
122     element->list = list;\r
123     list->tail    = element;\r
124     list->size++;\r
125 \r
126     EnableGlobalIRQ(regPrimask);\r
127     return kLIST_Ok;\r
128 }\r
129 \r
130 /*! *********************************************************************************\r
131  * \brief     Links element to the head of the list.\r
132  *\r
133  * \param[in] list - ID of list to insert into.\r
134  *            element - element to add\r
135  *\r
136  * \return kLIST_Full if list is full.\r
137  *         kLIST_Ok if insertion was successful.\r
138  *\r
139  * \pre\r
140  *\r
141  * \post\r
142  *\r
143  * \remarks\r
144  *\r
145  ********************************************************************************** */\r
146 list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element)\r
147 {\r
148     uint32_t regPrimask = DisableGlobalIRQ();\r
149 \r
150     if ((list->max != 0U) && (list->max == list->size))\r
151     {\r
152         EnableGlobalIRQ(regPrimask);\r
153         return kLIST_Full;\r
154     }\r
155 \r
156     if (kLIST_DuplicateError == LIST_Scan(list, element))\r
157     {\r
158         EnableGlobalIRQ(regPrimask);\r
159         return kLIST_DuplicateError;\r
160     }\r
161 \r
162     if (list->size == 0U)\r
163     {\r
164         list->tail = element;\r
165     }\r
166     else\r
167     {\r
168         list->head->prev = element;\r
169     }\r
170     element->next = list->head;\r
171     element->prev = NULL;\r
172     element->list = list;\r
173     list->head    = element;\r
174     list->size++;\r
175 \r
176     EnableGlobalIRQ(regPrimask);\r
177     return kLIST_Ok;\r
178 }\r
179 \r
180 /*! *********************************************************************************\r
181  * \brief     Unlinks element from the head of the list.\r
182  *\r
183  * \param[in] list - ID of list to remove from.\r
184  *\r
185  * \return NULL if list is empty.\r
186  *         ID of removed element(pointer) if removal was successful.\r
187  *\r
188  * \pre\r
189  *\r
190  * \post\r
191  *\r
192  * \remarks\r
193  *\r
194  ********************************************************************************** */\r
195 list_element_handle_t LIST_RemoveHead(list_handle_t list)\r
196 {\r
197     list_element_handle_t element;\r
198 \r
199     uint32_t regPrimask = DisableGlobalIRQ();\r
200 \r
201     if ((NULL == list) || (list->size == 0U))\r
202     {\r
203         EnableGlobalIRQ(regPrimask);\r
204         return NULL; /*LIST_ is empty*/\r
205     }\r
206 \r
207     element = list->head;\r
208     list->size--;\r
209     if (list->size == 0U)\r
210     {\r
211         list->tail = NULL;\r
212     }\r
213     else\r
214     {\r
215         element->next->prev = NULL;\r
216     }\r
217     list->head    = element->next; /*Is NULL if element is head*/\r
218     element->list = NULL;\r
219 \r
220     EnableGlobalIRQ(regPrimask);\r
221     return element;\r
222 }\r
223 \r
224 /*! *********************************************************************************\r
225  * \brief     Gets head element ID.\r
226  *\r
227  * \param[in] list - ID of list.\r
228  *\r
229  * \return NULL if list is empty.\r
230  *         ID of head element if list is not empty.\r
231  *\r
232  * \pre\r
233  *\r
234  * \post\r
235  *\r
236  * \remarks\r
237  *\r
238  ********************************************************************************** */\r
239 list_element_handle_t LIST_GetHead(list_handle_t list)\r
240 {\r
241     return list->head;\r
242 }\r
243 \r
244 /*! *********************************************************************************\r
245  * \brief     Gets next element ID.\r
246  *\r
247  * \param[in] element - ID of the element.\r
248  *\r
249  * \return NULL if element is tail.\r
250  *         ID of next element if exists.\r
251  *\r
252  * \pre\r
253  *\r
254  * \post\r
255  *\r
256  * \remarks\r
257  *\r
258  ********************************************************************************** */\r
259 list_element_handle_t LIST_GetNext(list_element_handle_t element)\r
260 {\r
261     return element->next;\r
262 }\r
263 \r
264 /*! *********************************************************************************\r
265  * \brief     Gets previous element ID.\r
266  *\r
267  * \param[in] element - ID of the element.\r
268  *\r
269  * \return NULL if element is head.\r
270  *         ID of previous element if exists.\r
271  *\r
272  * \pre\r
273  *\r
274  * \post\r
275  *\r
276  * \remarks\r
277  *\r
278  ********************************************************************************** */\r
279 list_element_handle_t LIST_GetPrev(list_element_handle_t element)\r
280 {\r
281     return element->prev;\r
282 }\r
283 \r
284 /*! *********************************************************************************\r
285  * \brief     Unlinks an element from its list.\r
286  *\r
287  * \param[in] element - ID of the element to remove.\r
288  *\r
289  * \return kLIST_OrphanElement if element is not part of any list.\r
290  *         kLIST_Ok if removal was successful.\r
291  *\r
292  * \pre\r
293  *\r
294  * \post\r
295  *\r
296  * \remarks\r
297  *\r
298  ********************************************************************************** */\r
299 list_status_t LIST_RemoveElement(list_element_handle_t element)\r
300 {\r
301     if (element->list == NULL)\r
302     {\r
303         return kLIST_OrphanElement; /*Element was previusly removed or never added*/\r
304     }\r
305 \r
306     uint32_t regPrimask = DisableGlobalIRQ();\r
307 \r
308     if (element->prev == NULL) /*Element is head or solo*/\r
309     {\r
310         element->list->head = element->next; /*is null if solo*/\r
311     }\r
312     if (element->next == NULL) /*Element is tail or solo*/\r
313     {\r
314         element->list->tail = element->prev; /*is null if solo*/\r
315     }\r
316     if (element->prev != NULL) /*Element is not head*/\r
317     {\r
318         element->prev->next = element->next;\r
319     }\r
320     if (element->next != NULL) /*Element is not tail*/\r
321     {\r
322         element->next->prev = element->prev;\r
323     }\r
324     element->list->size--;\r
325     element->list = NULL;\r
326 \r
327     EnableGlobalIRQ(regPrimask);\r
328     return kLIST_Ok;\r
329 }\r
330 \r
331 /*! *********************************************************************************\r
332  * \brief     Links an element in the previous position relative to a given member\r
333  *            of a list.\r
334  *\r
335  * \param[in] element - ID of a member of a list.\r
336  *            newElement - new element to insert before the given member.\r
337  *\r
338  * \return kLIST_OrphanElement if element is not part of any list.\r
339  *         kLIST_Full if list is full.\r
340  *         kLIST_Ok if insertion was successful.\r
341  *\r
342  * \pre\r
343  *\r
344  * \post\r
345  *\r
346  * \remarks\r
347  *\r
348  ********************************************************************************** */\r
349 list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement)\r
350 {\r
351     if (element->list == NULL)\r
352     {\r
353         return kLIST_OrphanElement; /*Element was previusly removed or never added*/\r
354     }\r
355     uint32_t regPrimask = DisableGlobalIRQ();\r
356 \r
357     if ((element->list->max != 0U) && (element->list->max == element->list->size))\r
358     {\r
359         EnableGlobalIRQ(regPrimask);\r
360         return kLIST_Full;\r
361     }\r
362 \r
363     if (kLIST_DuplicateError == LIST_Scan(element->list, newElement))\r
364     {\r
365         EnableGlobalIRQ(regPrimask);\r
366         return kLIST_DuplicateError;\r
367     }\r
368 \r
369     if (element->prev == NULL) /*Element is list head*/\r
370     {\r
371         element->list->head = newElement;\r
372     }\r
373     else\r
374     {\r
375         element->prev->next = newElement;\r
376     }\r
377     newElement->list = element->list;\r
378     element->list->size++;\r
379     newElement->next = element;\r
380     newElement->prev = element->prev;\r
381     element->prev    = newElement;\r
382 \r
383     EnableGlobalIRQ(regPrimask);\r
384     return kLIST_Ok;\r
385 }\r
386 \r
387 /*! *********************************************************************************\r
388  * \brief     Gets the current size of a list.\r
389  *\r
390  * \param[in] list - ID of the list.\r
391  *\r
392  * \return Current size of the list.\r
393  *\r
394  * \pre\r
395  *\r
396  * \post\r
397  *\r
398  * \remarks\r
399  *\r
400  ********************************************************************************** */\r
401 uint32_t LIST_GetSize(list_handle_t list)\r
402 {\r
403     return list->size;\r
404 }\r
405 \r
406 /*! *********************************************************************************\r
407  * \brief     Gets the number of free places in the list.\r
408  *\r
409  * \param[in] list - ID of the list.\r
410  *\r
411  * \return Available size of the list.\r
412  *\r
413  * \pre\r
414  *\r
415  * \post\r
416  *\r
417  * \remarks\r
418  *\r
419  ********************************************************************************** */\r
420 uint32_t LIST_GetAvailableSize(list_handle_t list)\r
421 {\r
422     return ((uint32_t)list->max - (uint32_t)list->size);\r
423 }\r