mirror of
				https://github.com/DigitalDevices/octonet.git
				synced 2023-10-10 11:36:52 +00:00 
			
		
		
		
	new linked list code
This commit is contained in:
		
							
								
								
									
										580
									
								
								octoscan/list.h
									
									
									
									
									
								
							
							
						
						
									
										580
									
								
								octoscan/list.h
									
									
									
									
									
								
							@@ -1,569 +1,53 @@
 | 
			
		||||
typedef int bool;
 | 
			
		||||
 | 
			
		||||
struct list_head {
 | 
			
		||||
	struct list_head *next, *prev;
 | 
			
		||||
	struct list_head *prev;
 | 
			
		||||
	struct list_head *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define offsetof(type, member) ((size_t)&((type *)0)->member)
 | 
			
		||||
#define list_entry(lh, st, field) container_of(lh, st, field)
 | 
			
		||||
#define list_first_entry(lh, st, field) list_entry((lh)->next, st, field)
 | 
			
		||||
#define list_next_entry(lh, field) list_entry((lh)->field.next, typeof(*(lh)), field)
 | 
			
		||||
 | 
			
		||||
#define container_of(ptr, type, member) ({			\
 | 
			
		||||
	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
 | 
			
		||||
	(type *)( (char *)__mptr - offsetof(type,member) );})
 | 
			
		||||
 | 
			
		||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
 | 
			
		||||
 | 
			
		||||
#define LIST_HEAD(name) \
 | 
			
		||||
	struct list_head name = LIST_HEAD_INIT(name)
 | 
			
		||||
 | 
			
		||||
static inline void INIT_LIST_HEAD(struct list_head *list)
 | 
			
		||||
static inline void list_head_init(struct list_head *lh)
 | 
			
		||||
{
 | 
			
		||||
	list->next = list;
 | 
			
		||||
	list->prev = list;
 | 
			
		||||
	lh->prev = lh->next = lh;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Insert a new entry between two known consecutive entries.
 | 
			
		||||
 *
 | 
			
		||||
 * This is only for internal list manipulation where we know
 | 
			
		||||
 * the prev/next entries already!
 | 
			
		||||
 */
 | 
			
		||||
static inline void __list_add(struct list_head *new,
 | 
			
		||||
			      struct list_head *prev,
 | 
			
		||||
			      struct list_head *next)
 | 
			
		||||
static inline int list_empty(const struct list_head *lh)
 | 
			
		||||
{
 | 
			
		||||
	next->prev = new;
 | 
			
		||||
	new->next = next;
 | 
			
		||||
	new->prev = prev;
 | 
			
		||||
	prev->next = new;
 | 
			
		||||
	return (lh == lh->next);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_add - add a new entry
 | 
			
		||||
 * @new: new entry to be added
 | 
			
		||||
 * @head: list head to add it after
 | 
			
		||||
 *
 | 
			
		||||
 * Insert a new entry after the specified head.
 | 
			
		||||
 * This is good for implementing stacks.
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_add(struct list_head *new, struct list_head *head)
 | 
			
		||||
static inline void list_add(struct list_head *add, struct list_head *lh)
 | 
			
		||||
{
 | 
			
		||||
	__list_add(new, head, head->next);
 | 
			
		||||
	add->prev = lh;
 | 
			
		||||
	add->next = lh->next;
 | 
			
		||||
	lh->next->prev = add;
 | 
			
		||||
	lh->next = add;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_add_tail - add a new entry
 | 
			
		||||
 * @new: new entry to be added
 | 
			
		||||
 * @head: list head to add it before
 | 
			
		||||
 *
 | 
			
		||||
 * Insert a new entry before the specified head.
 | 
			
		||||
 * This is useful for implementing queues.
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
 | 
			
		||||
static inline void list_add_tail(struct list_head *add, struct list_head *lh)
 | 
			
		||||
{
 | 
			
		||||
	__list_add(new, head->prev, head);
 | 
			
		||||
	add->prev = lh->prev;
 | 
			
		||||
	add->next = lh;
 | 
			
		||||
	lh->prev->next = add;
 | 
			
		||||
	lh->prev = add;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Delete a list entry by making the prev/next entries
 | 
			
		||||
 * point to each other.
 | 
			
		||||
 *
 | 
			
		||||
 * This is only for internal list manipulation where we know
 | 
			
		||||
 * the prev/next entries already!
 | 
			
		||||
 */
 | 
			
		||||
static inline void __list_del(struct list_head * prev, struct list_head * next)
 | 
			
		||||
static inline void list_del(struct list_head *del)
 | 
			
		||||
{
 | 
			
		||||
	next->prev = prev;
 | 
			
		||||
	prev->next = next;
 | 
			
		||||
	del->prev->next = del->next;
 | 
			
		||||
	del->next->prev = del->prev;
 | 
			
		||||
	del->prev = del->next = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_del - deletes entry from list.
 | 
			
		||||
 * @entry: the element to delete from the list.
 | 
			
		||||
 * Note: list_empty() on entry does not return true after this, the entry is
 | 
			
		||||
 * in an undefined state.
 | 
			
		||||
 */
 | 
			
		||||
static inline void __list_del_entry(struct list_head *entry)
 | 
			
		||||
{
 | 
			
		||||
	__list_del(entry->prev, entry->next);
 | 
			
		||||
}
 | 
			
		||||
#define list_for_each_entry(cur, lh, field)				\
 | 
			
		||||
	for ((cur) = list_entry((lh)->next, typeof(*(cur)), field);	\
 | 
			
		||||
	     &(cur)->field != (lh);					\
 | 
			
		||||
	     (cur) = list_entry((cur)->field.next, typeof(*(cur)), field))
 | 
			
		||||
 | 
			
		||||
static inline void list_del(struct list_head *entry)
 | 
			
		||||
{
 | 
			
		||||
	__list_del(entry->prev, entry->next);
 | 
			
		||||
	entry->next = NULL;
 | 
			
		||||
	entry->prev = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_replace - replace old entry by new one
 | 
			
		||||
 * @old : the element to be replaced
 | 
			
		||||
 * @new : the new element to insert
 | 
			
		||||
 *
 | 
			
		||||
 * If @old was empty, it will be overwritten.
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_replace(struct list_head *old,
 | 
			
		||||
				struct list_head *new)
 | 
			
		||||
{
 | 
			
		||||
	new->next = old->next;
 | 
			
		||||
	new->next->prev = new;
 | 
			
		||||
	new->prev = old->prev;
 | 
			
		||||
	new->prev->next = new;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void list_replace_init(struct list_head *old,
 | 
			
		||||
					struct list_head *new)
 | 
			
		||||
{
 | 
			
		||||
	list_replace(old, new);
 | 
			
		||||
	INIT_LIST_HEAD(old);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_del_init - deletes entry from list and reinitialize it.
 | 
			
		||||
 * @entry: the element to delete from the list.
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_del_init(struct list_head *entry)
 | 
			
		||||
{
 | 
			
		||||
	__list_del_entry(entry);
 | 
			
		||||
	INIT_LIST_HEAD(entry);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_move - delete from one list and add as another's head
 | 
			
		||||
 * @list: the entry to move
 | 
			
		||||
 * @head: the head that will precede our entry
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_move(struct list_head *list, struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	__list_del_entry(list);
 | 
			
		||||
	list_add(list, head);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_move_tail - delete from one list and add as another's tail
 | 
			
		||||
 * @list: the entry to move
 | 
			
		||||
 * @head: the head that will follow our entry
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_move_tail(struct list_head *list,
 | 
			
		||||
				  struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	__list_del_entry(list);
 | 
			
		||||
	list_add_tail(list, head);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_is_last - tests whether @list is the last entry in list @head
 | 
			
		||||
 * @list: the entry to test
 | 
			
		||||
 * @head: the head of the list
 | 
			
		||||
 */
 | 
			
		||||
static inline int list_is_last(const struct list_head *list,
 | 
			
		||||
				const struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	return list->next == head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_empty - tests whether a list is empty
 | 
			
		||||
 * @head: the list to test.
 | 
			
		||||
 */
 | 
			
		||||
static inline int list_empty(const struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	return head->next == head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_empty_careful - tests whether a list is empty and not being modified
 | 
			
		||||
 * @head: the list to test
 | 
			
		||||
 *
 | 
			
		||||
 * Description:
 | 
			
		||||
 * tests whether a list is empty _and_ checks that no other CPU might be
 | 
			
		||||
 * in the process of modifying either member (next or prev)
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: using list_empty_careful() without synchronization
 | 
			
		||||
 * can only be safe if the only activity that can happen
 | 
			
		||||
 * to the list entry is list_del_init(). Eg. it cannot be used
 | 
			
		||||
 * if another CPU could re-list_add() it.
 | 
			
		||||
 */
 | 
			
		||||
static inline int list_empty_careful(const struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *next = head->next;
 | 
			
		||||
	return (next == head) && (next == head->prev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_rotate_left - rotate the list to the left
 | 
			
		||||
 * @head: the head of the list
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_rotate_left(struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *first;
 | 
			
		||||
 | 
			
		||||
	if (!list_empty(head)) {
 | 
			
		||||
		first = head->next;
 | 
			
		||||
		list_move_tail(first, head);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_is_singular - tests whether a list has just one entry.
 | 
			
		||||
 * @head: the list to test.
 | 
			
		||||
 */
 | 
			
		||||
static inline int list_is_singular(const struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	return !list_empty(head) && (head->next == head->prev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void __list_cut_position(struct list_head *list,
 | 
			
		||||
		struct list_head *head, struct list_head *entry)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *new_first = entry->next;
 | 
			
		||||
	list->next = head->next;
 | 
			
		||||
	list->next->prev = list;
 | 
			
		||||
	list->prev = entry;
 | 
			
		||||
	entry->next = list;
 | 
			
		||||
	head->next = new_first;
 | 
			
		||||
	new_first->prev = head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_cut_position - cut a list into two
 | 
			
		||||
 * @list: a new list to add all removed entries
 | 
			
		||||
 * @head: a list with entries
 | 
			
		||||
 * @entry: an entry within head, could be the head itself
 | 
			
		||||
 *	and if so we won't cut the list
 | 
			
		||||
 *
 | 
			
		||||
 * This helper moves the initial part of @head, up to and
 | 
			
		||||
 * including @entry, from @head to @list. You should
 | 
			
		||||
 * pass on @entry an element you know is on @head. @list
 | 
			
		||||
 * should be an empty list or a list you do not care about
 | 
			
		||||
 * losing its data.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_cut_position(struct list_head *list,
 | 
			
		||||
		struct list_head *head, struct list_head *entry)
 | 
			
		||||
{
 | 
			
		||||
	if (list_empty(head))
 | 
			
		||||
		return;
 | 
			
		||||
	if (list_is_singular(head) &&
 | 
			
		||||
		(head->next != entry && head != entry))
 | 
			
		||||
		return;
 | 
			
		||||
	if (entry == head)
 | 
			
		||||
		INIT_LIST_HEAD(list);
 | 
			
		||||
	else
 | 
			
		||||
		__list_cut_position(list, head, entry);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void __list_splice(const struct list_head *list,
 | 
			
		||||
				 struct list_head *prev,
 | 
			
		||||
				 struct list_head *next)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *first = list->next;
 | 
			
		||||
	struct list_head *last = list->prev;
 | 
			
		||||
 | 
			
		||||
	first->prev = prev;
 | 
			
		||||
	prev->next = first;
 | 
			
		||||
 | 
			
		||||
	last->next = next;
 | 
			
		||||
	next->prev = last;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_splice - join two lists, this is designed for stacks
 | 
			
		||||
 * @list: the new list to add.
 | 
			
		||||
 * @head: the place to add it in the first list.
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_splice(const struct list_head *list,
 | 
			
		||||
				struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	if (!list_empty(list))
 | 
			
		||||
		__list_splice(list, head, head->next);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_splice_tail - join two lists, each list being a queue
 | 
			
		||||
 * @list: the new list to add.
 | 
			
		||||
 * @head: the place to add it in the first list.
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_splice_tail(struct list_head *list,
 | 
			
		||||
				struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	if (!list_empty(list))
 | 
			
		||||
		__list_splice(list, head->prev, head);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_splice_init - join two lists and reinitialise the emptied list.
 | 
			
		||||
 * @list: the new list to add.
 | 
			
		||||
 * @head: the place to add it in the first list.
 | 
			
		||||
 *
 | 
			
		||||
 * The list at @list is reinitialised
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_splice_init(struct list_head *list,
 | 
			
		||||
				    struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	if (!list_empty(list)) {
 | 
			
		||||
		__list_splice(list, head, head->next);
 | 
			
		||||
		INIT_LIST_HEAD(list);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_splice_tail_init - join two lists and reinitialise the emptied list
 | 
			
		||||
 * @list: the new list to add.
 | 
			
		||||
 * @head: the place to add it in the first list.
 | 
			
		||||
 *
 | 
			
		||||
 * Each of the lists is a queue.
 | 
			
		||||
 * The list at @list is reinitialised
 | 
			
		||||
 */
 | 
			
		||||
static inline void list_splice_tail_init(struct list_head *list,
 | 
			
		||||
					 struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	if (!list_empty(list)) {
 | 
			
		||||
		__list_splice(list, head->prev, head);
 | 
			
		||||
		INIT_LIST_HEAD(list);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_entry - get the struct for this entry
 | 
			
		||||
 * @ptr:	the &struct list_head pointer.
 | 
			
		||||
 * @type:	the type of the struct this is embedded in.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 */
 | 
			
		||||
#define list_entry(ptr, type, member) \
 | 
			
		||||
	container_of(ptr, type, member)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_first_entry - get the first element from a list
 | 
			
		||||
 * @ptr:	the list head to take the element from.
 | 
			
		||||
 * @type:	the type of the struct this is embedded in.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Note, that list is expected to be not empty.
 | 
			
		||||
 */
 | 
			
		||||
#define list_first_entry(ptr, type, member) \
 | 
			
		||||
	list_entry((ptr)->next, type, member)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_last_entry - get the last element from a list
 | 
			
		||||
 * @ptr:	the list head to take the element from.
 | 
			
		||||
 * @type:	the type of the struct this is embedded in.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Note, that list is expected to be not empty.
 | 
			
		||||
 */
 | 
			
		||||
#define list_last_entry(ptr, type, member) \
 | 
			
		||||
	list_entry((ptr)->prev, type, member)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_first_entry_or_null - get the first element from a list
 | 
			
		||||
 * @ptr:	the list head to take the element from.
 | 
			
		||||
 * @type:	the type of the struct this is embedded in.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that if the list is empty, it returns NULL.
 | 
			
		||||
 */
 | 
			
		||||
#define list_first_entry_or_null(ptr, type, member) \
 | 
			
		||||
	(!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_next_entry - get the next element in list
 | 
			
		||||
 * @pos:	the type * to cursor
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 */
 | 
			
		||||
#define list_next_entry(pos, member) \
 | 
			
		||||
	list_entry((pos)->member.next, typeof(*(pos)), member)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_prev_entry - get the prev element in list
 | 
			
		||||
 * @pos:	the type * to cursor
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 */
 | 
			
		||||
#define list_prev_entry(pos, member) \
 | 
			
		||||
	list_entry((pos)->member.prev, typeof(*(pos)), member)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each	-	iterate over a list
 | 
			
		||||
 * @pos:	the &struct list_head to use as a loop cursor.
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each(pos, head) \
 | 
			
		||||
	for (pos = (head)->next; pos != (head); pos = pos->next)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_prev	-	iterate over a list backwards
 | 
			
		||||
 * @pos:	the &struct list_head to use as a loop cursor.
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_prev(pos, head) \
 | 
			
		||||
	for (pos = (head)->prev; pos != (head); pos = pos->prev)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_safe - iterate over a list safe against removal of list entry
 | 
			
		||||
 * @pos:	the &struct list_head to use as a loop cursor.
 | 
			
		||||
 * @n:		another &struct list_head to use as temporary storage
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_safe(pos, n, head) \
 | 
			
		||||
	for (pos = (head)->next, n = pos->next; pos != (head); \
 | 
			
		||||
		pos = n, n = pos->next)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
 | 
			
		||||
 * @pos:	the &struct list_head to use as a loop cursor.
 | 
			
		||||
 * @n:		another &struct list_head to use as temporary storage
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_prev_safe(pos, n, head) \
 | 
			
		||||
	for (pos = (head)->prev, n = pos->prev; \
 | 
			
		||||
	     pos != (head); \
 | 
			
		||||
	     pos = n, n = pos->prev)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry	-	iterate over list of given type
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry(pos, head, member)				\
 | 
			
		||||
	for (pos = list_first_entry(head, typeof(*pos), member);	\
 | 
			
		||||
	     &pos->member != (head);					\
 | 
			
		||||
	     pos = list_next_entry(pos, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry_reverse - iterate backwards over list of given type.
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry_reverse(pos, head, member)			\
 | 
			
		||||
	for (pos = list_last_entry(head, typeof(*pos), member);		\
 | 
			
		||||
	     &pos->member != (head); 					\
 | 
			
		||||
	     pos = list_prev_entry(pos, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
 | 
			
		||||
 * @pos:	the type * to use as a start point
 | 
			
		||||
 * @head:	the head of the list
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
 | 
			
		||||
 */
 | 
			
		||||
#define list_prepare_entry(pos, head, member) \
 | 
			
		||||
	((pos) ? : list_entry(head, typeof(*pos), member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry_continue - continue iteration over list of given type
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Continue to iterate over list of given type, continuing after
 | 
			
		||||
 * the current position.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry_continue(pos, head, member) 		\
 | 
			
		||||
	for (pos = list_next_entry(pos, member);			\
 | 
			
		||||
	     &pos->member != (head);					\
 | 
			
		||||
	     pos = list_next_entry(pos, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry_continue_reverse - iterate backwards from the given point
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Start to iterate over list of given type backwards, continuing after
 | 
			
		||||
 * the current position.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry_continue_reverse(pos, head, member)		\
 | 
			
		||||
	for (pos = list_prev_entry(pos, member);			\
 | 
			
		||||
	     &pos->member != (head);					\
 | 
			
		||||
	     pos = list_prev_entry(pos, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry_from - iterate over list of given type from the current point
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Iterate over list of given type, continuing from current position.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry_from(pos, head, member) 			\
 | 
			
		||||
	for (; &pos->member != (head);					\
 | 
			
		||||
	     pos = list_next_entry(pos, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @n:		another type * to use as temporary storage
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry_safe(pos, n, head, member)			\
 | 
			
		||||
	for (pos = list_first_entry(head, typeof(*pos), member),	\
 | 
			
		||||
		n = list_next_entry(pos, member);			\
 | 
			
		||||
	     &pos->member != (head); 					\
 | 
			
		||||
	     pos = n, n = list_next_entry(n, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry_safe_continue - continue list iteration safe against removal
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @n:		another type * to use as temporary storage
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Iterate over list of given type, continuing after current point,
 | 
			
		||||
 * safe against removal of list entry.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
 | 
			
		||||
	for (pos = list_next_entry(pos, member), 				\
 | 
			
		||||
		n = list_next_entry(pos, member);				\
 | 
			
		||||
	     &pos->member != (head);						\
 | 
			
		||||
	     pos = n, n = list_next_entry(n, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry_safe_from - iterate over list from current point safe against removal
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @n:		another type * to use as temporary storage
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Iterate over list of given type from current point, safe against
 | 
			
		||||
 * removal of list entry.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry_safe_from(pos, n, head, member) 			\
 | 
			
		||||
	for (n = list_next_entry(pos, member);					\
 | 
			
		||||
	     &pos->member != (head);						\
 | 
			
		||||
	     pos = n, n = list_next_entry(n, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
 | 
			
		||||
 * @pos:	the type * to use as a loop cursor.
 | 
			
		||||
 * @n:		another type * to use as temporary storage
 | 
			
		||||
 * @head:	the head for your list.
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * Iterate backwards over list of given type, safe against removal
 | 
			
		||||
 * of list entry.
 | 
			
		||||
 */
 | 
			
		||||
#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
 | 
			
		||||
	for (pos = list_last_entry(head, typeof(*pos), member),		\
 | 
			
		||||
		n = list_prev_entry(pos, member);			\
 | 
			
		||||
	     &pos->member != (head); 					\
 | 
			
		||||
	     pos = n, n = list_prev_entry(n, member))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
 | 
			
		||||
 * @pos:	the loop cursor used in the list_for_each_entry_safe loop
 | 
			
		||||
 * @n:		temporary storage used in list_for_each_entry_safe
 | 
			
		||||
 * @member:	the name of the list_head within the struct.
 | 
			
		||||
 *
 | 
			
		||||
 * list_safe_reset_next is not safe to use in general if the list may be
 | 
			
		||||
 * modified concurrently (eg. the lock is dropped in the loop body). An
 | 
			
		||||
 * exception to this is if the cursor element (pos) is pinned in the list,
 | 
			
		||||
 * and list_safe_reset_next is called after re-taking the lock and before
 | 
			
		||||
 * completing the current iteration of the loop body.
 | 
			
		||||
 */
 | 
			
		||||
#define list_safe_reset_next(pos, n, member)				\
 | 
			
		||||
	n = list_next_entry(pos, member)
 | 
			
		||||
#define list_for_each_entry_safe(cur, nxt, lh, field)			\
 | 
			
		||||
	for ((cur) = list_entry((lh)->next, typeof(*(cur)), field),	\
 | 
			
		||||
		     (nxt) = list_next_entry((cur), field);		\
 | 
			
		||||
	     &(cur)->field != (lh);					\
 | 
			
		||||
	     (cur) = (nxt), (nxt) = list_next_entry((nxt), field))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,26 @@
 | 
			
		||||
/*  
 | 
			
		||||
    (C) 2015-16 Digital Devices GmbH. 
 | 
			
		||||
 | 
			
		||||
    Octoscan is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    Octoscan is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with octoserve.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
@@ -27,6 +45,10 @@
 | 
			
		||||
#include <net/if_arp.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define container_of(p, st, field) (st*)((char*)(p) - offsetof(st, field))
 | 
			
		||||
 | 
			
		||||
#include "list.h"
 | 
			
		||||
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
@@ -273,7 +295,7 @@ static struct service *get_service(struct tp_info *tpi, uint16_t sid)
 | 
			
		||||
			return s;
 | 
			
		||||
	}
 | 
			
		||||
	s = calloc(1, sizeof(struct service));
 | 
			
		||||
	INIT_LIST_HEAD(&s->events);
 | 
			
		||||
	list_head_init(&s->events);
 | 
			
		||||
	s->sid = sid;
 | 
			
		||||
	snprintf(s->name, sizeof(s->name), "Service %d", sid);
 | 
			
		||||
	snprintf(s->pname, sizeof(s->name), "~");
 | 
			
		||||
@@ -662,7 +684,7 @@ uint32_t dvb_crc32(uint8_t *data, int len)
 | 
			
		||||
static void pid_info_init(struct pid_info *pidi, uint16_t pid, struct ts_info *tsi)
 | 
			
		||||
{
 | 
			
		||||
	memset(pidi, 0, sizeof(struct pid_info));
 | 
			
		||||
	INIT_LIST_HEAD(&pidi->sfilters);
 | 
			
		||||
	list_head_init(&pidi->sfilters);
 | 
			
		||||
	pidi->pid=pid;
 | 
			
		||||
	pidi->tsi=tsi;
 | 
			
		||||
}
 | 
			
		||||
@@ -728,7 +750,7 @@ int add_tp(struct scanip *sip, struct tp_info *tpi_new)
 | 
			
		||||
	memcpy(tpi, tpi_new, sizeof(struct tp_info));
 | 
			
		||||
	//fprintf(stderr, "added tp freq = %u\n", tpi->freq);
 | 
			
		||||
	list_add_tail(&tpi->link, &sip->tps);
 | 
			
		||||
	INIT_LIST_HEAD(&tpi->services);
 | 
			
		||||
	list_head_init(&tpi->services);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -779,8 +801,8 @@ void ts_info_init(struct ts_info *tsi)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	INIT_LIST_HEAD(&tsi->pids);
 | 
			
		||||
	INIT_LIST_HEAD(&tsi->sfilters);
 | 
			
		||||
	list_head_init(&tsi->pids);
 | 
			
		||||
	list_head_init(&tsi->sfilters);
 | 
			
		||||
	for (i=0; i<0x2000; i++)
 | 
			
		||||
		pid_info_init(&tsi->pidi[i], i, tsi);
 | 
			
		||||
}
 | 
			
		||||
@@ -1949,8 +1971,8 @@ void term_action(int sig, siginfo_t *si, void *d)
 | 
			
		||||
 | 
			
		||||
void scanip_init(struct scanip *sip, char *host)
 | 
			
		||||
{
 | 
			
		||||
	INIT_LIST_HEAD(&sip->tps);
 | 
			
		||||
	INIT_LIST_HEAD(&sip->tps_done);
 | 
			
		||||
	list_head_init(&sip->tps);
 | 
			
		||||
	list_head_init(&sip->tps_done);
 | 
			
		||||
	sip->done = 0;
 | 
			
		||||
	sip->host = host;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user