1235783Skib/* 2235783Skib * Copyright (c) 2011 The FreeBSD Foundation 3235783Skib * All rights reserved. 4235783Skib * 5235783Skib * This software was developed by Konstantin Belousov under sponsorship from 6235783Skib * the FreeBSD Foundation. 7235783Skib * 8235783Skib * Redistribution and use in source and binary forms, with or without 9235783Skib * modification, are permitted provided that the following conditions 10235783Skib * are met: 11235783Skib * 1. Redistributions of source code must retain the above copyright 12235783Skib * notice, this list of conditions and the following disclaimer. 13235783Skib * 2. Redistributions in binary form must reproduce the above copyright 14235783Skib * notice, this list of conditions and the following disclaimer in the 15235783Skib * documentation and/or other materials provided with the distribution. 16235783Skib * 17235783Skib * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18235783Skib * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19235783Skib * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20235783Skib * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21235783Skib * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22235783Skib * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23235783Skib * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24235783Skib * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25235783Skib * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26235783Skib * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27235783Skib * SUCH DAMAGE. 28235783Skib */ 29235783Skib 30235783Skib#include <dev/drm2/drmP.h> 31235783Skib__FBSDID("$FreeBSD$"); 32235783Skib 33235783Skibstruct drm_list_sort_thunk { 34235783Skib int (*cmp)(void *, struct list_head *, struct list_head *); 35235783Skib void *priv; 36235783Skib}; 37235783Skib 38235783Skibstatic int 39235783Skibdrm_le_cmp(void *priv, const void *d1, const void *d2) 40235783Skib{ 41235783Skib struct list_head *le1, *le2; 42235783Skib struct drm_list_sort_thunk *thunk; 43235783Skib 44235783Skib thunk = priv; 45258707Sdumbbell le1 = *(__DECONST(struct list_head **, d1)); 46258707Sdumbbell le2 = *(__DECONST(struct list_head **, d2)); 47235783Skib return ((thunk->cmp)(thunk->priv, le1, le2)); 48235783Skib} 49235783Skib 50235783Skib/* 51235783Skib * Punt and use array sort. 52235783Skib */ 53235783Skibvoid 54235783Skibdrm_list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, 55235783Skib struct list_head *a, struct list_head *b)) 56235783Skib{ 57235783Skib struct drm_list_sort_thunk thunk; 58235783Skib struct list_head **ar, *le; 59235783Skib int count, i; 60235783Skib 61235783Skib count = 0; 62235783Skib list_for_each(le, head) 63235783Skib count++; 64235783Skib ar = malloc(sizeof(struct list_head *) * count, M_TEMP, M_WAITOK); 65235783Skib i = 0; 66235783Skib list_for_each(le, head) 67235783Skib ar[i++] = le; 68235783Skib thunk.cmp = cmp; 69235783Skib thunk.priv = priv; 70235783Skib qsort_r(ar, count, sizeof(struct list_head *), &thunk, drm_le_cmp); 71235783Skib INIT_LIST_HEAD(head); 72235783Skib for (i = 0; i < count; i++) 73235783Skib list_add_tail(ar[i], head); 74235783Skib free(ar, M_TEMP); 75235783Skib} 76