2 * Copyright 2018-2019 NXP
\r
3 * All rights reserved.
\r
6 * SPDX-License-Identifier: BSD-3-Clause
\r
9 /*! *********************************************************************************
\r
10 *************************************************************************************
\r
12 *************************************************************************************
\r
13 ********************************************************************************** */
\r
14 #include "fsl_common.h"
\r
15 #include "generic_list.h"
\r
17 static list_status_t LIST_Scan(list_handle_t list, list_element_handle_t newElement)
\r
19 list_element_handle_t element = list->head;
\r
21 while (element != NULL)
\r
23 if (element == newElement)
\r
25 return kLIST_DuplicateError;
\r
27 element = element->next;
\r
32 /*! *********************************************************************************
\r
33 *************************************************************************************
\r
35 *************************************************************************************
\r
36 ********************************************************************************** */
\r
37 /*! *********************************************************************************
\r
38 * \brief Initialises the list descriptor.
\r
40 * \param[in] list - LIST_ handle to init.
\r
41 * max - Maximum number of elements in list. 0 for unlimited.
\r
51 ********************************************************************************** */
\r
52 void LIST_Init(list_handle_t list, uint32_t max)
\r
56 list->max = (uint16_t)max;
\r
60 /*! *********************************************************************************
\r
61 * \brief Gets the list that contains the given element.
\r
63 * \param[in] element - Handle of the element.
\r
65 * \return NULL if element is orphan.
\r
66 * Handle of the list the element is inserted into.
\r
74 ********************************************************************************** */
\r
75 list_handle_t LIST_GetList(list_element_handle_t element)
\r
77 return element->list;
\r
80 /*! *********************************************************************************
\r
81 * \brief Links element to the tail of the list.
\r
83 * \param[in] list - ID of list to insert into.
\r
84 * element - element to add
\r
86 * \return kLIST_Full if list is full.
\r
87 * kLIST_Ok if insertion was successful.
\r
95 ********************************************************************************** */
\r
96 list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element)
\r
98 uint32_t regPrimask = DisableGlobalIRQ();
\r
100 if ((list->max != 0U) && (list->max == list->size))
\r
102 EnableGlobalIRQ(regPrimask);
\r
106 if (kLIST_DuplicateError == LIST_Scan(list, element))
\r
108 EnableGlobalIRQ(regPrimask);
\r
109 return kLIST_DuplicateError;
\r
112 if (list->size == 0U)
\r
114 list->head = element;
\r
118 list->tail->next = element;
\r
120 element->prev = list->tail;
\r
121 element->next = NULL;
\r
122 element->list = list;
\r
123 list->tail = element;
\r
126 EnableGlobalIRQ(regPrimask);
\r
130 /*! *********************************************************************************
\r
131 * \brief Links element to the head of the list.
\r
133 * \param[in] list - ID of list to insert into.
\r
134 * element - element to add
\r
136 * \return kLIST_Full if list is full.
\r
137 * kLIST_Ok if insertion was successful.
\r
145 ********************************************************************************** */
\r
146 list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element)
\r
148 uint32_t regPrimask = DisableGlobalIRQ();
\r
150 if ((list->max != 0U) && (list->max == list->size))
\r
152 EnableGlobalIRQ(regPrimask);
\r
156 if (kLIST_DuplicateError == LIST_Scan(list, element))
\r
158 EnableGlobalIRQ(regPrimask);
\r
159 return kLIST_DuplicateError;
\r
162 if (list->size == 0U)
\r
164 list->tail = element;
\r
168 list->head->prev = element;
\r
170 element->next = list->head;
\r
171 element->prev = NULL;
\r
172 element->list = list;
\r
173 list->head = element;
\r
176 EnableGlobalIRQ(regPrimask);
\r
180 /*! *********************************************************************************
\r
181 * \brief Unlinks element from the head of the list.
\r
183 * \param[in] list - ID of list to remove from.
\r
185 * \return NULL if list is empty.
\r
186 * ID of removed element(pointer) if removal was successful.
\r
194 ********************************************************************************** */
\r
195 list_element_handle_t LIST_RemoveHead(list_handle_t list)
\r
197 list_element_handle_t element;
\r
199 uint32_t regPrimask = DisableGlobalIRQ();
\r
201 if ((NULL == list) || (list->size == 0U))
\r
203 EnableGlobalIRQ(regPrimask);
\r
204 return NULL; /*LIST_ is empty*/
\r
207 element = list->head;
\r
209 if (list->size == 0U)
\r
215 element->next->prev = NULL;
\r
217 list->head = element->next; /*Is NULL if element is head*/
\r
218 element->list = NULL;
\r
220 EnableGlobalIRQ(regPrimask);
\r
224 /*! *********************************************************************************
\r
225 * \brief Gets head element ID.
\r
227 * \param[in] list - ID of list.
\r
229 * \return NULL if list is empty.
\r
230 * ID of head element if list is not empty.
\r
238 ********************************************************************************** */
\r
239 list_element_handle_t LIST_GetHead(list_handle_t list)
\r
244 /*! *********************************************************************************
\r
245 * \brief Gets next element ID.
\r
247 * \param[in] element - ID of the element.
\r
249 * \return NULL if element is tail.
\r
250 * ID of next element if exists.
\r
258 ********************************************************************************** */
\r
259 list_element_handle_t LIST_GetNext(list_element_handle_t element)
\r
261 return element->next;
\r
264 /*! *********************************************************************************
\r
265 * \brief Gets previous element ID.
\r
267 * \param[in] element - ID of the element.
\r
269 * \return NULL if element is head.
\r
270 * ID of previous element if exists.
\r
278 ********************************************************************************** */
\r
279 list_element_handle_t LIST_GetPrev(list_element_handle_t element)
\r
281 return element->prev;
\r
284 /*! *********************************************************************************
\r
285 * \brief Unlinks an element from its list.
\r
287 * \param[in] element - ID of the element to remove.
\r
289 * \return kLIST_OrphanElement if element is not part of any list.
\r
290 * kLIST_Ok if removal was successful.
\r
298 ********************************************************************************** */
\r
299 list_status_t LIST_RemoveElement(list_element_handle_t element)
\r
301 if (element->list == NULL)
\r
303 return kLIST_OrphanElement; /*Element was previusly removed or never added*/
\r
306 uint32_t regPrimask = DisableGlobalIRQ();
\r
308 if (element->prev == NULL) /*Element is head or solo*/
\r
310 element->list->head = element->next; /*is null if solo*/
\r
312 if (element->next == NULL) /*Element is tail or solo*/
\r
314 element->list->tail = element->prev; /*is null if solo*/
\r
316 if (element->prev != NULL) /*Element is not head*/
\r
318 element->prev->next = element->next;
\r
320 if (element->next != NULL) /*Element is not tail*/
\r
322 element->next->prev = element->prev;
\r
324 element->list->size--;
\r
325 element->list = NULL;
\r
327 EnableGlobalIRQ(regPrimask);
\r
331 /*! *********************************************************************************
\r
332 * \brief Links an element in the previous position relative to a given member
\r
335 * \param[in] element - ID of a member of a list.
\r
336 * newElement - new element to insert before the given member.
\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
348 ********************************************************************************** */
\r
349 list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement)
\r
351 if (element->list == NULL)
\r
353 return kLIST_OrphanElement; /*Element was previusly removed or never added*/
\r
355 uint32_t regPrimask = DisableGlobalIRQ();
\r
357 if ((element->list->max != 0U) && (element->list->max == element->list->size))
\r
359 EnableGlobalIRQ(regPrimask);
\r
363 if (kLIST_DuplicateError == LIST_Scan(element->list, newElement))
\r
365 EnableGlobalIRQ(regPrimask);
\r
366 return kLIST_DuplicateError;
\r
369 if (element->prev == NULL) /*Element is list head*/
\r
371 element->list->head = newElement;
\r
375 element->prev->next = newElement;
\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
383 EnableGlobalIRQ(regPrimask);
\r
387 /*! *********************************************************************************
\r
388 * \brief Gets the current size of a list.
\r
390 * \param[in] list - ID of the list.
\r
392 * \return Current size of the list.
\r
400 ********************************************************************************** */
\r
401 uint32_t LIST_GetSize(list_handle_t list)
\r
406 /*! *********************************************************************************
\r
407 * \brief Gets the number of free places in the list.
\r
409 * \param[in] list - ID of the list.
\r
411 * \return Available size of the list.
\r
419 ********************************************************************************** */
\r
420 uint32_t LIST_GetAvailableSize(list_handle_t list)
\r
422 return ((uint32_t)list->max - (uint32_t)list->size);
\r