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