Add more list_xxx() functions to the LinuxKPI.
Obtained from: kmacy @ MFC after: 1 week Sponsored by: Mellanox Technologies
This commit is contained in:
parent
0f8f7f554b
commit
aad02fb444
@ -108,6 +108,13 @@ list_replace(struct list_head *old, struct list_head *new)
|
||||
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);
|
||||
}
|
||||
|
||||
static inline void
|
||||
linux_list_add(struct list_head *new, struct list_head *prev,
|
||||
struct list_head *next)
|
||||
@ -132,9 +139,18 @@ list_del_init(struct list_head *entry)
|
||||
#define list_first_entry(ptr, type, member) \
|
||||
list_entry((ptr)->next, type, member)
|
||||
|
||||
#define list_last_entry(ptr, type, member) \
|
||||
list_entry((ptr)->prev, type, member)
|
||||
|
||||
#define list_first_entry_or_null(ptr, type, member) \
|
||||
(!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
|
||||
|
||||
#define list_next_entry(ptr, member) \
|
||||
list_entry(((ptr)->member.next), typeof(*(ptr)), member)
|
||||
|
||||
#define list_prev_entry(ptr, member) \
|
||||
list_entry(((ptr)->member.prev), typeof(*(ptr)), member)
|
||||
|
||||
#define list_for_each(p, head) \
|
||||
for (p = (head)->next; p != (head); p = (p)->next)
|
||||
|
||||
@ -436,4 +452,7 @@ static inline int list_is_last(const struct list_head *list,
|
||||
(pos) && ({ n = (pos)->member.next; 1; }); \
|
||||
pos = hlist_entry_safe(n, typeof(*(pos)), member))
|
||||
|
||||
extern void list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv,
|
||||
struct list_head *a, struct list_head *b));
|
||||
|
||||
#endif /* _LINUX_LIST_H_ */
|
||||
|
@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <vm/vm_pager.h>
|
||||
|
||||
@ -1358,6 +1359,47 @@ unregister_inetaddr_notifier(struct notifier_block *nb)
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct list_sort_thunk {
|
||||
int (*cmp)(void *, struct list_head *, struct list_head *);
|
||||
void *priv;
|
||||
};
|
||||
|
||||
static inline int
|
||||
linux_le_cmp(void *priv, const void *d1, const void *d2)
|
||||
{
|
||||
struct list_head *le1, *le2;
|
||||
struct list_sort_thunk *thunk;
|
||||
|
||||
thunk = priv;
|
||||
le1 = *(__DECONST(struct list_head **, d1));
|
||||
le2 = *(__DECONST(struct list_head **, d2));
|
||||
return ((thunk->cmp)(thunk->priv, le1, le2));
|
||||
}
|
||||
|
||||
void
|
||||
list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv,
|
||||
struct list_head *a, struct list_head *b))
|
||||
{
|
||||
struct list_sort_thunk thunk;
|
||||
struct list_head **ar, *le;
|
||||
size_t count, i;
|
||||
|
||||
count = 0;
|
||||
list_for_each(le, head)
|
||||
count++;
|
||||
ar = malloc(sizeof(struct list_head *) * count, M_KMALLOC, M_WAITOK);
|
||||
i = 0;
|
||||
list_for_each(le, head)
|
||||
ar[i++] = le;
|
||||
thunk.cmp = cmp;
|
||||
thunk.priv = priv;
|
||||
qsort_r(ar, count, sizeof(struct list_head *), &thunk, linux_le_cmp);
|
||||
INIT_LIST_HEAD(head);
|
||||
for (i = 0; i < count; i++)
|
||||
list_add_tail(ar[i], head);
|
||||
free(ar, M_KMALLOC);
|
||||
}
|
||||
|
||||
void
|
||||
linux_irq_handler(void *ent)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user