1 /*
2  * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3  */
4 
5 #ifndef K_LIST_H
6 #define K_LIST_H
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 /** @addtogroup aos_rhino list
13  *  List operations
14  *
15  *  @{
16  */
17 
18 /**
19  * As a member of other structures, 'klist_t' can form a doubly linked list.
20  */
21 typedef struct klist_s {
22     struct klist_s *next;
23     struct klist_s *prev;
24 } klist_t;
25 
26 /**
27  * Get the struct for this entry.
28  *
29  * @param[in]  node    the list head to take the element from.
30  * @param[in]  type    the type of the struct this is embedded in.
31  * @param[in]  member  the name of the klist_t within the struct.
32  *
33  * @return  the pointer to struct
34  */
35 #define krhino_list_entry(node, type, member) ((type *)((uint8_t *)(node) - (size_t)(&((type *)0)->member)))
36 
37 /**
38  * Double linked list initialization: a single Node forms a ring
39  *
40  * @param[in]  list_head    the list_head node to be initialized.
41  *
42  * @return  none
43  */
klist_init(klist_t * list_head)44 RHINO_INLINE void klist_init(klist_t *list_head)
45 {
46     list_head->next = list_head;
47     list_head->prev = list_head;
48 }
49 
50 /**
51  * Judge whether 'klist' is empty.
52  *
53  * @param[in]  list    the list node.
54  *
55  * @return 1 on empty, 0 FALSE.
56  */
is_klist_empty(klist_t * list)57 RHINO_INLINE uint8_t is_klist_empty(klist_t *list)
58 {
59     return (list->next == list);
60 }
61 
62 /**
63  * Double linked list insertion: 'element' before 'head'
64  * When 'head' is the head of the linked list, insert 'element' in the list end
65  *
66  * @param[in]  head       the specified head node.
67  * @param[in]  element    the data node to be inserted.
68  *
69  * @return  none
70  */
klist_insert(klist_t * head,klist_t * element)71 RHINO_INLINE void klist_insert(klist_t *head, klist_t *element)
72 {
73     element->prev = head->prev;
74     element->next = head;
75 
76     head->prev->next = element;
77     head->prev       = element;
78 }
79 
80 /**
81  * Double linked list insertion: 'element' after 'head'
82  * When 'head' is the head of the linked list, insert 'element' in the list front
83  *
84  * @param[in]  head       the specified head node.
85  * @param[in]  element    the data node to be inserted.
86  */
klist_add(klist_t * head,klist_t * element)87 RHINO_INLINE void klist_add(klist_t *head, klist_t *element)
88 {
89     element->prev = head;
90     element->next = head->next;
91 
92     head->next->prev = element;
93     head->next = element;
94 }
95 
96 /**
97  * Double linked list deletion: 'element' is deleted from the linked list
98  *
99  * @param[in]  element    the list node to be deleted.
100  */
klist_rm(klist_t * element)101 RHINO_INLINE void klist_rm(klist_t *element)
102 {
103     element->prev->next = element->next;
104     element->next->prev = element->prev;
105 }
106 
107 /**
108  * Double linked list deletion: 'element' is deleted from the linked list and 'element' is initialized
109  *
110  * @param[in]  element    the list node to be deleted and reinited.
111  */
klist_rm_init(klist_t * element)112 RHINO_INLINE void klist_rm_init(klist_t *element)
113 {
114     element->prev->next = element->next;
115     element->next->prev = element->prev;
116 
117     element->next = element->prev = element;
118 }
119 
120 /** @} */
121 
122 #ifdef __cplusplus
123 }
124 #endif
125 
126 #endif /* K_LIST_H */
127 
128