1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 #ifndef TEE_CLIENT_LIST_H
14 #define TEE_CLIENT_LIST_H
15 
16 #include "tee_client_type.h"
17 
18 #define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member))
19 #define CONTAINER_OF(pos, type, member) (type *)(((char *)(pos)) - OFFSET_OF(type, member))
20 
21 #define LIST_DECLARE(name) \
22     struct ListNode name = { \
23         .next = &(name), \
24         .prev = &(name), \
25     }
26 
ListInit(struct ListNode * list)27 static inline void ListInit(struct ListNode *list)
28 {
29     list->next = list;
30     list->prev = list;
31 }
32 
33 #define LIST_HEAD(list) ((list)->next)
34 #define LIST_TAIL(list) ((list)->prev)
35 #define LIST_EMPTY(list) ((list) == (list)->next)
36 
ListInsertHead(struct ListNode * list,struct ListNode * entry)37 static inline void ListInsertHead(struct ListNode *list, struct ListNode *entry)
38 {
39     list->next->prev = entry;
40     entry->next = list->next;
41     entry->prev = list;
42     list->next = entry;
43 }
44 
ListInsertTail(struct ListNode * list,struct ListNode * entry)45 static inline void ListInsertTail(struct ListNode *list, struct ListNode *entry)
46 {
47     entry->next = list;
48     entry->prev = list->prev;
49     list->prev->next = entry;
50     list->prev = entry;
51 }
52 
ListRemoveEntry(struct ListNode * entry)53 static inline void ListRemoveEntry(struct ListNode *entry)
54 {
55     entry->prev->next = entry->next;
56     entry->next->prev = entry->prev;
57 }
58 
ListRemoveHead(struct ListNode * list)59 static inline struct ListNode *ListRemoveHead(struct ListNode *list)
60 {
61     struct ListNode *entry = NULL;
62     if (!LIST_EMPTY(list)) {
63         entry = list->next;
64         ListRemoveEntry(entry);
65     }
66     return entry;
67 }
68 
ListRemoveTail(struct ListNode * list)69 static inline struct ListNode *ListRemoveTail(struct ListNode *list)
70 {
71     struct ListNode *entry = NULL;
72     if (!LIST_EMPTY(list)) {
73         entry = list->prev;
74         ListRemoveEntry(entry);
75     }
76     return entry;
77 }
78 
79 #define LIST_ENTRY(ptr, type, member) \
80     ((type *)(((char *)(ptr)) - (unsigned long)(&(((type *)0)->member))))
81 
82 #define LIST_FOR_EACH(pos, list) \
83     for ((pos) = (list)->next; (pos) != (list); (pos) = (pos)->next)
84 
85 #define LIST_FOR_EACH_SAFE(pos, n, list) \
86     for ((pos) = (list)->next, (n) = (pos)->next; (pos) != (list); (pos) = (n), (n) = (pos)->next)
87 
88 #define LIST_FOR_EACH_ENTRY(pos, list, member)                                                       \
89     do {                                                                                             \
90         for ((pos) = LIST_ENTRY((list)->next, typeof(*(pos)), (member)); &(pos)->(member) != (list); \
91              (pos) = LIST_ENTRY((pos)->(member).next, typeof(*(pos)), (member)))                     \
92     } while (0)
93 
94 #define LIST_FOR_EACH_ENTRY_SAFE(pos, n, list, member)                                                             \
95     do {                                                                                                           \
96         for ((pos) = LIST_ENTRY((list)->next, typeof(*(pos)), (member)),                                           \
97             (n) = LIST_ENTRY((pos)->(member).next, typeof(*(pos)), (member));                                      \
98             &(pos)->(member) != (list); (pos) = (n), (n) = LIST_ENTRY((n)->(member).next, typeof(*(n)), (member))) \
99     } while (0)
100 
101 #endif
102