122944501Smrg/**************************************************************************
222944501Smrg *
322944501Smrg * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
422944501Smrg * All Rights Reserved.
522944501Smrg *
622944501Smrg * Permission is hereby granted, free of charge, to any person obtaining a
722944501Smrg * copy of this software and associated documentation files (the
822944501Smrg * "Software"), to deal in the Software without restriction, including
922944501Smrg * without limitation the rights to use, copy, modify, merge, publish,
1022944501Smrg * distribute, sub license, and/or sell copies of the Software, and to
1122944501Smrg * permit persons to whom the Software is furnished to do so, subject to
1222944501Smrg * the following conditions:
1322944501Smrg *
1422944501Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1522944501Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1622944501Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1722944501Smrg * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
1822944501Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
1922944501Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2022944501Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
2122944501Smrg *
2222944501Smrg * The above copyright notice and this permission notice (including the
2322944501Smrg * next paragraph) shall be included in all copies or substantial portions
2422944501Smrg * of the Software.
2522944501Smrg */
2622944501Smrg
2722944501Smrg/*
2822944501Smrg * List macros heavily inspired by the Linux kernel
2922944501Smrg * list handling. No list looping yet.
3022944501Smrg */
3122944501Smrg
3222944501Smrg#include <stddef.h>
3322944501Smrg
3422944501Smrgtypedef struct _drmMMListHead
3522944501Smrg{
3622944501Smrg    struct _drmMMListHead *prev;
3722944501Smrg    struct _drmMMListHead *next;
3822944501Smrg} drmMMListHead;
3922944501Smrg
4022944501Smrg#define DRMINITLISTHEAD(__item)		       \
4122944501Smrg  do{					       \
4222944501Smrg    (__item)->prev = (__item);		       \
4322944501Smrg    (__item)->next = (__item);		       \
4422944501Smrg  } while (0)
4522944501Smrg
4622944501Smrg#define DRMLISTADD(__item, __list)		\
4722944501Smrg  do {						\
4822944501Smrg    (__item)->prev = (__list);			\
4922944501Smrg    (__item)->next = (__list)->next;		\
5022944501Smrg    (__list)->next->prev = (__item);		\
5122944501Smrg    (__list)->next = (__item);			\
5222944501Smrg  } while (0)
5322944501Smrg
5422944501Smrg#define DRMLISTADDTAIL(__item, __list)		\
5522944501Smrg  do {						\
5622944501Smrg    (__item)->next = (__list);			\
5722944501Smrg    (__item)->prev = (__list)->prev;		\
5822944501Smrg    (__list)->prev->next = (__item);		\
5922944501Smrg    (__list)->prev = (__item);			\
6022944501Smrg  } while(0)
6122944501Smrg
6222944501Smrg#define DRMLISTDEL(__item)			\
6322944501Smrg  do {						\
6422944501Smrg    (__item)->prev->next = (__item)->next;	\
6522944501Smrg    (__item)->next->prev = (__item)->prev;	\
6622944501Smrg  } while(0)
6722944501Smrg
6822944501Smrg#define DRMLISTDELINIT(__item)			\
6922944501Smrg  do {						\
7022944501Smrg    (__item)->prev->next = (__item)->next;	\
7122944501Smrg    (__item)->next->prev = (__item)->prev;	\
7222944501Smrg    (__item)->next = (__item);			\
7322944501Smrg    (__item)->prev = (__item);			\
7422944501Smrg  } while(0)
7522944501Smrg
7622944501Smrg#define DRMLISTENTRY(__type, __item, __field)   \
7722944501Smrg    ((__type *)(((char *) (__item)) - offsetof(__type, __field)))
7822944501Smrg
7922944501Smrg#define DRMLISTEMPTY(__item) ((__item)->next == (__item))
8022944501Smrg
81e88f27b3Smrg#define DRMLISTSINGLE(__list) \
82e88f27b3Smrg	(!DRMLISTEMPTY(__list) && ((__list)->next == (__list)->prev))
83e88f27b3Smrg
84e88f27b3Smrg#define DRMLISTFOREACH(__item, __list)					\
85e88f27b3Smrg	for ((__item) = (__list)->next;					\
86e88f27b3Smrg	     (__item) != (__list); (__item) = (__item)->next)
87e88f27b3Smrg
8822944501Smrg#define DRMLISTFOREACHSAFE(__item, __temp, __list)			\
8922944501Smrg	for ((__item) = (__list)->next, (__temp) = (__item)->next;	\
9022944501Smrg	     (__item) != (__list);					\
9122944501Smrg	     (__item) = (__temp), (__temp) = (__item)->next)
9222944501Smrg
9322944501Smrg#define DRMLISTFOREACHSAFEREVERSE(__item, __temp, __list)		\
9422944501Smrg	for ((__item) = (__list)->prev, (__temp) = (__item)->prev;	\
9522944501Smrg	     (__item) != (__list);					\
9622944501Smrg	     (__item) = (__temp), (__temp) = (__item)->prev)
97e88f27b3Smrg
98e88f27b3Smrg#define DRMLISTFOREACHENTRY(__item, __list, __head)                            \
99af9aa065Schristos	for ((__item) = DRMLISTENTRY(__typeof__(*__item), (__list)->next, __head); \
10050027b5bSmrg	     &(__item)->__head != (__list);                                        \
101af9aa065Schristos	     (__item) = DRMLISTENTRY(__typeof__(*__item),                          \
10250027b5bSmrg	                             (__item)->__head.next, __head))
103e88f27b3Smrg
104e88f27b3Smrg#define DRMLISTFOREACHENTRYSAFE(__item, __temp, __list, __head)                \
105af9aa065Schristos	for ((__item) = DRMLISTENTRY(__typeof__(*__item), (__list)->next, __head), \
106af9aa065Schristos	     (__temp) = DRMLISTENTRY(__typeof__(*__item),                          \
10750027b5bSmrg	                             (__item)->__head.next, __head);               \
10850027b5bSmrg	     &(__item)->__head != (__list);                                        \
10950027b5bSmrg	     (__item) = (__temp),                                                  \
110af9aa065Schristos	     (__temp) = DRMLISTENTRY(__typeof__(*__item),                          \
11150027b5bSmrg	                             (__temp)->__head.next, __head))
112e88f27b3Smrg
113e88f27b3Smrg#define DRMLISTJOIN(__list, __join) if (!DRMLISTEMPTY(__list)) {	\
114e88f27b3Smrg	(__list)->next->prev = (__join);				\
115e88f27b3Smrg	(__list)->prev->next = (__join)->next;				\
116e88f27b3Smrg	(__join)->next->prev = (__list)->prev;				\
117e88f27b3Smrg	(__join)->next = (__list)->next;				\
118e88f27b3Smrg}
119