svn commit: r300496 - in head/sys/compat/linuxkpi/common: include/linux src

Conrad Meyer cem at FreeBSD.org
Mon May 23 19:03:50 UTC 2016


Didn't we already have list_sort in linuxkpi?  Maybe I'm confused.

On Mon, May 23, 2016 at 5:03 AM, Hans Petter Selasky
<hselasky at freebsd.org> wrote:
> Author: hselasky
> Date: Mon May 23 12:03:40 2016
> New Revision: 300496
> URL: https://svnweb.freebsd.org/changeset/base/300496
>
> Log:
>   Add more list_xxx() functions to the LinuxKPI.
>
>   Obtained from:        kmacy @
>   MFC after:    1 week
>   Sponsored by: Mellanox Technologies
>
> Modified:
>   head/sys/compat/linuxkpi/common/include/linux/list.h
>   head/sys/compat/linuxkpi/common/src/linux_compat.c
>
> Modified: head/sys/compat/linuxkpi/common/include/linux/list.h
> ==============================================================================
> --- head/sys/compat/linuxkpi/common/include/linux/list.h        Mon May 23 11:57:23 2016        (r300495)
> +++ head/sys/compat/linuxkpi/common/include/linux/list.h        Mon May 23 12:03:40 2016        (r300496)
> @@ -109,6 +109,13 @@ list_replace(struct list_head *old, stru
>  }
>
>  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 str
>              (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_ */
>
> Modified: head/sys/compat/linuxkpi/common/src/linux_compat.c
> ==============================================================================
> --- head/sys/compat/linuxkpi/common/src/linux_compat.c  Mon May 23 11:57:23 2016        (r300495)
> +++ head/sys/compat/linuxkpi/common/src/linux_compat.c  Mon May 23 12:03:40 2016        (r300496)
> @@ -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 noti
>          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)
>  {
>


More information about the svn-src-head mailing list