13f012e29Smrg/* 23f012e29Smrg * 33f012e29Smrg * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. 43f012e29Smrg * All Rights Reserved. 53f012e29Smrg * 63f012e29Smrg * Permission is hereby granted, free of charge, to any person obtaining a 73f012e29Smrg * copy of this software and associated documentation files (the 83f012e29Smrg * "Software"), to deal in the Software without restriction, including 93f012e29Smrg * without limitation the rights to use, copy, modify, merge, publish, 103f012e29Smrg * distribute, sub license, and/or sell copies of the Software, and to 113f012e29Smrg * permit persons to whom the Software is furnished to do so, subject to 123f012e29Smrg * the following conditions: 133f012e29Smrg * 143f012e29Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 153f012e29Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 163f012e29Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 173f012e29Smrg * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 183f012e29Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 193f012e29Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 203f012e29Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 213f012e29Smrg * 223f012e29Smrg * The above copyright notice and this permission notice (including the 233f012e29Smrg * next paragraph) shall be included in all copies or substantial portions 243f012e29Smrg * of the Software. 253f012e29Smrg * 263f012e29Smrg */ 273f012e29Smrg 283f012e29Smrg/** 293f012e29Smrg * \file 303f012e29Smrg * List macros heavily inspired by the Linux kernel 313f012e29Smrg * list handling. No list looping yet. 323f012e29Smrg * 333f012e29Smrg * Is not threadsafe, so common operations need to 343f012e29Smrg * be protected using an external mutex. 353f012e29Smrg */ 363f012e29Smrg#ifndef _U_DOUBLE_LIST_H_ 373f012e29Smrg#define _U_DOUBLE_LIST_H_ 383f012e29Smrg 393f012e29Smrg#include <stddef.h> 403f012e29Smrg 413f012e29Smrgstruct list_head 423f012e29Smrg{ 433f012e29Smrg struct list_head *prev; 443f012e29Smrg struct list_head *next; 453f012e29Smrg}; 463f012e29Smrg 473f012e29Smrgstatic inline void list_inithead(struct list_head *item) 483f012e29Smrg{ 493f012e29Smrg item->prev = item; 503f012e29Smrg item->next = item; 513f012e29Smrg} 523f012e29Smrg 533f012e29Smrgstatic inline void list_add(struct list_head *item, struct list_head *list) 543f012e29Smrg{ 553f012e29Smrg item->prev = list; 563f012e29Smrg item->next = list->next; 573f012e29Smrg list->next->prev = item; 583f012e29Smrg list->next = item; 593f012e29Smrg} 603f012e29Smrg 613f012e29Smrgstatic inline void list_addtail(struct list_head *item, struct list_head *list) 623f012e29Smrg{ 633f012e29Smrg item->next = list; 643f012e29Smrg item->prev = list->prev; 653f012e29Smrg list->prev->next = item; 663f012e29Smrg list->prev = item; 673f012e29Smrg} 683f012e29Smrg 693f012e29Smrgstatic inline void list_replace(struct list_head *from, struct list_head *to) 703f012e29Smrg{ 713f012e29Smrg to->prev = from->prev; 723f012e29Smrg to->next = from->next; 733f012e29Smrg from->next->prev = to; 743f012e29Smrg from->prev->next = to; 753f012e29Smrg} 763f012e29Smrg 773f012e29Smrgstatic inline void list_del(struct list_head *item) 783f012e29Smrg{ 793f012e29Smrg item->prev->next = item->next; 803f012e29Smrg item->next->prev = item->prev; 813f012e29Smrg} 823f012e29Smrg 833f012e29Smrgstatic inline void list_delinit(struct list_head *item) 843f012e29Smrg{ 853f012e29Smrg item->prev->next = item->next; 863f012e29Smrg item->next->prev = item->prev; 873f012e29Smrg item->next = item; 883f012e29Smrg item->prev = item; 893f012e29Smrg} 903f012e29Smrg 913f012e29Smrg#define LIST_INITHEAD(__item) list_inithead(__item) 923f012e29Smrg#define LIST_ADD(__item, __list) list_add(__item, __list) 933f012e29Smrg#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list) 943f012e29Smrg#define LIST_REPLACE(__from, __to) list_replace(__from, __to) 953f012e29Smrg#define LIST_DEL(__item) list_del(__item) 963f012e29Smrg#define LIST_DELINIT(__item) list_delinit(__item) 973f012e29Smrg 983f012e29Smrg#define LIST_ENTRY(__type, __item, __field) \ 993f012e29Smrg ((__type *)(((char *)(__item)) - offsetof(__type, __field))) 1003f012e29Smrg 1013f012e29Smrg#define LIST_FIRST_ENTRY(__ptr, __type, __field) \ 1023f012e29Smrg LIST_ENTRY(__type, (__ptr)->next, __field) 1033f012e29Smrg 1043f012e29Smrg#define LIST_LAST_ENTRY(__ptr, __type, __field) \ 1053f012e29Smrg LIST_ENTRY(__type, (__ptr)->prev, __field) 1063f012e29Smrg 1073f012e29Smrg#define LIST_IS_EMPTY(__list) \ 1083f012e29Smrg ((__list)->next == (__list)) 1093f012e29Smrg 1103f012e29Smrg#ifndef container_of 1113f012e29Smrg#define container_of(ptr, sample, member) \ 1123f012e29Smrg (void *)((char *)(ptr) \ 11306a15751Schristos - ((char *)&((__typeof__(sample))0)->member)) 1143f012e29Smrg#endif 1153f012e29Smrg 1163f012e29Smrg#define LIST_FOR_EACH_ENTRY(pos, head, member) \ 1173f012e29Smrg for (pos = container_of((head)->next, pos, member); \ 1183f012e29Smrg &pos->member != (head); \ 1193f012e29Smrg pos = container_of(pos->member.next, pos, member)) 1203f012e29Smrg 1213f012e29Smrg#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \ 1223f012e29Smrg for (pos = container_of((head)->next, pos, member), \ 1233f012e29Smrg storage = container_of(pos->member.next, pos, member); \ 1243f012e29Smrg &pos->member != (head); \ 1253f012e29Smrg pos = storage, storage = container_of(storage->member.next, storage, member)) 1263f012e29Smrg 1273f012e29Smrg#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \ 1283f012e29Smrg for (pos = container_of((head)->prev, pos, member), \ 1293f012e29Smrg storage = container_of(pos->member.prev, pos, member); \ 1303f012e29Smrg &pos->member != (head); \ 1313f012e29Smrg pos = storage, storage = container_of(storage->member.prev, storage, member)) 1323f012e29Smrg 1333f012e29Smrg#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \ 1343f012e29Smrg for (pos = container_of((start), pos, member); \ 1353f012e29Smrg &pos->member != (head); \ 1363f012e29Smrg pos = container_of(pos->member.next, pos, member)) 1373f012e29Smrg 1383f012e29Smrg#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \ 1393f012e29Smrg for (pos = container_of((start), pos, member); \ 1403f012e29Smrg &pos->member != (head); \ 1413f012e29Smrg pos = container_of(pos->member.prev, pos, member)) 1423f012e29Smrg 1433f012e29Smrg#endif /*_U_DOUBLE_LIST_H_*/ 144