/* * Copyright (c) 2019-2025 Beijing Hanwei Innovation Technology Ltd. Co. and * its subsidiaries and affiliates (collectly called MKSEMI). * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into an MKSEMI * integrated circuit in a product or a software update for such product, * must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of MKSEMI nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * 4. This software, with or without modification, must only be used with a * MKSEMI integrated circuit. * * 5. Any software provided in binary form under this license must not be * reverse engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL MKSEMI OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef MK_LIST_H_ #define MK_LIST_H_ #include "mk_trace.h" #include "mk_common.h" #define MK_LIST_DEBUG 0 struct mk_list_hdr { struct mk_list_hdr *next; }; typedef struct mk_list_hdr mk_list_hdr_t; /// structure of a list struct mk_list { /// pointer to first element of the list struct mk_list_hdr *first; /// pointer to the last element struct mk_list_hdr *last; #if (MK_LIST_DEBUG) /// number of element in the list uint16_t cnt; /// max number of element in the list uint16_t maxcnt; /// min number of element in the list uint16_t mincnt; uint16_t reserved; #endif }; typedef struct mk_list mk_list_t; #ifdef __cplusplus extern "C" { #endif #define MK_LIST_POP_ELT(list, elt) mk_list_extract(&(list), &(elt->hdr)); /** * @brief Initialize a list to defaults values. * * @param[in] list Pointer to the list structure. */ void mk_list_init(struct mk_list *list); /** * @brief Add an element as last on the list. * * @param[in] list Pointer to the list structure * @param[in] list_hdr Pointer to the header to add at the end of the list */ void mk_list_push_back(struct mk_list *list, struct mk_list_hdr *list_hdr); /** * @brief Append a sequence of elements at the end of a list. * * @note The elements to append shall be linked together * * @param[in] list Pointer to the list structure * @param[in] first_hdr Pointer to the first element to append * @param[in] last_hdr Pointer to the last element to append */ void mk_list_push_back_sublist(struct mk_list *list, struct mk_list_hdr *first_hdr, struct mk_list_hdr *last_hdr); /** * @brief Add an element as first on the list. * @param[in] list Pointer to the list structure * @param[in] list_hdr Pointer to the header to add at the beginning of the list */ void mk_list_push_front(struct mk_list *list, struct mk_list_hdr *list_hdr); /** * @brief Extract the first element of the list. * @param[in] list Pointer to the list structure * @return The pointer to the element extracted, and NULL if the list is empty. */ struct mk_list_hdr *mk_list_pop_front(struct mk_list *list); /** * @brief Search for a given element in the list, and extract it if found. * * @param[in] list Pointer to the list structure * @param[in] list_hdr Element to extract * @return true if the element is found in the list, false otherwise */ bool mk_list_extract(struct mk_list *list, struct mk_list_hdr *list_hdr); /** * @brief Extract an element when the previous element is known * * @note The element to remove shall follow immediately the reference within the list * * @param[in] list Pointer to the list structure * @param[in] elt_ref_hdr Pointer to the referenced element * @note NULL if element to extract is the first in the list * @param[in] elt_to_rem_hdr Pointer to the element to be extracted */ void mk_list_extract_after(struct mk_list *list, struct mk_list_hdr *elt_ref_hdr, struct mk_list_hdr *elt_to_rem_hdr); /** * @brief Extract a sub-list when the previous element is known * * @note The elements to remove shall be linked together and follow immediately the reference element * @param[in] list Pointer to the list structure * @param[in] ref_hdr Pointer to the referenced element * @note NULL if first element to extract is first in the list * @param[in] last_hdr Pointer to the last element to extract */ void mk_list_extract_sublist(struct mk_list *list, struct mk_list_hdr *ref_hdr, struct mk_list_hdr *last_hdr); /** * @brief Searched a given element in the list. * * @param[in] list Pointer to the list structure * @param[in] list_hdr Pointer to the searched element * @return true if the element is found in the list, false otherwise */ bool mk_list_find(struct mk_list *list, struct mk_list_hdr *list_hdr); /** * @brief Merge two lists in a single one. * * @note This function appends the list pointed by list2 to the list pointed by list1. Once the merge is done, it empties list2. * * @param[in] list1 Pointer to the destination list * @param[in] list2 Pointer to the list to append to list1 */ void mk_list_merge(struct mk_list *list1, struct mk_list *list2); /** * @brief Insert a given element in the list before the referenced element. * * @param[in] list Pointer to the list structure * @param[in] elt_ref_hdr Pointer to the referenced element * @param[in] elt_to_add_hdr Pointer to the element to be inserted * @return true if the element is found in the list, false otherwise */ void mk_list_insert_before(struct mk_list *list, struct mk_list_hdr *elt_ref_hdr, struct mk_list_hdr *elt_to_add_hdr); /** * @brief Insert a given element in the list after the referenced element. * * @param[in] list Pointer to the list structure * @param[in] elt_ref_hdr Pointer to the referenced element * @param[in] elt_to_add_hdr Pointer to the element to be inserted * * @return true if the element is found in the list, false otherwise */ void mk_list_insert_after(struct mk_list *list, struct mk_list_hdr *elt_ref_hdr, struct mk_list_hdr *elt_to_add_hdr); /** * @brief Count number of elements present in the list * * @param[in] list Pointer to the list structure * * @return Number of elements present in the list */ uint16_t mk_list_size(struct mk_list *list); /** * @brief Test if the list is empty. * * @param[in] list Pointer to the list structure. * * @return true if the list is empty, false else otherwise. */ static inline bool mk_list_is_empty(const struct mk_list *const list) { bool listempty; listempty = (list->first == NULL); return (listempty); } /** * @brief Pick the first element from the list without removing it. * * @param[in] list Pointer to the list structure. * * @return First element address. Returns NULL pointer if the list is empty. */ static inline struct mk_list_hdr *mk_list_pick(const struct mk_list *const list) { return (list->first); } /** * * @brief Return following element of a list element. * * @param[in] list_hdr Pointer to the list element. * * @return The pointer to the next element. * */ static inline struct mk_list_hdr *mk_list_next(const struct mk_list_hdr *const list_hdr) { return (list_hdr->next); } #ifdef __cplusplus } #endif #endif /* MK_LIST_H_ */