XFusion API v1.3.0
载入中...
搜索中...
未找到
xf_list.h
浏览该文件的文档.
1
23/*
24 * xf_list.h
25 *
26 * Created on: 2013-8-29
27 * Author: bt
28 */
29
30#ifndef __XF_LIST_H__
31#define __XF_LIST_H__
32
33/* ==================== [Includes] ========================================== */
34
35#include "xf_predef.h"
36
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50/* ==================== [Defines] =========================================== */
51
52#if !defined(XF_LIST_POISON1)
53# define XF_LIST_POISON1 0x00100100
54#endif
55#if !defined(XF_LIST_POISON2)
56# define XF_LIST_POISON2 0x00200200
57#endif
58
59/* ==================== [Typedefs] ========================================== */
60
66};
67typedef struct xf_list_head xf_list_t;
68
69/*
70 * Simple doubly linked list implementation.
71 *
72 * Some of the internal functions ("__xxx") are useful when
73 * manipulating whole lists rather than single entries, as
74 * sometimes we already know the next/prev entries and we can
75 * generate better code by using them directly rather than
76 * using the generic single-entry routines.
77 */
78//static define
82#define XF_LIST_HEAD_INIT(name) { &(name), &(name) }
83
87#define XF_LIST_HEAD(name) \
88 xf_list_t name = XF_LIST_HEAD_INIT(name)
89
90/* ==================== [Global Prototypes] ================================= */
91
97static inline void xf_list_init(xf_list_t *list)
98{
99 list->next = list;
100 list->prev = list;
101}
102
103/*
104 * Insert a new_node entry between two known consecutive entries.
105 *
106 * This is only for internal list manipulation where we know
107 * the prev/next entries already!
108 */
109
119static inline void __xf_list_add(xf_list_t *new_node, xf_list_t *prev, xf_list_t *next)
120{
121 next->prev = new_node;
122 new_node->next = next;
123 new_node->prev = prev;
124 prev->next = new_node;
125}
126
127/*
128 * list_add - add a new_node entry
129 * @new_node: new_node entry to be added
130 * @head: list head to add it after
131 *
132 * Insert a new_node entry after the specified head.
133 * This is good for implementing stacks.
134 */
135
145static inline void xf_list_add(xf_list_t *new_node, xf_list_t *head)
146{
147 __xf_list_add(new_node, head, head->next);
148}
149
150/*
151 * list_add_tail - add a new_node entry
152 * @new_node: new_node entry to be added
153 * @head: list head to add it before
154 *
155 * Insert a new_node entry before the specified head.
156 * This is useful for implementing queues.
157 */
158
168static inline void xf_list_add_tail(xf_list_t *new_node, xf_list_t *head)
169{
170 __xf_list_add(new_node, head->prev, head);
171}
172
173/*
174 * list_del - deletes entry from list.
175 * @entry: the element to delete from the list.
176 * Note: list_empty() on entry does not return true after this, the entry is
177 * in an undefined state.
178 */
179
189{
190 next->prev = prev;
191 prev->next = next;
192}
193
194/*
195 * list_del - deletes entry from list.
196 * @entry: the element to delete from the list.
197 * Note: list_empty() on entry does not return true after this, the entry is
198 * in an undefined state.
199 */
200
201static inline void __xf_list_del_entry(xf_list_t *entry)
202{
203 __xf_list_del(entry->prev, entry->next);
204}
205
213static inline void xf_list_del(xf_list_t *entry)
214{
215 __xf_list_del(entry->prev, entry->next);
216 entry->next = (xf_list_t *)XF_LIST_POISON1;
217 entry->prev = (xf_list_t *)XF_LIST_POISON2;
218}
219
220/*
221 * list_replace - replace old entry by new_node one
222 * @old : the element to be replaced
223 * @new_node : the new_node element to insert
224 *
225 * If @old was empty, it will be overwritten.
226 */
227
236static inline void xf_list_replace(xf_list_t *old, xf_list_t *new_node)
237{
238 new_node->next = old->next;
239 new_node->next->prev = new_node;
240 new_node->prev = old->prev;
241 new_node->prev->next = new_node;
242}
243
250static inline void xf_list_replace_init(xf_list_t *old, xf_list_t *new_node)
251{
252 xf_list_replace(old, new_node);
253 xf_list_init(old);
254}
255
256/*
257 * list_del_init - deletes entry from list and reinitialize it.
258 * @entry: the element to delete from the list.
259 */
260
266static inline void xf_list_del_init(xf_list_t *entry)
267{
268 __xf_list_del_entry(entry);
269 xf_list_init(entry);
270}
271
272/*
273 * list_move - delete from one list and add as another's head
274 * @list: the entry to move
275 * @head: the head that will precede our entry
276 */
277
285static inline void xf_list_move(xf_list_t *list, xf_list_t *head)
286{
288 xf_list_add(list, head);
289}
290
291/*
292 * list_move_tail - delete from one list and add as another's tail
293 * @list: the entry to move
294 * @head: the head that will follow our entry
295 */
296
303static inline void xf_list_move_tail(xf_list_t *list, xf_list_t *head)
304{
306 xf_list_add_tail(list, head);
307}
308
309/*
310 * list_is_last - tests whether @list is the last entry in list @head
311 * @list: the entry to test
312 * @head: the head of the list
313 */
314
324static inline int xf_list_is_last(const xf_list_t *list, const xf_list_t *head)
325{
326 return list->next == head;
327}
328
329/*
330 * list_empty - tests whether a list is empty
331 * @head: the list to test.
332 */
333
342static inline int xf_list_empty(const xf_list_t *head)
343{
344 return head->next == head;
345}
346
347/*
348 * xf_list_empty_careful - tests whether a list is empty and not being modified
349 * @head: the list to test
350 *
351 * Description:
352 * tests whether a list is empty _and_ checks that no other CPU might be
353 * in the process of modifying either member (next or prev)
354 *
355 * NOTE: using xf_list_empty_careful() without synchronization
356 * can only be safe if the only activity that can happen
357 * to the list entry is xf_list_del_init(). Eg. it cannot be used
358 * if another CPU could re-xf_list_add() it.
359 */
360
375static inline int xf_list_empty_careful(const xf_list_t *head)
376{
377 xf_list_t *next = head->next;
378 return (next == head) && (next == head->prev);
379}
380
381/*
382 * list_rotate_left - rotate the list to the left
383 * @head: the head of the list
384 */
385
391static inline void xf_list_rotate_left(xf_list_t *head)
392{
393 xf_list_t *first;
394
395 if (!xf_list_empty(head)) {
396 first = head->next;
397 xf_list_move_tail(first, head);
398 }
399}
400
401/*
402 * list_is_singular - tests whether a list has just one entry.
403 * @head: the list to test.
404 */
405
414static inline int xf_list_is_singular(const xf_list_t *head)
415{
416 return !xf_list_empty(head) && (head->next == head->prev);
417}
418
419static inline void __xf_list_cut_position(
420 xf_list_t *list, xf_list_t *head, xf_list_t *entry)
421{
422 xf_list_t *new_node_first = entry->next;
423 list->next = head->next;
424 list->next->prev = list;
425 list->prev = entry;
426 entry->next = list;
427 head->next = new_node_first;
428 new_node_first->prev = head;
429}
430
431/*
432 * xf_list_cut_position - cut a list into two
433 * @list: a new_node list to add all removed entries
434 * @head: a list with entries
435 * @entry: an entry within head, could be the head itself
436 * and if so we won't cut the list
437 *
438 * This helper moves the initial part of @head, up to and
439 * including @entry, from @head to @list. You should
440 * pass on @entry an element you know is on @head. @list
441 * should be an empty list or a list you do not care about
442 * losing its data.
443 *
444 */
445
457static inline void xf_list_cut_position(
458 xf_list_t *list, xf_list_t *head, xf_list_t *entry)
459{
460 if (xf_list_empty(head)) {
461 return;
462 }
463 if (xf_list_is_singular(head)
464 && (head->next != entry && head != entry)) {
465 return;
466 }
467 if (entry == head) {
468 xf_list_init(list);
469 } else {
470 __xf_list_cut_position(list, head, entry);
471 }
472}
473
474static inline void __xf_list_splice(
475 const xf_list_t *list, xf_list_t *prev, xf_list_t *next)
476{
477 xf_list_t *first = list->next;
478 xf_list_t *last = list->prev;
479
480 first->prev = prev;
481 prev->next = first;
482
483 last->next = next;
484 next->prev = last;
485}
486
487/*
488 * xf_list_splice - join two lists, this is designed for stacks
489 * @list: the new_node list to add.
490 * @head: the place to add it in the first list.
491 */
492
499static inline void xf_list_splice(
500 const xf_list_t *list, xf_list_t *head)
501{
502 if (!xf_list_empty(list)) {
503 __xf_list_splice(list, head, head->next);
504 }
505}
506
507/*
508 * xf_list_splice_tail - join two lists, each list being a queue
509 * @list: the new_node list to add.
510 * @head: the place to add it in the first list.
511 */
512
519static inline void xf_list_splice_tail(xf_list_t *list, xf_list_t *head)
520{
521 if (!xf_list_empty(list)) {
522 __xf_list_splice(list, head->prev, head);
523 }
524}
525
526/*
527 * xf_list_splice_init - join two lists and reinitialise the emptied list.
528 * @list: the new_node list to add.
529 * @head: the place to add it in the first list.
530 *
531 * The list at @list is reinitialised
532 */
533
542static inline void xf_list_splice_init(xf_list_t *list, xf_list_t *head)
543{
544 if (!xf_list_empty(list)) {
545 __xf_list_splice(list, head, head->next);
546 xf_list_init(list);
547 }
548}
549
550/*
551 * xf_list_splice_tail_init - join two lists and reinitialise the emptied list
552 * @list: the new_node list to add.
553 * @head: the place to add it in the first list.
554 *
555 * Each of the lists is a queue.
556 * The list at @list is reinitialised
557 */
558
568static inline void xf_list_splice_tail_init(xf_list_t *list, xf_list_t *head)
569{
570 if (!xf_list_empty(list)) {
571 __xf_list_splice(list, head->prev, head);
572 xf_list_init(list);
573 }
574}
575
576/* ==================== [Macros] ============================================ */
577
578/*
579 * list_entry - get the struct for this entry
580 * @ptr: the &struct list_head pointer.
581 * @type: the type of the struct this is embedded in.
582 * @member: the name of the list_struct within the struct.
583 */
584
595#define xf_list_entry(ptr, type, member) \
596 xf_container_of(ptr, type, member)
597
598/*
599 * list_first_entry - get the first element from a list
600 * @ptr: the list head to take the element from.
601 * @type: the type of the struct this is embedded in.
602 * @member: the name of the list_struct within the struct.
603 *
604 * Note, that list is expected to be not empty.
605 */
606
617#define xf_list_first_entry(ptr, type, member) \
618 xf_list_entry((ptr)->next, type, member)
619
620/*
621 * list_for_each - iterate over a list
622 * @pos: the &struct list_head to use as a loop cursor.
623 * @head: the head for your list.
624 */
625
632#define xf_list_for_each(pos, head) \
633 for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
634
635/*
636 * __list_for_each - iterate over a list
637 * @pos: the &struct list_head to use as a loop cursor.
638 * @head: the head for your list.
639 *
640 * This variant doesn't differ from list_for_each() any more.
641 * We don't do prefetching in either case.
642 */
643
652#define __xf_list_for_each(pos, head) \
653 for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
654
655/*
656 * list_for_each_prev - iterate over a list backwards
657 * @pos: the &struct list_head to use as a loop cursor.
658 * @head: the head for your list.
659 */
660
667#define xf_list_for_each_prev(pos, head) \
668 for ((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)
669
670/*
671 * list_for_each_safe - iterate over a list safe against removal of list entry
672 * @pos: the &struct list_head to use as a loop cursor.
673 * @n: another &struct list_head to use as temporary storage
674 * @head: the head for your list.
675 */
676
684#define xf_list_for_each_safe(pos, n, head) \
685 for ((pos) = (head)->next, (n) = (pos)->next; (pos) != (head); \
686 (pos) = (n), (n) = (pos)->next)
687
688/*
689 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
690 * @pos: the &struct list_head to use as a loop cursor.
691 * @n: another &struct list_head to use as temporary storage
692 * @head: the head for your list.
693 */
694
702#define xf_list_for_each_prev_safe(pos, n, head) \
703 for ((pos) = (head)->prev, (n) = (pos)->prev; \
704 (pos) != (head); \
705 (pos) = (n), (n) = (pos)->prev)
706
715/*
716 * list_for_each_entry - iterate over list of given type
717 * @pos: the type * to use as a loop cursor.
718 * @head: the head for your list.
719 * @member: the name of the list_struct within the struct.
720 */
721
732#define xf_list_for_each_entry(pos, head, type, member) \
733 for ((pos) = xf_list_entry((head)->next, type, member); \
734 &(pos)->member != (head); \
735 (pos) = xf_list_entry((pos)->member.next, type, member))
736
737/*
738 * list_for_each_entry_reverse - iterate backwards over list of given type.
739 * @pos: the type * to use as a loop cursor.
740 * @head: the head for your list.
741 * @member: the name of the list_struct within the struct.
742 */
743
754#define xf_list_for_each_entry_reverse(pos, head, type, member) \
755 for ((pos) = xf_list_entry((head)->prev, type, member); \
756 &(pos)->member != (head); \
757 (pos) = xf_list_entry((pos)->member.prev, type, member))
758
759/*
760 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
761 * @pos: the type * to use as a start point
762 * @head: the head of the list
763 * @member: the name of the list_struct within the struct.
764 *
765 * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
766 */
767
779#define xf_list_prepare_entry(pos, head, type, member) \
780 ((pos) ? : xf_list_entry(head, type, member))
781
782/*
783 * list_for_each_entry_continue - continue iteration over list of given type
784 * @pos: the type * to use as a loop cursor.
785 * @head: the head for your list.
786 * @member: the name of the list_struct within the struct.
787 *
788 * Continue to iterate over list of given type, continuing after
789 * the current position.
790 */
791
802#define xf_list_for_each_entry_continue(pos, head, type, member) \
803 for ((pos) = xf_list_entry((pos)->member.next, type, member); \
804 &(pos)->member != (head); \
805 (pos) = xf_list_entry((pos)->member.next, type, member))
806
807/*
808 * list_for_each_entry_continue_reverse - iterate backwards from the given point
809 * @pos: the type * to use as a loop cursor.
810 * @head: the head for your list.
811 * @member: the name of the list_struct within the struct.
812 *
813 * Start to iterate over list of given type backwards, continuing after
814 * the current position.
815 */
816
827#define xf_list_for_each_entry_continue_reverse(pos, head, type, member) \
828 for ((pos) = xf_list_entry((pos)->member.prev, type, member); \
829 &(pos)->member != (head); \
830 (pos) = xf_list_entry((pos)->member.prev, type, member))
831
832/*
833 * list_for_each_entry_from - iterate over list of given type from the current point
834 * @pos: the type * to use as a loop cursor.
835 * @head: the head for your list.
836 * @member: the name of the list_struct within the struct.
837 *
838 * Iterate over list of given type, continuing from current position.
839 */
840
851#define xf_list_for_each_entry_from(pos, head, type, member) \
852 for (; &(pos)->member != (head); \
853 (pos) = xf_list_entry((pos)->member.next, type, member))
854
855/*
856 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
857 * @pos: the type * to use as a loop cursor.
858 * @n: another type * to use as temporary storage
859 * @head: the head for your list.
860 * @member: the name of the list_struct within the struct.
861 */
862
876#define xf_list_for_each_entry_safe(pos, n, head, type, member) \
877 for ((pos) = xf_list_entry((head)->next, type, member), \
878 (n) = xf_list_entry((pos)->member.next, type, member); \
879 &(pos)->member != (head); \
880 (pos) = (n), (n) = xf_list_entry(n->member.next, type, member))
881
882/*
883 * list_for_each_entry_safe_continue - continue list iteration safe against removal
884 * @pos: the type * to use as a loop cursor.
885 * @n: another type * to use as temporary storage
886 * @head: the head for your list.
887 * @member: the name of the list_struct within the struct.
888 *
889 * Iterate over list of given type, continuing after current point,
890 * safe against removal of list entry.
891 */
892
906#define xf_list_for_each_entry_safe_continue(pos, n, head, type, member) \
907 for ((pos) = xf_list_entry((pos)->member.next, type, member), \
908 (n) = xf_list_entry((pos)->member.next, type, member); \
909 &(pos)->member != (head); \
910 (pos) = (n), (n) = xf_list_entry((n)->member.next, type, member))
911
912/*
913 * list_for_each_entry_safe_from - iterate over list from current point safe against removal
914 * @pos: the type * to use as a loop cursor.
915 * @n: another type * to use as temporary storage
916 * @head: the head for your list.
917 * @member: the name of the list_struct within the struct.
918 *
919 * Iterate over list of given type from current point, safe against
920 * removal of list entry.
921 */
922
936#define xf_list_for_each_entry_safe_from(pos, n, head, type, member) \
937 for ((n) = xf_list_entry((pos)->member.next, type, member); \
938 &(pos)->member != (head); \
939 (pos) = (n), (n) = xf_list_entry((n)->member.next, type, member))
940
941/*
942 * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
943 * @pos: the type * to use as a loop cursor.
944 * @n: another type * to use as temporary storage
945 * @head: the head for your list.
946 * @member: the name of the list_struct within the struct.
947 *
948 * Iterate backwards over list of given type, safe against removal
949 * of list entry.
950 */
951
965#define xf_list_for_each_entry_safe_reverse(pos, n, head, type, member) \
966 for ((pos) = xf_list_entry((head)->prev, type, member), \
967 (n) = xf_list_entry((pos)->member.prev, type, member); \
968 &(pos)->member != (head); \
969 (pos) = (n), (n) = xf_list_entry((n)->member.prev, type, member))
970
971/*
972 * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
973 * @pos: the loop cursor used in the list_for_each_entry_safe loop
974 * @n: temporary storage used in list_for_each_entry_safe
975 * @member: the name of the list_struct within the struct.
976 *
977 * list_safe_reset_next is not safe to use in general if the list may be
978 * modified concurrently (eg. the lock is dropped in the loop body). An
979 * exception to this is if the cursor element (pos) is pinned in the list,
980 * and list_safe_reset_next is called after re-taking the lock and before
981 * completing the current iteration of the loop body.
982 */
983
999#define xf_list_safe_reset_next(pos, n, type, member) \
1000 (n) = xf_list_entry((pos)->member.next, type, member)
1001
1002#ifdef __cplusplus
1003} /*extern "C"*/
1004#endif
1005
1011#endif /* __XF_LIST_H__ */
static void xf_list_init(xf_list_t *list)
动态初始化链表.
Definition xf_list.h:97
static int xf_list_is_singular(const xf_list_t *head)
xf_list_is_singular - 测试链表是否只有一个节点.
Definition xf_list.h:414
static void xf_list_add_tail(xf_list_t *new_node, xf_list_t *head)
xf_list_add_tail - 在指定节点之前添加一个 new_node.
Definition xf_list.h:168
static void xf_list_del_init(xf_list_t *entry)
xf_list_del_init - 从链表中删除节点, 并重新初始化.
Definition xf_list.h:266
static void xf_list_splice(const xf_list_t *list, xf_list_t *head)
xf_list_splice - 连接两个链表, 这是为栈设计的.
Definition xf_list.h:499
static void __xf_list_splice(const xf_list_t *list, xf_list_t *prev, xf_list_t *next)
Definition xf_list.h:474
static void xf_list_cut_position(xf_list_t *list, xf_list_t *head, xf_list_t *entry)
xf_list_cut_position - 将链表切成两部分.
Definition xf_list.h:457
static void xf_list_replace(xf_list_t *old, xf_list_t *new_node)
xf_list_replace - 用 new_node 替换旧节点.
Definition xf_list.h:236
static int xf_list_empty(const xf_list_t *head)
xf_list_empty - 测试链表是否为空.
Definition xf_list.h:342
static void xf_list_splice_init(xf_list_t *list, xf_list_t *head)
xf_list_splice_init - 连接两个链表并重新初始化空链表.
Definition xf_list.h:542
static void __xf_list_add(xf_list_t *new_node, xf_list_t *prev, xf_list_t *next)
在两个已知的连续节点之间插入一个 new_node 节点.
Definition xf_list.h:119
#define XF_LIST_POISON1
Definition xf_list.h:53
static void xf_list_splice_tail(xf_list_t *list, xf_list_t *head)
xf_list_splice_tail - 连接两个链表, 每个链表都是一个队列
Definition xf_list.h:519
static void xf_list_splice_tail_init(xf_list_t *list, xf_list_t *head)
xf_list_splice_tail_init - 连接两个链表并重新初始化空链表.
Definition xf_list.h:568
static void xf_list_rotate_left(xf_list_t *head)
xf_list_rotate_left - 将链表向左旋转.
Definition xf_list.h:391
static void __xf_list_del_entry(xf_list_t *entry)
Definition xf_list.h:201
#define XF_LIST_POISON2
Definition xf_list.h:56
static void xf_list_move_tail(xf_list_t *list, xf_list_t *head)
xf_list_move_tail - 从一个链表中删除指定节点, 并添加为另一个链表的尾节点.
Definition xf_list.h:303
static int xf_list_empty_careful(const xf_list_t *head)
xf_list_empty_careful - 测试链表是否为空且未被修改.
Definition xf_list.h:375
static void xf_list_add(xf_list_t *new_node, xf_list_t *head)
xf_list_add - 在指定节点之后添加一个 new_node.
Definition xf_list.h:145
static int xf_list_is_last(const xf_list_t *list, const xf_list_t *head)
xf_list_is_last - 测试 list 是否是链表 head 中的最后一个节点.
Definition xf_list.h:324
static void xf_list_del(xf_list_t *entry)
xf_list_del - 从链表中删除节点.
Definition xf_list.h:213
static void xf_list_replace_init(xf_list_t *old, xf_list_t *new_node)
xf_list_replace_init - 用 new_node 替换旧节点, 并重新初始化旧节点.
Definition xf_list.h:250
static void __xf_list_cut_position(xf_list_t *list, xf_list_t *head, xf_list_t *entry)
Definition xf_list.h:419
static void xf_list_move(xf_list_t *list, xf_list_t *head)
xf_list_move - 从一个链表中删除指定节点, 并添加为另一个链表的头节点。.
Definition xf_list.h:285
static void __xf_list_del(xf_list_t *prev, xf_list_t *next)
删除链表节点(list entry), 使前一个/后一个节点相互指向.
Definition xf_list.h:188
双向链表结构体.
Definition xf_list.h:64
struct xf_list_head * next
Definition xf_list.h:65
struct xf_list_head * prev
Definition xf_list.h:65
预定义宏.