blob: 94512e306d8cbf6bfcc2063b222a1f2b65302e83 [file] [log] [blame]
#ifndef __LIST_H
#define __LIST_H
#include "types.h" // container_of
/****************************************************************
* hlist - Double linked lists with a single pointer list head
****************************************************************/
struct hlist_node {
struct hlist_node *next, **pprev;
};
struct hlist_head {
struct hlist_node *first;
};
static inline int
hlist_empty(const struct hlist_head *h)
{
return !h->first;
}
static inline void
hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;
*pprev = next;
if (next)
next->pprev = pprev;
}
static inline void
hlist_add(struct hlist_node *n, struct hlist_node **pprev)
{
struct hlist_node *next = *pprev;
n->pprev = pprev;
n->next = next;
if (next)
next->pprev = &n->next;
*pprev = n;
}
static inline void
hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
hlist_add(n, &h->first);
}
static inline void
hlist_add_before(struct hlist_node *n, struct hlist_node *next)
{
hlist_add(n, next->pprev);
}
static inline void
hlist_add_after(struct hlist_node *n, struct hlist_node *prev)
{
hlist_add(n, &prev->next);
}
static inline void
hlist_replace(struct hlist_node *old, struct hlist_node *new)
{
new->next = old->next;
if (new->next)
new->next->pprev = &new->next;
new->pprev = old->pprev;
*new->pprev = new;
}
#define hlist_for_each_entry(pos, head, member) \
for (pos = container_of((head)->first, typeof(*pos), member) \
; pos != container_of(NULL, typeof(*pos), member) \
; pos = container_of(pos->member.next, typeof(*pos), member))
#define hlist_for_each_entry_safe(pos, n, head, member) \
for (pos = container_of((head)->first, typeof(*pos), member) \
; pos != container_of(NULL, typeof(*pos), member) \
&& ({ n = pos->member.next; 1; }) \
; pos = container_of(n, typeof(*pos), member))
#define hlist_for_each_entry_pprev(pos, pprev, head, member) \
for (pprev = &(head)->first \
; *pprev && ({ pos=container_of(*pprev, typeof(*pos), member); 1; }) \
; pprev = &(*pprev)->next)
#endif // list.h