summaryrefslogtreecommitdiff
path: root/FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/include/private/iot_doubly_linked_list.h
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/include/private/iot_doubly_linked_list.h')
-rw-r--r--FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/include/private/iot_doubly_linked_list.h242
1 files changed, 242 insertions, 0 deletions
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/include/private/iot_doubly_linked_list.h b/FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/include/private/iot_doubly_linked_list.h
new file mode 100644
index 000000000..734dd8f78
--- /dev/null
+++ b/FreeRTOS-Labs/Demo/FreeRTOS_Plus_POSIX_with_actor_Windows_Simulator/lib/include/private/iot_doubly_linked_list.h
@@ -0,0 +1,242 @@
+/*
+ * Amazon FreeRTOS Common V1.0.0
+ * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/**
+ * @file iot_doubly_linked_list.h
+ * @brief Doubly Linked List implementation.
+ *
+ * A generic implementation of circular Doubly Linked List which consists of a
+ * list head and some list entries (zero in case of an empty list).
+ *
+ * To start with, a structure of type Link_t should be embedded in the structure
+ * which is to be organized as doubly linked list.
+ * @code
+ * typedef struct UserStruct
+ * {
+ * uint32_t ulField1;
+ * uint32_t ulField2;
+ * Link_t xLink;
+ * } UserStruct_t;
+ * @endcode
+ *
+ * A List head should then be defined and initialized.
+ * @code
+ * Link_t xListHead;
+ * listINIT_HEAD( &xListHead );
+ * @endcode
+ *
+ * listADD can then be used to add nodes to the list.
+ * @code
+ * listADD( &( xListHead ), &( pxUserStruct->xLink ) );
+ * @endcode
+ *
+ * listFOR_EACH can be used for traversing the list.
+ * @code
+ * Link_t *pxLink;
+ * UserStruct_t *pxUserStruct;
+ * listFOR_EACH( pxLink, &( xListHead ) )
+ * {
+ * pxUserStruct = listCONTAINER( pxLink, UserStruct_t, xLink );
+ * }
+ * @endcode
+ *
+ * listFOR_EACH_SAFE should be used if you want to perform destructive operations
+ * (like free) on nodes while traversing the list.
+ * @code
+ * Link_t *pxLink, *pxTempLink;
+ * UserStruct_t *pxUserStruct;
+ * listFOR_EACH( pxLink, pxTempLink, &( xListHead ) )
+ * {
+ * pxUserStruct = listCONTAINER( pxLink, UserStruct_t, xLink );
+ * free( pxUserStruct );
+ * }
+ * @endcode
+ */
+
+#ifndef _AWS_DOUBLY_LINKED_LIST_H_
+#define _AWS_DOUBLY_LINKED_LIST_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * @brief Struct embedded in any struct to make it a doubly linked
+ * list.
+ *
+ * pxNext in the head points to the first node in the list and pxPrev
+ * in the head points to the last node in the list. In case of empty
+ * list, both pxPrev and pxNext in the head point to the head node itself.
+ */
+typedef struct Link
+{
+ struct Link * pxPrev; /**< Pointer to the previous node. */
+ struct Link * pxNext; /**< Pointer to the next node. */
+} Link_t;
+
+/**
+ * @brief Initializes the given list head to an empty list.
+ *
+ * @param[in] pxHead The given list head to initialize.
+ */
+#define listINIT_HEAD( pxHead ) \
+ { \
+ ( pxHead )->pxPrev = ( pxHead ); \
+ ( pxHead )->pxNext = ( pxHead ); \
+ }
+
+/**
+ * @brief Adds the given new node to the given list.
+ *
+ * @param[in] pxHead The head of the given list.
+ * @param[in] pxLink The given new node to be added to the given
+ * list.
+ */
+#define listADD( pxHead, pxLink ) \
+ { \
+ Link_t * pxPrevLink = ( pxHead ); \
+ Link_t * pxNextLink = ( ( pxHead )->pxNext ); \
+ \
+ ( pxLink )->pxNext = pxNextLink; \
+ pxNextLink->pxPrev = ( pxLink ); \
+ pxPrevLink->pxNext = ( pxLink ); \
+ ( pxLink )->pxPrev = ( pxPrevLink ); \
+ }
+
+/**
+ * @brief Removes the given node from the list it is part of.
+ *
+ * If the given node is not a part of any list (i.e. next and previous
+ * nodes are NULL), nothing happens.
+ *
+ * @param[in] pxLink The given node to remove from the list.
+ */
+#define listREMOVE( pxLink ) \
+ { \
+ /* If the link is part of a list, remove it from the list. */ \
+ if( ( pxLink )->pxNext != NULL && ( pxLink )->pxPrev != NULL ) \
+ { \
+ ( pxLink )->pxPrev->pxNext = ( pxLink )->pxNext; \
+ ( pxLink )->pxNext->pxPrev = ( pxLink )->pxPrev; \
+ } \
+ \
+ /* Make sure that this link is not part of any list anymore. */ \
+ ( pxLink )->pxPrev = NULL; \
+ ( pxLink )->pxNext = NULL; \
+ }
+
+/**
+ * @brief Given the head of a list, checks if the list is empty.
+ *
+ * @param[in] pxHead The head of the given list.
+ */
+#define listIS_EMPTY( pxHead ) ( ( ( pxHead ) == NULL ) || ( ( pxHead )->pxNext == ( pxHead ) ) )
+
+/**
+ * @brief Removes the first node from the given list and returns it.
+ *
+ * Removes the first node from the given list and assigns it to the
+ * pxLink parameter. If the list is empty, it assigns NULL to the
+ * pxLink.
+ *
+ * @param[in] pxHead The head of the list from which to remove the
+ * first node.
+ * @param[out] pxLink The output parameter to receive the removed
+ * node.
+ */
+#define listPOP( pxHead, pxLink ) \
+ { \
+ if( listIS_EMPTY( ( pxHead ) ) ) \
+ { \
+ ( pxLink ) = NULL; \
+ } \
+ else \
+ { \
+ ( pxLink ) = ( pxHead )->pxNext; \
+ /* If the link is part of a list, remove it from the list. */ \
+ if( ( pxLink )->pxNext != NULL && ( pxLink )->pxPrev != NULL ) \
+ { \
+ ( pxLink )->pxPrev->pxNext = ( pxLink )->pxNext; \
+ ( pxLink )->pxNext->pxPrev = ( pxLink )->pxPrev; \
+ } \
+ \
+ /* Make sure that this link is not part of any list anymore. */ \
+ ( pxLink )->pxPrev = NULL; \
+ ( pxLink )->pxNext = NULL; \
+ } \
+ }
+
+/**
+ * @brief Merges a list into a given list.
+ *
+ * @param[in] pxHeadResultList The head of the given list into which the
+ * other list should be merged.
+ * @param[in] pxHeadListToMerge The head of the list to be merged into the
+ * given list.
+ */
+#define listMERGE( pxHeadResultList, pxHeadListToMerge ) \
+ { \
+ if( !listIS_EMPTY( ( pxHeadListToMerge ) ) ) \
+ { \
+ /* Setup links between last node of listToMerge and first node of resultList. */ \
+ ( pxHeadListToMerge )->pxPrev->pxNext = ( pxHeadResultList )->pxNext; \
+ ( pxHeadResultList )->pxNext->pxPrev = ( pxHeadListToMerge )->pxPrev; \
+ \
+ /* Setup links between first node of listToMerge and the head of resultList. */ \
+ ( pxHeadListToMerge )->pxNext->pxPrev = ( pxHeadResultList ); \
+ ( pxHeadResultList )->pxNext = ( pxHeadListToMerge )->pxNext; \
+ /* Empty the merged list. */ \
+ listINIT_HEAD( ( pxHeadListToMerge ) ); \
+ } \
+ }
+
+/**
+ * @brief Helper macro to iterate over a list. pxLink contains the link node
+ * in each iteration.
+ */
+#define listFOR_EACH( pxLink, pxHead ) \
+ for( ( pxLink ) = ( pxHead )->pxNext; \
+ ( pxLink ) != ( pxHead ); \
+ ( pxLink ) = ( pxLink )->pxNext )
+
+/**
+ * @brief Helper macro to iterate over a list. It is safe to destroy/free the
+ * nodes while iterating. pxLink contains the link node in each iteration.
+ */
+#define listFOR_EACH_SAFE( pxLink, pxTempLink, pxHead ) \
+ for( ( pxLink ) = ( pxHead )->pxNext, ( pxTempLink ) = ( pxLink )->pxNext; \
+ ( pxLink ) != ( pxHead ); \
+ ( pxLink ) = ( pxTempLink ), ( pxTempLink ) = ( pxLink )->pxNext )
+
+/**
+ * @brief Given the pointer to the link member (of type Link_t) in a struct,
+ * extracts the pointer to the containing struct.
+ *
+ * @param[in] pxLink The pointer to the link member.
+ * @param[in] type The type of the containing struct.
+ * @param[in] member Name of the link member in the containing struct.
+ */
+#define listCONTAINER( pxLink, type, member ) ( ( type * ) ( ( uint8_t * ) ( pxLink ) - ( uint8_t * ) ( &( ( type * ) 0 )->member ) ) )
+
+#endif /* _AWS_DOUBLY_LINKED_LIST_H_ */