• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_IPC_DOUBLY_LINKED_LIST_H
17 #define OHOS_IPC_DOUBLY_LINKED_LIST_H
18 
19 #include <stdbool.h>
20 #include <stddef.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif /* __cplusplus */
25 
26 typedef struct DL_LIST {
27     struct DL_LIST *pstPrev; /* < Current node's pointer to the previous node */
28     struct DL_LIST *pstNext; /* < Current node's pointer to the next node */
29 } DL_LIST;
30 
31 /* List initialize */
DLListInit(DL_LIST * list)32 static inline void DLListInit(DL_LIST *list)
33 {
34     list->pstNext = list;
35     list->pstPrev = list;
36 }
37 
38 /* Get list head node */
39 #define DL_GET_LIST_HEAD(object) ((object)->pstNext)
40 
41 /* Get list tail node */
42 #define DL_GET_LIST_TAIL(object) ((object)->pstPrev)
43 
44 /* Insert a new node to list. */
DLListAdd(DL_LIST * list,DL_LIST * node)45 static inline void DLListAdd(DL_LIST *list, DL_LIST *node)
46 {
47     node->pstNext = list->pstNext;
48     node->pstPrev = list;
49     list->pstNext->pstPrev = node;
50     list->pstNext = node;
51 }
52 
53 /* Insert a node to the tail of a list. */
DLListTailInsert(DL_LIST * list,DL_LIST * node)54 static inline void DLListTailInsert(DL_LIST *list, DL_LIST *node)
55 {
56     DLListAdd(list->pstPrev, node);
57 }
58 
59 /* Insert a new node to list. */
DLListInsert(DL_LIST * list,DL_LIST * node)60 static inline void DLListInsert(DL_LIST *list, DL_LIST *node)
61 {
62     DLListAdd(list, node);
63 }
64 
65 /* Delete a specified node from list. */
DLListDelete(DL_LIST * node)66 static inline void DLListDelete(DL_LIST *node)
67 {
68     node->pstNext->pstPrev = node->pstPrev;
69     node->pstPrev->pstNext = node->pstNext;
70     node->pstNext = NULL;
71     node->pstPrev = NULL;
72 }
73 
74 /* Check list is empty. */
DLListEmpty(DL_LIST * list)75 static inline bool DLListEmpty(DL_LIST *list)
76 {
77     return (bool)(list->pstNext == list);
78 }
79 
80 /* Obtain the pointer to a list in a structure. */
81 #define DL_OFF_SET_OF(type, member) ((size_t)&((type *)0)->member)
82 
83 /* Obtain the pointer to a structure that contains a list. */
84 #define DL_LIST_ENTRY(item, type, member) \
85     ((type *)(void *)((char *)(item) - DL_OFF_SET_OF(type, member)))
86 
87 /* Iterate over a list of given type. */
88 #define DL_LIST_FOR_EACH_ENTRY(item, list, type, member) \
89     for ((item) = DL_LIST_ENTRY((list)->pstNext, type, member); \
90         ((item) != NULL) && (&(item)->member != (list)); \
91         (item) = DL_LIST_ENTRY((item)->member.pstNext, type, member))
92 
93 /* Iterate over a list safe against removal of list entry. */
94 #define DL_LIST_FOR_EACH_ENTRY_SAFE(item, next, list, type, member) \
95     for ((item) = DL_LIST_ENTRY((list)->pstNext, type, member), \
96         (next) = DL_LIST_ENTRY((item)->member.pstNext, type, member); \
97         &(item)->member != (list); \
98         (item) = (next), (next) = DL_LIST_ENTRY((item)->member.pstNext, type, member))
99 
100 
DLListDel(DL_LIST * prevNode,DL_LIST * nextNode)101 static inline void DLListDel(DL_LIST *prevNode, DL_LIST *nextNode)
102 {
103     nextNode->pstPrev = prevNode;
104     prevNode->pstNext = nextNode;
105 }
106 
107 /* Delete node and initialize list */
ListDeInit(DL_LIST * list)108 static inline void ListDeInit(DL_LIST *list)
109 {
110     DLListDel(list->pstPrev, list->pstNext);
111     DLListInit(list);
112 }
113 
114 /* Iterate over a list. */
115 #define DL_LIST_FOR_EACH(item, list) \
116     for ((item) = (list)->pstNext; \
117         (item) != (list); \
118         (item) = (item)->pstNext)
119 
120 /* Iterate over a list safe against removal of list entry. */
121 #define DL_LIST_FOR_EACH_SAFE(item, next, list) \
122     for ((item) = (list)->pstNext, (next) = (item)->pstNext; \
123          (item) != (list); \
124          (item) = (next), (next) = (item)->pstNext)
125 
126 /* Initialize a list. */
127 #define DL_LIST_HEAD(list) DL_LIST list = { &(list), &(list) }
128 
129 #ifdef __cplusplus
130 }
131 #endif /* __cplusplus */
132 #endif  /* OHOS_IPC_DOUBLY_LINKED_LIST_H */