xref: /nrf52832-nimble/rt-thread/include/rtservice.h (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero  *
4*10465441SEvalZero  * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero  *
6*10465441SEvalZero  * Change Logs:
7*10465441SEvalZero  * Date           Author       Notes
8*10465441SEvalZero  * 2006-03-16     Bernard      the first version
9*10465441SEvalZero  * 2006-09-07     Bernard      move the kservice APIs to rtthread.h
10*10465441SEvalZero  * 2007-06-27     Bernard      fix the rt_list_remove bug
11*10465441SEvalZero  * 2012-03-22     Bernard      rename kservice.h to rtservice.h
12*10465441SEvalZero  * 2017-11-15     JasonJia     Modify rt_slist_foreach to rt_slist_for_each_entry.
13*10465441SEvalZero  *                             Make code cleanup.
14*10465441SEvalZero  */
15*10465441SEvalZero 
16*10465441SEvalZero #ifndef __RT_SERVICE_H__
17*10465441SEvalZero #define __RT_SERVICE_H__
18*10465441SEvalZero 
19*10465441SEvalZero #ifdef __cplusplus
20*10465441SEvalZero extern "C" {
21*10465441SEvalZero #endif
22*10465441SEvalZero 
23*10465441SEvalZero /**
24*10465441SEvalZero  * @addtogroup KernelService
25*10465441SEvalZero  */
26*10465441SEvalZero 
27*10465441SEvalZero /**@{*/
28*10465441SEvalZero 
29*10465441SEvalZero /**
30*10465441SEvalZero  * rt_container_of - return the member address of ptr, if the type of ptr is the
31*10465441SEvalZero  * struct type.
32*10465441SEvalZero  */
33*10465441SEvalZero #define rt_container_of(ptr, type, member) \
34*10465441SEvalZero     ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
35*10465441SEvalZero 
36*10465441SEvalZero 
37*10465441SEvalZero /**
38*10465441SEvalZero  * @brief initialize a list object
39*10465441SEvalZero  */
40*10465441SEvalZero #define RT_LIST_OBJECT_INIT(object) { &(object), &(object) }
41*10465441SEvalZero 
42*10465441SEvalZero /**
43*10465441SEvalZero  * @brief initialize a list
44*10465441SEvalZero  *
45*10465441SEvalZero  * @param l list to be initialized
46*10465441SEvalZero  */
rt_list_init(rt_list_t * l)47*10465441SEvalZero rt_inline void rt_list_init(rt_list_t *l)
48*10465441SEvalZero {
49*10465441SEvalZero     l->next = l->prev = l;
50*10465441SEvalZero }
51*10465441SEvalZero 
52*10465441SEvalZero /**
53*10465441SEvalZero  * @brief insert a node after a list
54*10465441SEvalZero  *
55*10465441SEvalZero  * @param l list to insert it
56*10465441SEvalZero  * @param n new node to be inserted
57*10465441SEvalZero  */
rt_list_insert_after(rt_list_t * l,rt_list_t * n)58*10465441SEvalZero rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
59*10465441SEvalZero {
60*10465441SEvalZero     l->next->prev = n;
61*10465441SEvalZero     n->next = l->next;
62*10465441SEvalZero 
63*10465441SEvalZero     l->next = n;
64*10465441SEvalZero     n->prev = l;
65*10465441SEvalZero }
66*10465441SEvalZero 
67*10465441SEvalZero /**
68*10465441SEvalZero  * @brief insert a node before a list
69*10465441SEvalZero  *
70*10465441SEvalZero  * @param n new node to be inserted
71*10465441SEvalZero  * @param l list to insert it
72*10465441SEvalZero  */
rt_list_insert_before(rt_list_t * l,rt_list_t * n)73*10465441SEvalZero rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
74*10465441SEvalZero {
75*10465441SEvalZero     l->prev->next = n;
76*10465441SEvalZero     n->prev = l->prev;
77*10465441SEvalZero 
78*10465441SEvalZero     l->prev = n;
79*10465441SEvalZero     n->next = l;
80*10465441SEvalZero }
81*10465441SEvalZero 
82*10465441SEvalZero /**
83*10465441SEvalZero  * @brief remove node from list.
84*10465441SEvalZero  * @param n the node to remove from the list.
85*10465441SEvalZero  */
rt_list_remove(rt_list_t * n)86*10465441SEvalZero rt_inline void rt_list_remove(rt_list_t *n)
87*10465441SEvalZero {
88*10465441SEvalZero     n->next->prev = n->prev;
89*10465441SEvalZero     n->prev->next = n->next;
90*10465441SEvalZero 
91*10465441SEvalZero     n->next = n->prev = n;
92*10465441SEvalZero }
93*10465441SEvalZero 
94*10465441SEvalZero /**
95*10465441SEvalZero  * @brief tests whether a list is empty
96*10465441SEvalZero  * @param l the list to test.
97*10465441SEvalZero  */
rt_list_isempty(const rt_list_t * l)98*10465441SEvalZero rt_inline int rt_list_isempty(const rt_list_t *l)
99*10465441SEvalZero {
100*10465441SEvalZero     return l->next == l;
101*10465441SEvalZero }
102*10465441SEvalZero 
103*10465441SEvalZero /**
104*10465441SEvalZero  * @brief get the list length
105*10465441SEvalZero  * @param l the list to get.
106*10465441SEvalZero  */
rt_list_len(const rt_list_t * l)107*10465441SEvalZero rt_inline unsigned int rt_list_len(const rt_list_t *l)
108*10465441SEvalZero {
109*10465441SEvalZero     unsigned int len = 0;
110*10465441SEvalZero     const rt_list_t *p = l;
111*10465441SEvalZero     while (p->next != l)
112*10465441SEvalZero     {
113*10465441SEvalZero         p = p->next;
114*10465441SEvalZero         len ++;
115*10465441SEvalZero     }
116*10465441SEvalZero 
117*10465441SEvalZero     return len;
118*10465441SEvalZero }
119*10465441SEvalZero 
120*10465441SEvalZero /**
121*10465441SEvalZero  * @brief get the struct for this entry
122*10465441SEvalZero  * @param node the entry point
123*10465441SEvalZero  * @param type the type of structure
124*10465441SEvalZero  * @param member the name of list in structure
125*10465441SEvalZero  */
126*10465441SEvalZero #define rt_list_entry(node, type, member) \
127*10465441SEvalZero     rt_container_of(node, type, member)
128*10465441SEvalZero 
129*10465441SEvalZero /**
130*10465441SEvalZero  * rt_list_for_each - iterate over a list
131*10465441SEvalZero  * @pos:	the rt_list_t * to use as a loop cursor.
132*10465441SEvalZero  * @head:	the head for your list.
133*10465441SEvalZero  */
134*10465441SEvalZero #define rt_list_for_each(pos, head) \
135*10465441SEvalZero     for (pos = (head)->next; pos != (head); pos = pos->next)
136*10465441SEvalZero 
137*10465441SEvalZero /**
138*10465441SEvalZero  * rt_list_for_each_safe - iterate over a list safe against removal of list entry
139*10465441SEvalZero  * @pos:	the rt_list_t * to use as a loop cursor.
140*10465441SEvalZero  * @n:		another rt_list_t * to use as temporary storage
141*10465441SEvalZero  * @head:	the head for your list.
142*10465441SEvalZero  */
143*10465441SEvalZero #define rt_list_for_each_safe(pos, n, head) \
144*10465441SEvalZero 	for (pos = (head)->next, n = pos->next; pos != (head); \
145*10465441SEvalZero 		pos = n, n = pos->next)
146*10465441SEvalZero 
147*10465441SEvalZero /**
148*10465441SEvalZero  * rt_list_for_each_entry  -   iterate over list of given type
149*10465441SEvalZero  * @pos:    the type * to use as a loop cursor.
150*10465441SEvalZero  * @head:   the head for your list.
151*10465441SEvalZero  * @member: the name of the list_struct within the struct.
152*10465441SEvalZero  */
153*10465441SEvalZero #define rt_list_for_each_entry(pos, head, member) \
154*10465441SEvalZero     for (pos = rt_list_entry((head)->next, typeof(*pos), member); \
155*10465441SEvalZero          &pos->member != (head); \
156*10465441SEvalZero          pos = rt_list_entry(pos->member.next, typeof(*pos), member))
157*10465441SEvalZero 
158*10465441SEvalZero /**
159*10465441SEvalZero  * rt_list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
160*10465441SEvalZero  * @pos:    the type * to use as a loop cursor.
161*10465441SEvalZero  * @n:      another type * to use as temporary storage
162*10465441SEvalZero  * @head:   the head for your list.
163*10465441SEvalZero  * @member: the name of the list_struct within the struct.
164*10465441SEvalZero  */
165*10465441SEvalZero #define rt_list_for_each_entry_safe(pos, n, head, member) \
166*10465441SEvalZero     for (pos = rt_list_entry((head)->next, typeof(*pos), member), \
167*10465441SEvalZero          n = rt_list_entry(pos->member.next, typeof(*pos), member); \
168*10465441SEvalZero          &pos->member != (head); \
169*10465441SEvalZero          pos = n, n = rt_list_entry(n->member.next, typeof(*n), member))
170*10465441SEvalZero 
171*10465441SEvalZero /**
172*10465441SEvalZero  * rt_list_first_entry - get the first element from a list
173*10465441SEvalZero  * @ptr:    the list head to take the element from.
174*10465441SEvalZero  * @type:   the type of the struct this is embedded in.
175*10465441SEvalZero  * @member: the name of the list_struct within the struct.
176*10465441SEvalZero  *
177*10465441SEvalZero  * Note, that list is expected to be not empty.
178*10465441SEvalZero  */
179*10465441SEvalZero #define rt_list_first_entry(ptr, type, member) \
180*10465441SEvalZero     rt_list_entry((ptr)->next, type, member)
181*10465441SEvalZero 
182*10465441SEvalZero #define RT_SLIST_OBJECT_INIT(object) { RT_NULL }
183*10465441SEvalZero 
184*10465441SEvalZero /**
185*10465441SEvalZero  * @brief initialize a single list
186*10465441SEvalZero  *
187*10465441SEvalZero  * @param l the single list to be initialized
188*10465441SEvalZero  */
rt_slist_init(rt_slist_t * l)189*10465441SEvalZero rt_inline void rt_slist_init(rt_slist_t *l)
190*10465441SEvalZero {
191*10465441SEvalZero     l->next = RT_NULL;
192*10465441SEvalZero }
193*10465441SEvalZero 
rt_slist_append(rt_slist_t * l,rt_slist_t * n)194*10465441SEvalZero rt_inline void rt_slist_append(rt_slist_t *l, rt_slist_t *n)
195*10465441SEvalZero {
196*10465441SEvalZero     struct rt_slist_node *node;
197*10465441SEvalZero 
198*10465441SEvalZero     node = l;
199*10465441SEvalZero     while (node->next) node = node->next;
200*10465441SEvalZero 
201*10465441SEvalZero     /* append the node to the tail */
202*10465441SEvalZero     node->next = n;
203*10465441SEvalZero     n->next = RT_NULL;
204*10465441SEvalZero }
205*10465441SEvalZero 
rt_slist_insert(rt_slist_t * l,rt_slist_t * n)206*10465441SEvalZero rt_inline void rt_slist_insert(rt_slist_t *l, rt_slist_t *n)
207*10465441SEvalZero {
208*10465441SEvalZero     n->next = l->next;
209*10465441SEvalZero     l->next = n;
210*10465441SEvalZero }
211*10465441SEvalZero 
rt_slist_len(const rt_slist_t * l)212*10465441SEvalZero rt_inline unsigned int rt_slist_len(const rt_slist_t *l)
213*10465441SEvalZero {
214*10465441SEvalZero     unsigned int len = 0;
215*10465441SEvalZero     const rt_slist_t *list = l->next;
216*10465441SEvalZero     while (list != RT_NULL)
217*10465441SEvalZero     {
218*10465441SEvalZero         list = list->next;
219*10465441SEvalZero         len ++;
220*10465441SEvalZero     }
221*10465441SEvalZero 
222*10465441SEvalZero     return len;
223*10465441SEvalZero }
224*10465441SEvalZero 
rt_slist_remove(rt_slist_t * l,rt_slist_t * n)225*10465441SEvalZero rt_inline rt_slist_t *rt_slist_remove(rt_slist_t *l, rt_slist_t *n)
226*10465441SEvalZero {
227*10465441SEvalZero     /* remove slist head */
228*10465441SEvalZero     struct rt_slist_node *node = l;
229*10465441SEvalZero     while (node->next && node->next != n) node = node->next;
230*10465441SEvalZero 
231*10465441SEvalZero     /* remove node */
232*10465441SEvalZero     if (node->next != (rt_slist_t *)0) node->next = node->next->next;
233*10465441SEvalZero 
234*10465441SEvalZero     return l;
235*10465441SEvalZero }
236*10465441SEvalZero 
rt_slist_first(rt_slist_t * l)237*10465441SEvalZero rt_inline rt_slist_t *rt_slist_first(rt_slist_t *l)
238*10465441SEvalZero {
239*10465441SEvalZero     return l->next;
240*10465441SEvalZero }
241*10465441SEvalZero 
rt_slist_tail(rt_slist_t * l)242*10465441SEvalZero rt_inline rt_slist_t *rt_slist_tail(rt_slist_t *l)
243*10465441SEvalZero {
244*10465441SEvalZero     while (l->next) l = l->next;
245*10465441SEvalZero 
246*10465441SEvalZero     return l;
247*10465441SEvalZero }
248*10465441SEvalZero 
rt_slist_next(rt_slist_t * n)249*10465441SEvalZero rt_inline rt_slist_t *rt_slist_next(rt_slist_t *n)
250*10465441SEvalZero {
251*10465441SEvalZero     return n->next;
252*10465441SEvalZero }
253*10465441SEvalZero 
rt_slist_isempty(rt_slist_t * l)254*10465441SEvalZero rt_inline int rt_slist_isempty(rt_slist_t *l)
255*10465441SEvalZero {
256*10465441SEvalZero     return l->next == RT_NULL;
257*10465441SEvalZero }
258*10465441SEvalZero 
259*10465441SEvalZero /**
260*10465441SEvalZero  * @brief get the struct for this single list node
261*10465441SEvalZero  * @param node the entry point
262*10465441SEvalZero  * @param type the type of structure
263*10465441SEvalZero  * @param member the name of list in structure
264*10465441SEvalZero  */
265*10465441SEvalZero #define rt_slist_entry(node, type, member) \
266*10465441SEvalZero     rt_container_of(node, type, member)
267*10465441SEvalZero 
268*10465441SEvalZero /**
269*10465441SEvalZero  * rt_slist_for_each - iterate over a single list
270*10465441SEvalZero  * @pos:    the rt_slist_t * to use as a loop cursor.
271*10465441SEvalZero  * @head:   the head for your single list.
272*10465441SEvalZero  */
273*10465441SEvalZero #define rt_slist_for_each(pos, head) \
274*10465441SEvalZero     for (pos = (head)->next; pos != RT_NULL; pos = pos->next)
275*10465441SEvalZero 
276*10465441SEvalZero /**
277*10465441SEvalZero  * rt_slist_for_each_entry  -   iterate over single list of given type
278*10465441SEvalZero  * @pos:    the type * to use as a loop cursor.
279*10465441SEvalZero  * @head:   the head for your single list.
280*10465441SEvalZero  * @member: the name of the list_struct within the struct.
281*10465441SEvalZero  */
282*10465441SEvalZero #define rt_slist_for_each_entry(pos, head, member) \
283*10465441SEvalZero     for (pos = rt_slist_entry((head)->next, typeof(*pos), member); \
284*10465441SEvalZero          &pos->member != (RT_NULL); \
285*10465441SEvalZero          pos = rt_slist_entry(pos->member.next, typeof(*pos), member))
286*10465441SEvalZero 
287*10465441SEvalZero /**
288*10465441SEvalZero  * rt_slist_first_entry - get the first element from a slist
289*10465441SEvalZero  * @ptr:    the slist head to take the element from.
290*10465441SEvalZero  * @type:   the type of the struct this is embedded in.
291*10465441SEvalZero  * @member: the name of the slist_struct within the struct.
292*10465441SEvalZero  *
293*10465441SEvalZero  * Note, that slist is expected to be not empty.
294*10465441SEvalZero  */
295*10465441SEvalZero #define rt_slist_first_entry(ptr, type, member) \
296*10465441SEvalZero     rt_slist_entry((ptr)->next, type, member)
297*10465441SEvalZero 
298*10465441SEvalZero /**
299*10465441SEvalZero  * rt_slist_tail_entry - get the tail element from a slist
300*10465441SEvalZero  * @ptr:    the slist head to take the element from.
301*10465441SEvalZero  * @type:   the type of the struct this is embedded in.
302*10465441SEvalZero  * @member: the name of the slist_struct within the struct.
303*10465441SEvalZero  *
304*10465441SEvalZero  * Note, that slist is expected to be not empty.
305*10465441SEvalZero  */
306*10465441SEvalZero #define rt_slist_tail_entry(ptr, type, member) \
307*10465441SEvalZero     rt_slist_entry(rt_slist_tail(ptr), type, member)
308*10465441SEvalZero 
309*10465441SEvalZero /**@}*/
310*10465441SEvalZero 
311*10465441SEvalZero #ifdef __cplusplus
312*10465441SEvalZero }
313*10465441SEvalZero #endif
314*10465441SEvalZero 
315*10465441SEvalZero #endif
316