Mic_chen

It is not the strongest of the species that survive, nor the most intelligent, but the one most responsive to change

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

如下代码是linux上的链表接口源码,使用的这个链表(list)源码,可以方便快捷的建立链表队列,但使用时需要注意的坑有:
 1、不支持,多对多,否则在add的时候,因为要加入链表的对象只有一块list_head内存,如果将它多次添加到其他链表,那么只有最后一个有效,前面的均无效。
 2、如果链表节点的内存是动态申请的,在遍历链表的循环中,取得链表数据后要释放节点资源,必须使用list_for_each_entry_safe,不能使用list_for_each_entry
    否则将有访问异常风险,原因是:_safe才会将下一个节点先保存起来,当取得链表数据,释放完节点资源后,才能保证能查找到该节点后面的节点。

 

  1 #ifndef _LINUX_LIST_H_
  2 #define _LINUX_LIST_H_ 
  3 
  4 #ifdef __cplusplus
  5 extern "C" {
  6 #endif
  7 
  8 #include <stdbool.h>
  9 
 10 #define offset_of(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 
 11 
 12 #define container_of(ptr, type, member) ({\
 13     const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
 14     (type *)( (char *)__mptr - offset_of(type,member) ); })
 15 
 16 #define LIST_POISON1  ((void *) 0x00100100) 
 17 #define LIST_POISON2  ((void *) 0x00200200) 
 18 
 19 struct list_head {
 20     struct list_head *next, *prev; 
 21 }; 
 22 
 23 #define LIST_HEAD_INIT(name) { &(name), &(name) } 
 24 
 25 #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) 
 26 
 27 static inline void INIT_LIST_HEAD(struct list_head *list)
 28 {    
 29     list->next = list;    
 30     list->prev = list;
 31 }
 32 
 33 /* 
 34  * Insert a new entry between two known consecutive entries. 
 35  * 
 36  * This is only for internal list manipulation where we know 
 37  * the prev/next entries already! 
 38  */ 
 39 static inline void __list_add(struct list_head *new_entry, 
 40        struct list_head *prev, 
 41        struct list_head *next) 
 42 { 
 43     next->prev = new_entry; 
 44     new_entry->next = next; 
 45     new_entry->prev = prev; 
 46     prev->next = new_entry;
 47 } 
 48 
 49 /** 
 50  * list_add - add a new entry 
 51  * @new_entry: new entry to be added 
 52  * @head: list head to add it after 
 53  * 
 54  * Insert a new entry after the specified head. 
 55  * This is good for implementing stacks. 
 56  */ 
 57 static inline void list_add(struct list_head *new_entry, struct list_head *head) 
 58 { 
 59     __list_add(new_entry, head, head->next); 
 60 } 
 61 
 62 /** 
 63  * list_add_tail - add a new entry 
 64  * @new_entry: new entry to be added 
 65  * @head: list head to add it before 
 66  * 
 67  * Insert a new entry before the specified head. 
 68  * This is useful for implementing queues. 
 69  */ 
 70 static inline void list_add_tail(struct list_head *new_entry, struct list_head *head) 
 71 { 
 72     __list_add(new_entry, head->prev, head); 
 73 } 
 74 
 75 /*
 76  * Delete a list entry by making the prev/next entries
 77  * point to each other.
 78  *
 79  * This is only for internal list manipulation where we know
 80  * the prev/next entries already!
 81  */
 82 static inline void __list_del(struct list_head * prev, struct list_head * next) 
 83 { 
 84     next->prev = prev; 
 85     prev->next = next; 
 86 } 
 87 
 88 static inline void __list_del_entry(struct list_head *entry)
 89 {
 90     __list_del(entry->prev, entry->next);
 91 }
 92 
 93 /**
 94  * list_del - deletes entry from list.
 95  * @entry: the element to delete from the list.
 96  * Note: list_empty() on entry does not return true after this, the entry is
 97  * in an undefined state.
 98  */
 99 static inline void list_del(struct list_head *entry) 
100 { 
101     __list_del(entry->prev, entry->next); 
102     entry->next = (struct list_head *)LIST_POISON1; 
103     entry->prev = (struct list_head *)LIST_POISON2; 
104 }
105 
106 /**
107  * list_replace - replace old entry by new one
108  * @old : the element to be replaced
109  * @new_entry : the new element to insert
110  *
111  * If @old was empty, it will be overwritten.
112  */
113 static inline void list_replace(struct list_head *old,
114                 struct list_head *new_entry)
115 {
116     new_entry->next = old->next;
117     new_entry->next->prev = new_entry;
118     new_entry->prev = old->prev;
119     new_entry->prev->next = new_entry;
120 }
121 
122 static inline void list_replace_init(struct list_head *old,
123                     struct list_head *new_entry)
124 {
125     list_replace(old, new_entry);
126     INIT_LIST_HEAD(old);
127 }
128 
129 /**
130  * list_del_init - deletes entry from list and reinitialize it.
131  * @entry: the element to delete from the list.
132  */
133 static inline void list_del_init(struct list_head *entry)
134 {
135     __list_del_entry(entry);
136     INIT_LIST_HEAD(entry);
137 }
138 
139 /**
140  * list_move - delete from one list and add as another's head
141  * @list: the entry to move
142  * @head: the head that will precede our entry
143  */
144 static inline void list_move(struct list_head *list, struct list_head *head)
145 {
146     __list_del_entry(list);
147     list_add(list, head);
148 }
149 
150 /**
151  * list_move_tail - delete from one list and add as another's tail
152  * @list: the entry to move
153  * @head: the head that will follow our entry
154  */
155 static inline void list_move_tail(struct list_head *list,
156                   struct list_head *head)
157 {
158     __list_del_entry(list);
159     list_add_tail(list, head);
160 }
161 
162 /**
163  * list_is_last - tests whether @list is the last entry in list @head
164  * @list: the entry to test
165  * @head: the head of the list
166  */
167 static inline int list_is_last(const struct list_head *list,
168                 const struct list_head *head)
169 {
170     return list->next == head;
171 }
172 
173 /**
174  * list_empty - tests whether a list is empty
175  * @head: the list to test.
176  */
177 static inline int list_empty(const struct list_head *head) 
178 { 
179     return head->next == head; 
180 } 
181 
182 /**
183  * list_empty_careful - tests whether a list is empty and not being modified
184  * @head: the list to test
185  *
186  * Description:
187  * tests whether a list is empty _and_ checks that no other CPU might be
188  * in the process of modifying either member (next or prev)
189  *
190  * NOTE: using list_empty_careful() without synchronization
191  * can only be safe if the only activity that can happen
192  * to the list entry is list_del_init(). Eg. it cannot be used
193  * if another CPU could re-list_add() it.
194  */
195 static inline int list_empty_careful(const struct list_head *head)
196 {
197     struct list_head *next = head->next;
198     return (next == head) && (next == head->prev);
199 }
200 
201 /**
202  * list_rotate_left - rotate the list to the left
203  * @head: the head of the list
204  */
205 static inline void list_rotate_left(struct list_head *head)
206 {
207     struct list_head *first;
208 
209     if (!list_empty(head)) {
210         first = head->next;
211         list_move_tail(first, head);
212     }
213 }
214 
215 /**
216  * list_is_singular - tests whether a list has just one entry.
217  * @head: the list to test.
218  */
219 static inline int list_is_singular(const struct list_head *head)
220 {
221     return !list_empty(head) && (head->next == head->prev);
222 }
223 
224 static inline void __list_cut_position(struct list_head *list,
225         struct list_head *head, struct list_head *entry)
226 {
227     struct list_head *new_first = entry->next;
228     list->next = head->next;
229     list->next->prev = list;
230     list->prev = entry;
231     entry->next = list;
232     head->next = new_first;
233     new_first->prev = head;
234 }
235 
236 /**
237  * list_cut_position - cut a list into two
238  * @list: a new list to add all removed entries
239  * @head: a list with entries
240  * @entry: an entry within head, could be the head itself
241  *    and if so we won't cut the list
242  *
243  * This helper moves the initial part of @head, up to and
244  * including @entry, from @head to @list. You should
245  * pass on @entry an element you know is on @head. @list
246  * should be an empty list or a list you do not care about
247  * losing its data.
248  *
249  */
250 static inline void list_cut_position(struct list_head *list,
251         struct list_head *head, struct list_head *entry)
252 {
253     if (list_empty(head))
254         return;
255     if (list_is_singular(head) &&
256         (head->next != entry && head != entry))
257         return;
258     if (entry == head)
259         INIT_LIST_HEAD(list);
260     else
261         __list_cut_position(list, head, entry);
262 }
263 
264 static inline void __list_splice(const struct list_head *list,
265                  struct list_head *prev,
266                  struct list_head *next)
267 {
268     struct list_head *first = list->next;
269     struct list_head *last = list->prev;
270 
271     first->prev = prev;
272     prev->next = first;
273 
274     last->next = next;
275     next->prev = last;
276 }
277 
278 /**
279  * list_splice - join two lists, this is designed for stacks
280  * @list: the new list to add.
281  * @head: the place to add it in the first list.
282  */
283 static inline void list_splice(const struct list_head *list,
284                 struct list_head *head)
285 {
286     if (!list_empty(list))
287         __list_splice(list, head, head->next);
288 }
289 
290 /**
291  * list_splice_tail - join two lists, each list being a queue
292  * @list: the new list to add.
293  * @head: the place to add it in the first list.
294  */
295 static inline void list_splice_tail(struct list_head *list,
296                 struct list_head *head)
297 {
298     if (!list_empty(list))
299         __list_splice(list, head->prev, head);
300 }
301 
302 /**
303  * list_splice_init - join two lists and reinitialise the emptied list.
304  * @list: the new list to add.
305  * @head: the place to add it in the first list.
306  *
307  * The list at @list is reinitialised
308  */
309 static inline void list_splice_init(struct list_head *list,
310                     struct list_head *head)
311 {
312     if (!list_empty(list)) {
313         __list_splice(list, head, head->next);
314         INIT_LIST_HEAD(list);
315     }
316 }
317 
318 /**
319  * list_splice_tail_init - join two lists and reinitialise the emptied list
320  * @list: the new list to add.
321  * @head: the place to add it in the first list.
322  *
323  * Each of the lists is a queue.
324  * The list at @list is reinitialised
325  */
326 static inline void list_splice_tail_init(struct list_head *list,
327                      struct list_head *head)
328 {
329     if (!list_empty(list)) {
330         __list_splice(list, head->prev, head);
331         INIT_LIST_HEAD(list);
332     }
333 }
334 
335 /**
336  * list_entry - get the struct for this entry
337  * @ptr:    the &struct list_head pointer.
338  * @type:    the type of the struct this is embedded in.
339  * @member:    the name of the list_head within the struct.
340  */
341 #define list_entry(ptr, type, member) \
342     container_of(ptr, type, member) 
343 
344 /**
345  * list_first_entry - get the first element from a list
346  * @ptr:    the list head to take the element from.
347  * @type:    the type of the struct this is embedded in.
348  * @member:    the name of the list_head within the struct.
349  *
350  * Note, that list is expected to be not empty.
351  */
352 #define list_first_entry(ptr, type, member) \
353     list_entry((ptr)->next, type, member)
354 
355 /**
356  * list_last_entry - get the last element from a list
357  * @ptr:    the list head to take the element from.
358  * @type:    the type of the struct this is embedded in.
359  * @member:    the name of the list_head within the struct.
360  *
361  * Note, that list is expected to be not empty.
362  */
363 #define list_last_entry(ptr, type, member) \
364     list_entry((ptr)->prev, type, member)
365 
366 /**
367  * list_first_entry_or_null - get the first element from a list
368  * @ptr:    the list head to take the element from.
369  * @type:    the type of the struct this is embedded in.
370  * @member:    the name of the list_head within the struct.
371  *
372  * Note that if the list is empty, it returns NULL.
373  */
374 #define list_first_entry_or_null(ptr, type, member) \
375     (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
376 
377 /**
378  * list_next_entry - get the next element in list
379  * @pos:    the type * to cursor
380  * @member:    the name of the list_head within the struct.
381  */
382 #define list_next_entry(pos, member) \
383     list_entry((pos)->member.next, __typeof__(*(pos)), member)
384 
385 /**
386  * list_prev_entry - get the prev element in list
387  * @pos:    the type * to cursor
388  * @member:    the name of the list_head within the struct.
389  */
390 #define list_prev_entry(pos, member) \
391     list_entry((pos)->member.prev, __typeof__(*(pos)), member)
392 
393 /**
394  * list_for_each    -    iterate over a list
395  * @pos:    the &struct list_head to use as a loop cursor.
396  * @head:    the head for your list.
397  */
398 #define list_for_each(pos, head) \
399     for (pos = (head)->next; pos != (head); pos = pos->next)
400     
401 /**
402  * list_for_each_prev    -    iterate over a list backwards
403  * @pos:    the &struct list_head to use as a loop cursor.
404  * @head:    the head for your list.
405  */
406 #define list_for_each_prev(pos, head) \
407     for (pos = (head)->prev; pos != (head); pos = pos->prev)
408 
409 /**
410  * list_for_each_safe - iterate over a list safe against removal of list entry
411  * @pos:    the &struct list_head to use as a loop cursor.
412  * @n:        another &struct list_head to use as temporary storage
413  * @head:    the head for your list.
414  */
415 #define list_for_each_safe(pos, n, head) \
416     for (pos = (head)->next, n = pos->next; pos != (head); \
417         pos = n, n = pos->next)
418 
419 /**
420  * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
421  * @pos:    the &struct list_head to use as a loop cursor.
422  * @n:        another &struct list_head to use as temporary storage
423  * @head:    the head for your list.
424  */
425 #define list_for_each_prev_safe(pos, n, head) \
426     for (pos = (head)->prev, n = pos->prev; \
427          pos != (head); \
428          pos = n, n = pos->prev)
429 
430 /**
431  * list_for_each_entry    -    iterate over list of given type
432  * @pos:    the type * to use as a loop cursor.
433  * @head:    the head for your list.
434  * @member:    the name of the list_head within the struct.
435  */
436 #define list_for_each_entry(pos, head, member) \
437     for (pos = list_first_entry(head, __typeof__(*pos), member); \
438          &pos->member != (head);                    \
439          pos = list_next_entry(pos, member))
440 
441 /**
442  * list_for_each_entry_reverse - iterate backwards over list of given type.
443  * @pos:    the type * to use as a loop cursor.
444  * @head:    the head for your list.
445  * @member:    the name of the list_head within the struct.
446  */
447 #define list_for_each_entry_reverse(pos, head, member) \
448     for (pos = list_last_entry(head, __typeof__(*pos), member); \
449          &pos->member != (head); \
450          pos = list_prev_entry(pos, member))
451 
452 /**
453  * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
454  * @pos:    the type * to use as a start point
455  * @head:    the head of the list
456  * @member:    the name of the list_head within the struct.
457  *
458  * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
459  */
460 #define list_prepare_entry(pos, head, member) \
461     ((pos) ? : list_entry(head, __typeof__(*pos), member))
462 
463 /**
464  * list_for_each_entry_continue - continue iteration over list of given type
465  * @pos:    the type * to use as a loop cursor.
466  * @head:    the head for your list.
467  * @member:    the name of the list_head within the struct.
468  *
469  * Continue to iterate over list of given type, continuing after
470  * the current position.
471  */
472 #define list_for_each_entry_continue(pos, head, member) \
473     for (pos = list_next_entry(pos, member); \
474          &pos->member != (head); \
475          pos = list_next_entry(pos, member))
476 
477 /**
478  * list_for_each_entry_continue_reverse - iterate backwards from the given point
479  * @pos:    the type * to use as a loop cursor.
480  * @head:    the head for your list.
481  * @member:    the name of the list_head within the struct.
482  *
483  * Start to iterate over list of given type backwards, continuing after
484  * the current position.
485  */
486 #define list_for_each_entry_continue_reverse(pos, head, member) \
487     for (pos = list_prev_entry(pos, member); \
488          &pos->member != (head); \
489          pos = list_prev_entry(pos, member))
490 
491 /**
492  * list_for_each_entry_from - iterate over list of given type from the current point
493  * @pos:    the type * to use as a loop cursor.
494  * @head:    the head for your list.
495  * @member:    the name of the list_head within the struct.
496  *
497  * Iterate over list of given type, continuing from current position.
498  */
499 #define list_for_each_entry_from(pos, head, member) \
500     for (; &pos->member != (head); \
501          pos = list_next_entry(pos, member))
502 
503 /**
504  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
505  * @pos:    the type * to use as a loop cursor.
506  * @n:        another type * to use as temporary storage
507  * @head:    the head for your list.
508  * @member:    the name of the list_head within the struct.
509  */
510 #define list_for_each_entry_safe(pos, n, head, member) \
511     for (pos = list_first_entry(head, __typeof__(*pos), member), \
512             n = list_next_entry(pos, member); \
513          &pos->member != (head); \
514          pos = n, n = list_next_entry(n, member))
515 
516 /**
517  * list_for_each_entry_safe_continue - continue list iteration safe against removal
518  * @pos:    the type * to use as a loop cursor.
519  * @n:        another type * to use as temporary storage
520  * @head:    the head for your list.
521  * @member: the name of the list_head within the struct.
522  *
523  * Iterate over list of given type, continuing after current point,
524  * safe against removal of list entry.
525  */
526 #define list_for_each_entry_safe_continue(pos, n, head, member) \
527     for (pos = list_next_entry(pos, member), \
528         n = list_next_entry(pos, member); \
529          &pos->member != (head); \
530          pos = n, n = list_next_entry(n, member))
531     
532 /**
533  * list_for_each_entry_safe_from - iterate over list from current point safe against removal
534  * @pos:    the type * to use as a loop cursor.
535  * @n:        another type * to use as temporary storage
536  * @head:    the head for your list.
537  * @member: the name of the list_head within the struct.
538  *
539  * Iterate over list of given type from current point, safe against
540  * removal of list entry.
541  */
542 #define list_for_each_entry_safe_from(pos, n, head, member) \
543     for (n = list_next_entry(pos, member); \
544          &pos->member != (head); \
545          pos = n, n = list_next_entry(n, member))
546 
547 /**
548  * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
549  * @pos:    the type * to use as a loop cursor.
550  * @n:        another type * to use as temporary storage
551  * @head:    the head for your list.
552  * @member: the name of the list_head within the struct.
553  *
554  * Iterate backwards over list of given type, safe against removal
555  * of list entry.
556  */
557 #define list_for_each_entry_safe_reverse(pos, n, head, member) \
558     for (pos = list_last_entry(head, __typeof__(*pos), member), \
559         n = list_prev_entry(pos, member); \
560          &pos->member != (head); \
561          pos = n, n = list_prev_entry(n, member))
562 
563 /**
564  * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
565  * @pos:    the loop cursor used in the list_for_each_entry_safe loop
566  * @n:        temporary storage used in list_for_each_entry_safe
567  * @member: the name of the list_head within the struct.
568  *
569  * list_safe_reset_next is not safe to use in general if the list may be
570  * modified concurrently (eg. the lock is dropped in the loop body). An
571  * exception to this is if the cursor element (pos) is pinned in the list,
572  * and list_safe_reset_next is called after re-taking the lock and before
573  * completing the current iteration of the loop body.
574  */
575 #define list_safe_reset_next(pos, n, member)                \
576     n = list_next_entry(pos, member)
577 
578 //HASH LIST 
579 struct hlist_head { 
580     struct hlist_node *first; 
581 }; 
582 
583 struct hlist_node { 
584     struct hlist_node *next, **pprev; 
585 }; 
586 
587 /*
588  * Double linked lists with a single pointer list head.
589  * Mostly useful for hash tables where the two pointer list head is
590  * too wasteful.
591  * You lose the ability to access the tail in O(1).
592  */
593 #define HLIST_HEAD_INIT { .first = NULL }
594 #define HLIST_HEAD(name) struct hlist_head name = {.first = NULL}
595 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
596 static inline void INIT_HLIST_NODE(struct hlist_node *h)
597 {
598     h->next = NULL;
599     h->pprev = NULL;
600 }
601 
602 static inline int hlist_unhashed(const struct hlist_node *h) 
603 { 
604     return !h->pprev; 
605 } 
606 
607 static inline int hlist_empty(const struct hlist_head *h) 
608 { 
609     return !h->first; 
610 } 
611 
612 static inline void __hlist_del(struct hlist_node *n) 
613 { 
614     struct hlist_node *next = n->next; 
615     struct hlist_node **pprev = n->pprev; 
616     *pprev = next; 
617     if(next){
618         next->pprev = pprev;
619     }
620 } 
621 
622 static inline void hlist_del(struct hlist_node *n) 
623 { 
624     __hlist_del(n); 
625     n->next = (struct hlist_node *)LIST_POISON1; 
626     n->pprev = (struct hlist_node **)LIST_POISON2; 
627 } 
628 
629 static inline void hlist_del_init(struct hlist_node *n)
630 {
631     if (!hlist_unhashed(n)) {
632         __hlist_del(n);
633         INIT_HLIST_NODE(n);
634     }
635 }
636 
637 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 
638 { 
639     struct hlist_node *first = h->first; 
640     n->next = first; 
641     if(first){
642         first->pprev = &n->next; 
643     }
644     h->first = n; 
645     n->pprev = &h->first; 
646 } 
647 
648 
649 /* next must be != NULL */ 
650 static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next) 
651 { 
652     n->pprev = next->pprev; 
653     n->next = next; 
654     next->pprev = &n->next; 
655     *(n->pprev) = n; 
656 } 
657 
658 static inline void hlist_add_behind(struct hlist_node *n,
659                     struct hlist_node *prev)
660 {
661     n->next = prev->next;
662     prev->next = n;
663     n->pprev = &prev->next;
664 
665     if (n->next)
666         n->next->pprev = &n->next;
667 }
668 
669 /* after that we'll appear to be on some hlist and hlist_del will work */
670 static inline void hlist_add_fake(struct hlist_node *n)
671 {
672     n->pprev = &n->next;
673 }
674 
675 static inline bool hlist_fake(struct hlist_node *h)
676 {
677     return h->pprev == &h->next;
678 }
679 
680 /*
681  * Check whether the node is the only node of the head without
682  * accessing head:
683  */
684 static inline bool hlist_is_singular_node(struct hlist_node *n, 
685                                         struct hlist_head *h)
686 {
687     return !n->next && n->pprev == &h->first;
688 }
689 
690 /*
691  * Move a list from one list head to another. Fixup the pprev
692  * reference of the first entry if it exists.
693  */
694 static inline void hlist_move_list(struct hlist_head *old,
695                    struct hlist_head *new)
696 {
697     new->first = old->first;
698     if (new->first)
699         new->first->pprev = &new->first;
700     old->first = NULL;
701 }
702 
703 #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
704 
705 #define hlist_for_each(pos, head) \
706     for (pos = (head)->first; pos ; pos = pos->next)
707 
708 #define hlist_for_each_safe(pos, n, head) \
709     for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
710          pos = n)
711 
712 #define hlist_entry_safe(ptr, type, member) \
713     ({ __typeof__(ptr) ____ptr = (ptr); \
714        ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
715     })
716 
717 /**
718  * hlist_for_each_entry    - iterate over list of given type
719  * @pos:    the type * to use as a loop cursor.
720  * @head:    the head for your list.
721  * @member:    the name of the hlist_node within the struct.
722  */
723 #define hlist_for_each_entry(pos, head, member) \
724     for (pos = hlist_entry_safe((head)->first, __typeof__(*(pos)), member);\
725          pos; \
726          pos = hlist_entry_safe((pos)->member.next, __typeof__(*(pos)), member))
727 
728 /**
729  * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
730  * @pos:    the type * to use as a loop cursor.
731  * @member: the name of the hlist_node within the struct.
732  */
733 #define hlist_for_each_entry_continue(pos, member) \
734     for (pos = hlist_entry_safe((pos)->member.next, __typeof__(*(pos)), member); \
735          pos; \
736          pos = hlist_entry_safe((pos)->member.next, __typeof__(*(pos)), member))
737 
738 /**
739  * hlist_for_each_entry_from - iterate over a hlist continuing from current point
740  * @pos:    the type * to use as a loop cursor.
741  * @member:    the name of the hlist_node within the struct.
742  */
743 #define hlist_for_each_entry_from(pos, member) \
744     for (; pos; \
745          pos = hlist_entry_safe((pos)->member.next, __typeof__(*(pos)), member))
746 
747 /**
748  * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
749  * @pos:    the type * to use as a loop cursor.
750  * @n:        another &struct hlist_node to use as temporary storage
751  * @head:    the head for your list.
752  * @member:    the name of the hlist_node within the struct.
753  */
754 #define hlist_for_each_entry_safe(pos, n, head, member) \
755     for (pos = hlist_entry_safe((head)->first, __typeof__(*pos), member); \
756          pos && ({ n = pos->member.next; 1; });    \
757          pos = hlist_entry_safe(n, __typeof__(*pos), member))
758 
759 #ifdef __cplusplus
760 } /* extern "C" */
761 #endif
762 
763 #endif

 

posted on 2018-05-04 16:17  Mic_chen  阅读(344)  评论(0编辑  收藏  举报