123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475 |
- /*
- * Copyright 2018-2019 NXP
- * All rights reserved.
- *
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- /*! *********************************************************************************
- *************************************************************************************
- * Include
- *************************************************************************************
- ********************************************************************************** */
- #include "generic_list.h"
- static list_status_t LIST_Error_Check(list_handle_t list, list_element_handle_t newElement)
- {
- list_status_t listStatus = kLIST_Ok;
- list_element_handle_t element = list->head;
- if ((list->max != 0U) && (list->max == list->size))
- {
- listStatus = kLIST_Full; /*List is full*/
- }
- else
- {
- while (element != NULL) /*Scan list*/
- {
- /* Determine if element is duplicated */
- if (element == newElement)
- {
- listStatus = kLIST_DuplicateError;
- break;
- }
- element = element->next;
- }
- }
- return listStatus;
- }
- /*! *********************************************************************************
- *************************************************************************************
- * Public functions
- *************************************************************************************
- ********************************************************************************** */
- /*! *********************************************************************************
- * \brief Initialises the list descriptor.
- *
- * \param[in] list - LIST_ handle to init.
- * max - Maximum number of elements in list. 0 for unlimited.
- *
- * \return void.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- void LIST_Init(list_handle_t list, uint32_t max)
- {
- list->head = NULL;
- list->tail = NULL;
- list->max = (uint16_t)max;
- list->size = 0;
- }
- /*! *********************************************************************************
- * \brief Gets the list that contains the given element.
- *
- * \param[in] element - Handle of the element.
- *
- * \return NULL if element is orphan.
- * Handle of the list the element is inserted into.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_handle_t LIST_GetList(list_element_handle_t element)
- {
- return element->list;
- }
- /*! *********************************************************************************
- * \brief Links element to the tail of the list.
- *
- * \param[in] list - ID of list to insert into.
- * element - element to add
- *
- * \return kLIST_Full if list is full.
- * kLIST_Ok if insertion was successful.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_status_t LIST_AddTail(list_handle_t list, list_element_handle_t element)
- {
- uint32_t regPrimask = DisableGlobalIRQ();
- list_status_t listStatus = kLIST_Ok;
- listStatus = LIST_Error_Check(list, element);
- if (listStatus == kLIST_Ok) /* Avoiding list status error */
- {
- if (list->size == 0U)
- {
- list->head = element;
- }
- else
- {
- list->tail->next = element;
- }
- #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
- #else
- element->prev = list->tail;
- #endif
- element->list = list;
- element->next = NULL;
- list->tail = element;
- list->size++;
- }
- EnableGlobalIRQ(regPrimask);
- return listStatus;
- }
- /*! *********************************************************************************
- * \brief Links element to the head of the list.
- *
- * \param[in] list - ID of list to insert into.
- * element - element to add
- *
- * \return kLIST_Full if list is full.
- * kLIST_Ok if insertion was successful.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_status_t LIST_AddHead(list_handle_t list, list_element_handle_t element)
- {
- uint32_t regPrimask = DisableGlobalIRQ();
- list_status_t listStatus = kLIST_Ok;
- listStatus = LIST_Error_Check(list, element);
- if (listStatus == kLIST_Ok) /* Avoiding list status error */
- {
- /* Links element to the head of the list */
- if (list->size == 0U)
- {
- list->tail = element;
- }
- #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
- #else
- else
- {
- list->head->prev = element;
- }
- element->prev = NULL;
- #endif
- element->list = list;
- element->next = list->head;
- list->head = element;
- list->size++;
- }
- EnableGlobalIRQ(regPrimask);
- return listStatus;
- }
- /*! *********************************************************************************
- * \brief Unlinks element from the head of the list.
- *
- * \param[in] list - ID of list to remove from.
- *
- * \return NULL if list is empty.
- * ID of removed element(pointer) if removal was successful.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_element_handle_t LIST_RemoveHead(list_handle_t list)
- {
- list_element_handle_t element;
- uint32_t regPrimask = DisableGlobalIRQ();
- if ((NULL == list) || (list->size == 0U))
- {
- element = NULL; /*LIST_ is empty*/
- }
- else
- {
- element = list->head;
- list->size--;
- if (list->size == 0U)
- {
- list->tail = NULL;
- }
- #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
- #else
- else
- {
- element->next->prev = NULL;
- }
- #endif
- element->list = NULL;
- list->head = element->next; /*Is NULL if element is head*/
- }
- EnableGlobalIRQ(regPrimask);
- return element;
- }
- /*! *********************************************************************************
- * \brief Gets head element ID.
- *
- * \param[in] list - ID of list.
- *
- * \return NULL if list is empty.
- * ID of head element if list is not empty.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_element_handle_t LIST_GetHead(list_handle_t list)
- {
- return list->head;
- }
- /*! *********************************************************************************
- * \brief Gets next element ID.
- *
- * \param[in] element - ID of the element.
- *
- * \return NULL if element is tail.
- * ID of next element if exists.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_element_handle_t LIST_GetNext(list_element_handle_t element)
- {
- return element->next;
- }
- /*! *********************************************************************************
- * \brief Gets previous element ID.
- *
- * \param[in] element - ID of the element.
- *
- * \return NULL if element is head.
- * ID of previous element if exists.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_element_handle_t LIST_GetPrev(list_element_handle_t element)
- {
- #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
- return NULL;
- #else
- return element->prev;
- #endif
- }
- /*! *********************************************************************************
- * \brief Unlinks an element from its list.
- *
- * \param[in] element - ID of the element to remove.
- *
- * \return kLIST_OrphanElement if element is not part of any list.
- * kLIST_Ok if removal was successful.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_status_t LIST_RemoveElement(list_element_handle_t element)
- {
- list_status_t listStatus = kLIST_Ok;
- uint32_t regPrimask = DisableGlobalIRQ();
- if (element->list == NULL)
- {
- listStatus = kLIST_OrphanElement; /*Element was previusly removed or never added*/
- }
- else
- {
- #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
- list_element_handle_t element_list = element->list->head;
- while (element_list)
- {
- if (element->list->head == element)
- {
- element->list->head = element_list->next;
- break;
- }
- if (element_list->next == element)
- {
- element_list->next = element->next;
- break;
- }
- element_list = element_list->next;
- }
- #else
- if (element->prev == NULL) /*Element is head or solo*/
- {
- element->list->head = element->next; /*is null if solo*/
- }
- if (element->next == NULL) /*Element is tail or solo*/
- {
- element->list->tail = element->prev; /*is null if solo*/
- }
- if (element->prev != NULL) /*Element is not head*/
- {
- element->prev->next = element->next;
- }
- if (element->next != NULL) /*Element is not tail*/
- {
- element->next->prev = element->prev;
- }
- #endif
- element->list->size--;
- element->list = NULL;
- }
- EnableGlobalIRQ(regPrimask);
- return listStatus;
- }
- /*! *********************************************************************************
- * \brief Links an element in the previous position relative to a given member
- * of a list.
- *
- * \param[in] element - ID of a member of a list.
- * newElement - new element to insert before the given member.
- *
- * \return kLIST_OrphanElement if element is not part of any list.
- * kLIST_Full if list is full.
- * kLIST_Ok if insertion was successful.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- list_status_t LIST_AddPrevElement(list_element_handle_t element, list_element_handle_t newElement)
- {
- list_status_t listStatus = kLIST_Ok;
- uint32_t regPrimask = DisableGlobalIRQ();
- if (element->list == NULL)
- {
- listStatus = kLIST_OrphanElement; /*Element was previusly removed or never added*/
- }
- else
- {
- listStatus = LIST_Error_Check(element->list, newElement);
- if (listStatus == kLIST_Ok)
- {
- #if (defined(GENERIC_LIST_LIGHT) && (GENERIC_LIST_LIGHT > 0U))
- list_element_handle_t element_list = element->list->head;
- while (element_list)
- {
- if ((element_list->next == element) || (element_list == element))
- {
- if (element_list == element)
- {
- element->list->head = newElement;
- }
- else
- {
- element_list->next = newElement;
- }
- newElement->list = element->list;
- newElement->next = element;
- element->list->size++;
- break;
- }
- element_list = element_list->next;
- }
- #else
- if (element->prev == NULL) /*Element is list head*/
- {
- element->list->head = newElement;
- }
- else
- {
- element->prev->next = newElement;
- }
- newElement->list = element->list;
- element->list->size++;
- newElement->next = element;
- newElement->prev = element->prev;
- element->prev = newElement;
- #endif
- }
- }
- EnableGlobalIRQ(regPrimask);
- return listStatus;
- }
- /*! *********************************************************************************
- * \brief Gets the current size of a list.
- *
- * \param[in] list - ID of the list.
- *
- * \return Current size of the list.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- uint32_t LIST_GetSize(list_handle_t list)
- {
- return list->size;
- }
- /*! *********************************************************************************
- * \brief Gets the number of free places in the list.
- *
- * \param[in] list - ID of the list.
- *
- * \return Available size of the list.
- *
- * \pre
- *
- * \post
- *
- * \remarks
- *
- ********************************************************************************** */
- uint32_t LIST_GetAvailableSize(list_handle_t list)
- {
- return ((uint32_t)list->max - (uint32_t)list->size); /*Gets the number of free places in the list*/
- }
|