1 /**
2  ****************************************************************************************
3  *
4  * @file co_list.h
5  *
6  * @brief Common list structures definitions
7  *
8  * Copyright (C) RivieraWaves 2009-2015
9  *
10  *
11  ****************************************************************************************
12  */
13 
14 #ifndef _CO_LIST_H_
15 #define _CO_LIST_H_
16 
17 /**
18  *****************************************************************************************
19  * @defgroup CO_LIST List management
20  * @ingroup COMMON
21  *
22  * @brief  List management.
23  *
24  * This module contains the list structures and handling functions.
25  * @{
26  *****************************************************************************************
27  */
28 
29 /*
30  * INCLUDE FILES
31  ****************************************************************************************
32  */
33 #include <stdint.h>         // standard definition
34 #include <stdbool.h>        // boolean definition
35 #include <stddef.h>         // for NULL and size_t
36 #include "rwip_config.h"    // stack configuration
37 #include "ble_arch.h"
38 //#include "core_cm0.h"        // for __INLINE
39 
40 
41 /*
42  * DEFINES
43  ****************************************************************************************
44  */
45 ///list type
46 enum
47 {
48     POOL_LINKED_LIST    = 0x00,
49     RING_LINKED_LIST,
50     LINK_TYPE_END
51 };
52 
53 /// structure of a list element header
54 struct co_list_hdr
55 {
56     /// Pointer to next co_list_hdr
57     struct co_list_hdr *next;
58 };
59 
60 /// structure of a list
61 struct co_list
62 {
63     /// pointer to first element of the list
64     struct co_list_hdr *first;
65     /// pointer to the last element
66     struct co_list_hdr *last;
67 
68     #if (KE_PROFILING)
69     /// number of element in the list
70     uint32_t cnt;
71     /// max number of element in the list
72     uint32_t maxcnt;
73     /// min number of element in the list
74     uint32_t mincnt;
75     #endif //KE_PROFILING
76 };
77 
78 
79 /*
80  * FUNCTION DECLARATIONS
81  ****************************************************************************************
82  */
83 /**
84  ****************************************************************************************
85  * @brief Initialize a list to defaults values.
86  *
87  * @param list           Pointer to the list structure.
88  ****************************************************************************************
89  */
90 void co_list_init(struct co_list *list);
91 
92 /**
93  ****************************************************************************************
94  * @brief Initialize a pool to default values, and initialize the relative free list.
95  *
96  * @param list           Pointer to the list structure
97  * @param pool           Pointer to the pool to be initialized
98  * @param elmt_size      Size of one element of the pool
99  * @param elmt_cnt       Nb of elements available in the pool
100  * @param default_value  Pointer to the default value of each element (may be NULL)
101  * @param list_type      Determine if the it is a ring list or not
102  *
103  ****************************************************************************************
104  */
105 void co_list_pool_init(struct co_list *list,
106                        void *pool,
107                        size_t elmt_size,
108                        uint32_t elmt_cnt,
109                        void *default_value,
110                        uint8_t list_type);
111 
112 /**
113  ****************************************************************************************
114  * @brief Add an element as last on the list.
115  *
116  * @param list           Pointer to the list structure
117  * @param list_hdr       Pointer to the header to add at the end of the list
118  *
119  ****************************************************************************************
120  */
121 void co_list_push_back(struct co_list *list, struct co_list_hdr *list_hdr);
122 
123 /**
124  ****************************************************************************************
125  * @brief Add an element as first on the list.
126  *
127  * @param list           Pointer to the list structure
128  * @param list_hdr       Pointer to the header to add at the beginning of the list
129  ****************************************************************************************
130  */
131 void co_list_push_front(struct co_list *list, struct co_list_hdr *list_hdr);
132 
133 /**
134  ****************************************************************************************
135  * @brief Extract the first element of the list.
136  * @param list           Pointer to the list structure
137  * @return The pointer to the element extracted, and NULL if the list is empty.
138  ****************************************************************************************
139  */
140 struct co_list_hdr *co_list_pop_front(struct co_list *list);
141 
142 /**
143  ****************************************************************************************
144  * @brief Search for a given element in the list, and extract it if found.
145  *
146  * @param list           Pointer to the list structure
147  * @param list_hdr       Element to extract
148  * @param nb_following   Number of following elements to extract
149  *
150  * @return true if the element is found in the list, false otherwise
151  ****************************************************************************************
152  */
153 bool co_list_extract(struct co_list *list, struct co_list_hdr *list_hdr, uint8_t nb_following);
154 
155 /**
156  ****************************************************************************************
157  * @brief Extract an element when the previous element is known
158  *
159  * Note: the element to remove shall follow immediately the reference within the list
160  *
161  * @param list           Pointer to the list structure
162  * @param elt_ref_hdr    Pointer to the referenced element (NULL if element to extract is the first in the list)
163  * @param elt_to_rem_hdr Pointer to the element to be extracted
164  ****************************************************************************************
165  */
166 void co_list_extract_after(struct co_list *list, struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_rem_hdr);
167 
168 /**
169  ****************************************************************************************
170  * @brief Searched a given element in the list.
171  *
172  * @param list           Pointer to the list structure
173  * @param list_hdr       Pointer to the searched element
174  *
175  * @return true if the element is found in the list, false otherwise
176  ****************************************************************************************
177  */
178 bool co_list_find(struct co_list *list, struct co_list_hdr *list_hdr);
179 
180 /**
181  ****************************************************************************************
182  * @brief Merge two lists in a single one.
183  *
184  * This function appends the list pointed by list2 to the list pointed by list1. Once the
185  * merge is done, it empties list2.
186  *
187  * @param list1    Pointer to the destination list
188  * @param list2    Pointer to the list to append to list1
189  ****************************************************************************************
190  */
191 void co_list_merge(struct co_list *list1, struct co_list *list2);
192 
193 /**
194  ****************************************************************************************
195  * @brief Insert a given element in the list before the referenced element.
196  *
197  * @param list           Pointer to the list structure
198  * @param elt_ref_hdr    Pointer to the referenced element
199  * @param elt_to_add_hdr Pointer to the element to be inserted
200  *
201  * @return true if the element is found in the list, false otherwise
202  ****************************************************************************************
203  */
204 void co_list_insert_before(struct co_list *list,
205                         struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr);
206 
207 /**
208  ****************************************************************************************
209  * @brief Insert a given element in the list after the referenced element.
210  *
211  * @param list           Pointer to the list structure
212  * @param elt_ref_hdr    Pointer to the referenced element
213  * @param elt_to_add_hdr Pointer to the element to be inserted
214  *
215  * @return true if the element is found in the list, false otherwise
216  ****************************************************************************************
217  */
218 void co_list_insert_after(struct co_list *list,
219                         struct co_list_hdr *elt_ref_hdr, struct co_list_hdr *elt_to_add_hdr);
220 
221 
222 /**
223  ****************************************************************************************
224  * @brief Count number of elements present in the list
225  *
226  * @param list           Pointer to the list structure
227  *
228  * @return Number of elements present in the list
229  ****************************************************************************************
230  */
231 uint16_t co_list_size(struct co_list *list);
232 
233 /**
234  ****************************************************************************************
235  * @brief Check if there is enough element available in the list
236  *
237  * @param list           Pointer to the list structure
238  * @param nb_elt_needed  Number of element needed
239  *
240  * @return True if enough element are available in the list
241  ****************************************************************************************
242  */
243 bool co_list_check_size_available(struct co_list *list, uint8_t nb_elt_needed);
244 
245 /**
246  ****************************************************************************************
247  * @brief Test if the list is empty.
248  * @param list           Pointer to the list structure.
249  * @return true if the list is empty, false else otherwise.
250  ****************************************************************************************
251  */
252 
co_list_is_empty(const struct co_list * const list)253 __INLINE bool co_list_is_empty(const struct co_list *const list)
254 {
255     bool listempty;
256     listempty = (list->first == NULL);
257     return (listempty);
258 }
259 
260 /**
261  ****************************************************************************************
262  * @brief Pick the first element from the list without removing it.
263  *
264  * @param list           Pointer to the list structure.
265  *
266  * @return First element address. Returns NULL pointer if the list is empty.
267  ****************************************************************************************
268  */
co_list_pick(const struct co_list * const list)269 __INLINE struct co_list_hdr *co_list_pick(const struct co_list *const list)
270 {
271     return(list->first);
272 }
273 
274 
275 /**
276  ****************************************************************************************
277  * @brief Return following element of a list element.
278  *
279  * @param list_hdr     Pointer to the list element.
280  *
281  * @return The pointer to the next element.
282  ****************************************************************************************
283  */
co_list_next(const struct co_list_hdr * const list_hdr)284 __INLINE struct co_list_hdr *co_list_next(const struct co_list_hdr *const list_hdr)
285 {
286     return(list_hdr->next);
287 }
288 
289 /// @} CO_LIST
290 #endif // _CO_LIST_H_
291