Home | History | Annotate | Download | only in libutil
      1 /**
      2  * @file op_list.h
      3  * Kernel-style lists
      4  *
      5  * @remark Copyright 2002 OProfile authors
      6  * @remark Read the file COPYING
      7  *
      8  * @author Linux kernel authors
      9  */
     10 
     11 #ifndef OP_LIST_H
     12 #define OP_LIST_H
     13 
     14 /*
     15  * Simple doubly linked list implementation.
     16  *
     17  * Some of the internal functions ("__xxx") are useful when
     18  * manipulating whole lists rather than single entries, as
     19  * sometimes we already know the next/prev entries and we can
     20  * generate better code by using them directly rather than
     21  * using the generic single-entry routines.
     22  */
     23 
     24 struct list_head {
     25 	struct list_head * next, * prev;
     26 };
     27 
     28 /**
     29  * list_init - init a new entry
     30  * @param ptr  the list to init
     31  *
     32  * Init a list head to create an empty list from it
     33  */
     34 static __inline__ void list_init(struct list_head * ptr)
     35 {
     36 	ptr->next = ptr;
     37 	ptr->prev = ptr;
     38 }
     39 
     40 /*
     41  * Insert a new entry between two known consecutive entries.
     42  *
     43  * This is only for internal list manipulation where we know
     44  * the prev/next entries already!
     45  */
     46 static __inline__ void __list_add(struct list_head * new_entry,
     47 	struct list_head * prev,
     48 	struct list_head * next)
     49 {
     50 	next->prev = new_entry;
     51 	new_entry->next = next;
     52 	new_entry->prev = prev;
     53 	prev->next = new_entry;
     54 }
     55 
     56 /**
     57  * list_add - add a new entry
     58  * @param new  new entry to be added
     59  * @param head  list head to add it after
     60  *
     61  * Insert a new entry after the specified head.
     62  * This is good for implementing stacks.
     63  */
     64 static __inline__ void list_add(struct list_head * new_entry, struct list_head * head)
     65 {
     66 	__list_add(new_entry, head, head->next);
     67 }
     68 
     69 /**
     70  * list_add_tail - add a new entry
     71  * @param new  new entry to be added
     72  * @param head  list head to add it before
     73  *
     74  * Insert a new entry before the specified head.
     75  * This is useful for implementing queues.
     76  */
     77 static __inline__ void list_add_tail(struct list_head * new_entry, struct list_head * head)
     78 {
     79 	__list_add(new_entry, head->prev, head);
     80 }
     81 
     82 /*
     83  * Delete a list entry by making the prev/next entries
     84  * point to each other.
     85  *
     86  * This is only for internal list manipulation where we know
     87  * the prev/next entries already!
     88  */
     89 static __inline__ void __list_del(struct list_head * prev,
     90 				  struct list_head * next)
     91 {
     92 	next->prev = prev;
     93 	prev->next = next;
     94 }
     95 
     96 /**
     97  * list_del - deletes entry from list.
     98  * @param entry  the element to delete from the list.
     99  * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
    100  */
    101 static __inline__ void list_del(struct list_head * entry)
    102 {
    103 	__list_del(entry->prev, entry->next);
    104 }
    105 
    106 /**
    107  * list_del_init - deletes entry from list and reinitialize it.
    108  * @param entry  the element to delete from the list.
    109  */
    110 static __inline__ void list_del_init(struct list_head * entry)
    111 {
    112 	__list_del(entry->prev, entry->next);
    113 	list_init(entry);
    114 }
    115 
    116 /**
    117  * list_empty - tests whether a list is empty
    118  * @param head  the list to test.
    119  */
    120 static __inline__ int list_empty(struct list_head const * head)
    121 {
    122 	return head->next == head;
    123 }
    124 
    125 /**
    126  * list_splice - join two lists
    127  * @param list  the new list to add.
    128  * @param head  the place to add it in the first list.
    129  */
    130 static __inline__ void list_splice(struct list_head * list, struct list_head * head)
    131 {
    132 	struct list_head * first = list->next;
    133 
    134 	if (first != list) {
    135 		struct list_head * last = list->prev;
    136 		struct list_head * at = head->next;
    137 
    138 		first->prev = head;
    139 		head->next = first;
    140 
    141 		last->next = at;
    142 		at->prev = last;
    143 	}
    144 }
    145 
    146 /**
    147  * list_entry - get the struct for this entry
    148  * @param ptr 	the &struct list_head pointer.
    149  * @param type 	the type of the struct this is embedded in.
    150  * @param member 	the name of the list_struct within the struct.
    151  */
    152 #define list_entry(ptr, type, member) \
    153 	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
    154 
    155 /**
    156  * list_for_each - iterate over a list
    157  * @param pos 	the &struct list_head to use as a loop counter.
    158  * @param head 	the head for your list.
    159  */
    160 #define list_for_each(pos, head) \
    161 	for (pos = (head)->next; pos != (head); pos = pos->next)
    162 
    163 /**
    164  * list_for_each_safe - iterate over a list safe against removal of list entry
    165  * @param pos 	the &struct list_head to use as a loop counter.
    166  * @param n 		another &struct list_head to use as temporary storage
    167  * @param head 	the head for your list.
    168  */
    169 #define list_for_each_safe(pos, n, head) \
    170 	for (pos = (head)->next, n = pos->next; pos != (head); \
    171 		pos = n, n = pos->next)
    172 
    173 #define LIST_HEAD_INIT(name) { &(name), &(name) }
    174 
    175 #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
    176 
    177 #endif /* OP_LIST_H */
    178