103b705cfSriastradh/* 203b705cfSriastradh * Copyright © 2010-2012 Intel Corporation 303b705cfSriastradh * Copyright © 2010 Francisco Jerez <currojerez@riseup.net> 403b705cfSriastradh * 503b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a 603b705cfSriastradh * copy of this software and associated documentation files (the "Software"), 703b705cfSriastradh * to deal in the Software without restriction, including without limitation 803b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 903b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the 1003b705cfSriastradh * Software is furnished to do so, subject to the following conditions: 1103b705cfSriastradh * 1203b705cfSriastradh * The above copyright notice and this permission notice (including the next 1303b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the 1403b705cfSriastradh * Software. 1503b705cfSriastradh * 1603b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1703b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1803b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1903b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2003b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2103b705cfSriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2203b705cfSriastradh * IN THE SOFTWARE. 2303b705cfSriastradh * 2403b705cfSriastradh */ 2503b705cfSriastradh 2603b705cfSriastradh#ifndef _INTEL_LIST_H_ 2703b705cfSriastradh#define _INTEL_LIST_H_ 2803b705cfSriastradh 2903b705cfSriastradh#include <xorgVersion.h> 3003b705cfSriastradh 3103b705cfSriastradh#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,9,0,0,0) || XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,11,99,903,0) 3203b705cfSriastradh 3303b705cfSriastradh#include <stdbool.h> 3403b705cfSriastradh 3503b705cfSriastradh/** 3603b705cfSriastradh * @file Classic doubly-link circular list implementation. 3703b705cfSriastradh * For real usage examples of the linked list, see the file test/list.c 3803b705cfSriastradh * 3903b705cfSriastradh * Example: 4003b705cfSriastradh * We need to keep a list of struct foo in the parent struct bar, i.e. what 4103b705cfSriastradh * we want is something like this. 4203b705cfSriastradh * 4303b705cfSriastradh * struct bar { 4403b705cfSriastradh * ... 4503b705cfSriastradh * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{} 4603b705cfSriastradh * ... 4703b705cfSriastradh * } 4803b705cfSriastradh * 4903b705cfSriastradh * We need one list head in bar and a list element in all list_of_foos (both are of 5003b705cfSriastradh * data type 'struct list'). 5103b705cfSriastradh * 5203b705cfSriastradh * struct bar { 5303b705cfSriastradh * ... 5403b705cfSriastradh * struct list list_of_foos; 5503b705cfSriastradh * ... 5603b705cfSriastradh * } 5703b705cfSriastradh * 5803b705cfSriastradh * struct foo { 5903b705cfSriastradh * ... 6003b705cfSriastradh * struct list entry; 6103b705cfSriastradh * ... 6203b705cfSriastradh * } 6303b705cfSriastradh * 6403b705cfSriastradh * Now we initialize the list head: 6503b705cfSriastradh * 6603b705cfSriastradh * struct bar bar; 6703b705cfSriastradh * ... 6803b705cfSriastradh * list_init(&bar.list_of_foos); 6903b705cfSriastradh * 7003b705cfSriastradh * Then we create the first element and add it to this list: 7103b705cfSriastradh * 7203b705cfSriastradh * struct foo *foo = malloc(...); 7303b705cfSriastradh * .... 7403b705cfSriastradh * list_add(&foo->entry, &bar.list_of_foos); 7503b705cfSriastradh * 7603b705cfSriastradh * Repeat the above for each element you want to add to the list. Deleting 7703b705cfSriastradh * works with the element itself. 7803b705cfSriastradh * list_del(&foo->entry); 7903b705cfSriastradh * free(foo); 8003b705cfSriastradh * 8103b705cfSriastradh * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty 8203b705cfSriastradh * list again. 8303b705cfSriastradh * 8403b705cfSriastradh * Looping through the list requires a 'struct foo' as iterator and the 8503b705cfSriastradh * name of the field the subnodes use. 8603b705cfSriastradh * 8703b705cfSriastradh * struct foo *iterator; 8803b705cfSriastradh * list_for_each_entry(iterator, &bar.list_of_foos, entry) { 8903b705cfSriastradh * if (iterator->something == ...) 9003b705cfSriastradh * ... 9103b705cfSriastradh * } 9203b705cfSriastradh * 9303b705cfSriastradh * Note: You must not call list_del() on the iterator if you continue the 9403b705cfSriastradh * loop. You need to run the safe for-each loop instead: 9503b705cfSriastradh * 9603b705cfSriastradh * struct foo *iterator, *next; 9703b705cfSriastradh * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) { 9803b705cfSriastradh * if (...) 9903b705cfSriastradh * list_del(&iterator->entry); 10003b705cfSriastradh * } 10103b705cfSriastradh * 10203b705cfSriastradh */ 10303b705cfSriastradh 10403b705cfSriastradh/** 10503b705cfSriastradh * The linkage struct for list nodes. This struct must be part of your 10603b705cfSriastradh * to-be-linked struct. struct list is required for both the head of the 10703b705cfSriastradh * list and for each list node. 10803b705cfSriastradh * 10903b705cfSriastradh * Position and name of the struct list field is irrelevant. 11003b705cfSriastradh * There are no requirements that elements of a list are of the same type. 11103b705cfSriastradh * There are no requirements for a list head, any struct list can be a list 11203b705cfSriastradh * head. 11303b705cfSriastradh */ 11403b705cfSriastradhstruct list { 11503b705cfSriastradh struct list *next, *prev; 11603b705cfSriastradh}; 11703b705cfSriastradh 11803b705cfSriastradh/** 11903b705cfSriastradh * Initialize the list as an empty list. 12003b705cfSriastradh * 12103b705cfSriastradh * Example: 12203b705cfSriastradh * list_init(&bar->list_of_foos); 12303b705cfSriastradh * 12403b705cfSriastradh * @param The list to initialized. 12503b705cfSriastradh */ 12603b705cfSriastradhstatic void 12703b705cfSriastradhlist_init(struct list *list) 12803b705cfSriastradh{ 12903b705cfSriastradh list->next = list->prev = list; 13003b705cfSriastradh} 13103b705cfSriastradh 13203b705cfSriastradhstatic inline void 13303b705cfSriastradh__list_add(struct list *entry, 13403b705cfSriastradh struct list *prev, 13503b705cfSriastradh struct list *next) 13603b705cfSriastradh{ 13703b705cfSriastradh next->prev = entry; 13803b705cfSriastradh entry->next = next; 13903b705cfSriastradh entry->prev = prev; 14003b705cfSriastradh prev->next = entry; 14103b705cfSriastradh} 14203b705cfSriastradh 14303b705cfSriastradh/** 14403b705cfSriastradh * Insert a new element after the given list head. The new element does not 14503b705cfSriastradh * need to be initialised as empty list. 14603b705cfSriastradh * The list changes from: 14703b705cfSriastradh * head → some element → ... 14803b705cfSriastradh * to 14903b705cfSriastradh * head → new element → older element → ... 15003b705cfSriastradh * 15103b705cfSriastradh * Example: 15203b705cfSriastradh * struct foo *newfoo = malloc(...); 15303b705cfSriastradh * list_add(&newfoo->entry, &bar->list_of_foos); 15403b705cfSriastradh * 15503b705cfSriastradh * @param entry The new element to prepend to the list. 15603b705cfSriastradh * @param head The existing list. 15703b705cfSriastradh */ 15803b705cfSriastradhstatic inline void 15903b705cfSriastradhlist_add(struct list *entry, struct list *head) 16003b705cfSriastradh{ 16103b705cfSriastradh __list_add(entry, head, head->next); 16203b705cfSriastradh} 16303b705cfSriastradh 16403b705cfSriastradhstatic inline void 16503b705cfSriastradhlist_add_tail(struct list *entry, struct list *head) 16603b705cfSriastradh{ 16703b705cfSriastradh __list_add(entry, head->prev, head); 16803b705cfSriastradh} 16903b705cfSriastradh 17003b705cfSriastradhstatic inline void list_replace(struct list *old, 17103b705cfSriastradh struct list *new) 17203b705cfSriastradh{ 17303b705cfSriastradh new->next = old->next; 17403b705cfSriastradh new->next->prev = new; 17503b705cfSriastradh new->prev = old->prev; 17603b705cfSriastradh new->prev->next = new; 17703b705cfSriastradh} 17803b705cfSriastradh 17903b705cfSriastradh#define list_last_entry(ptr, type, member) \ 18003b705cfSriastradh list_entry((ptr)->prev, type, member) 18103b705cfSriastradh 18203b705cfSriastradh#define list_for_each(pos, head) \ 18303b705cfSriastradh for (pos = (head)->next; pos != (head); pos = pos->next) 18403b705cfSriastradh 18503b705cfSriastradh/** 18603b705cfSriastradh * Append a new element to the end of the list given with this list head. 18703b705cfSriastradh * 18803b705cfSriastradh * The list changes from: 18903b705cfSriastradh * head → some element → ... → lastelement 19003b705cfSriastradh * to 19103b705cfSriastradh * head → some element → ... → lastelement → new element 19203b705cfSriastradh * 19303b705cfSriastradh * Example: 19403b705cfSriastradh * struct foo *newfoo = malloc(...); 19503b705cfSriastradh * list_append(&newfoo->entry, &bar->list_of_foos); 19603b705cfSriastradh * 19703b705cfSriastradh * @param entry The new element to prepend to the list. 19803b705cfSriastradh * @param head The existing list. 19903b705cfSriastradh */ 20003b705cfSriastradhstatic inline void 20103b705cfSriastradhlist_append(struct list *entry, struct list *head) 20203b705cfSriastradh{ 20303b705cfSriastradh __list_add(entry, head->prev, head); 20403b705cfSriastradh} 20503b705cfSriastradh 20603b705cfSriastradh 20703b705cfSriastradhstatic inline void 20803b705cfSriastradh__list_del(struct list *prev, struct list *next) 20903b705cfSriastradh{ 21003b705cfSriastradh assert(next->prev == prev->next); 21103b705cfSriastradh next->prev = prev; 21203b705cfSriastradh prev->next = next; 21303b705cfSriastradh} 21403b705cfSriastradh 21503b705cfSriastradhstatic inline void 21603b705cfSriastradh_list_del(struct list *entry) 21703b705cfSriastradh{ 21803b705cfSriastradh assert(entry->prev->next == entry); 21903b705cfSriastradh assert(entry->next->prev == entry); 22003b705cfSriastradh __list_del(entry->prev, entry->next); 22103b705cfSriastradh} 22203b705cfSriastradh 22303b705cfSriastradh/** 22403b705cfSriastradh * Remove the element from the list it is in. Using this function will reset 22503b705cfSriastradh * the pointers to/from this element so it is removed from the list. It does 22603b705cfSriastradh * NOT free the element itself or manipulate it otherwise. 22703b705cfSriastradh * 22803b705cfSriastradh * Using list_del on a pure list head (like in the example at the top of 22903b705cfSriastradh * this file) will NOT remove the first element from 23003b705cfSriastradh * the list but rather reset the list as empty list. 23103b705cfSriastradh * 23203b705cfSriastradh * Example: 23303b705cfSriastradh * list_del(&foo->entry); 23403b705cfSriastradh * 23503b705cfSriastradh * @param entry The element to remove. 23603b705cfSriastradh */ 23703b705cfSriastradhstatic inline void 23803b705cfSriastradhlist_del(struct list *entry) 23903b705cfSriastradh{ 24003b705cfSriastradh _list_del(entry); 24103b705cfSriastradh list_init(entry); 24203b705cfSriastradh} 24303b705cfSriastradh 24403b705cfSriastradhstatic inline void list_move(struct list *list, struct list *head) 24503b705cfSriastradh{ 24603b705cfSriastradh if (list->prev != head) { 24703b705cfSriastradh _list_del(list); 24803b705cfSriastradh list_add(list, head); 24903b705cfSriastradh } 25003b705cfSriastradh} 25103b705cfSriastradh 25203b705cfSriastradhstatic inline void list_move_tail(struct list *list, struct list *head) 25303b705cfSriastradh{ 25403b705cfSriastradh _list_del(list); 25503b705cfSriastradh list_add_tail(list, head); 25603b705cfSriastradh} 25703b705cfSriastradh 25803b705cfSriastradh/** 25903b705cfSriastradh * Check if the list is empty. 26003b705cfSriastradh * 26103b705cfSriastradh * Example: 26203b705cfSriastradh * list_is_empty(&bar->list_of_foos); 26303b705cfSriastradh * 26403b705cfSriastradh * @return True if the list contains one or more elements or False otherwise. 26503b705cfSriastradh */ 26603b705cfSriastradhstatic inline bool 26703b705cfSriastradhlist_is_empty(const struct list *head) 26803b705cfSriastradh{ 26903b705cfSriastradh return head->next == head; 27003b705cfSriastradh} 27103b705cfSriastradh 27203b705cfSriastradh/** 27303b705cfSriastradh * Alias of container_of 27403b705cfSriastradh */ 27503b705cfSriastradh#define list_entry(ptr, type, member) \ 27603b705cfSriastradh container_of(ptr, type, member) 27703b705cfSriastradh 27803b705cfSriastradh/** 27903b705cfSriastradh * Retrieve the first list entry for the given list pointer. 28003b705cfSriastradh * 28103b705cfSriastradh * Example: 28203b705cfSriastradh * struct foo *first; 28303b705cfSriastradh * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos); 28403b705cfSriastradh * 28503b705cfSriastradh * @param ptr The list head 28603b705cfSriastradh * @param type Data type of the list element to retrieve 28703b705cfSriastradh * @param member Member name of the struct list field in the list element. 28803b705cfSriastradh * @return A pointer to the first list element. 28903b705cfSriastradh */ 29003b705cfSriastradh#define list_first_entry(ptr, type, member) \ 29103b705cfSriastradh list_entry((ptr)->next, type, member) 29203b705cfSriastradh 29303b705cfSriastradh/** 29403b705cfSriastradh * Retrieve the last list entry for the given listpointer. 29503b705cfSriastradh * 29603b705cfSriastradh * Example: 29703b705cfSriastradh * struct foo *first; 29803b705cfSriastradh * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos); 29903b705cfSriastradh * 30003b705cfSriastradh * @param ptr The list head 30103b705cfSriastradh * @param type Data type of the list element to retrieve 30203b705cfSriastradh * @param member Member name of the struct list field in the list element. 30303b705cfSriastradh * @return A pointer to the last list element. 30403b705cfSriastradh */ 30503b705cfSriastradh#define list_last_entry(ptr, type, member) \ 30603b705cfSriastradh list_entry((ptr)->prev, type, member) 30703b705cfSriastradh 30863ef14f0Smrg#define __container_of(ptr, sample, member) \ 30963ef14f0Smrg (void *)((char *)(ptr) - ((char *)&(sample)->member - (char *)(sample))) 31003b705cfSriastradh/** 31103b705cfSriastradh * Loop through the list given by head and set pos to struct in the list. 31203b705cfSriastradh * 31303b705cfSriastradh * Example: 31403b705cfSriastradh * struct foo *iterator; 31503b705cfSriastradh * list_for_each_entry(iterator, &bar->list_of_foos, entry) { 31603b705cfSriastradh * [modify iterator] 31703b705cfSriastradh * } 31803b705cfSriastradh * 31903b705cfSriastradh * This macro is not safe for node deletion. Use list_for_each_entry_safe 32003b705cfSriastradh * instead. 32103b705cfSriastradh * 32203b705cfSriastradh * @param pos Iterator variable of the type of the list elements. 32303b705cfSriastradh * @param head List head 32403b705cfSriastradh * @param member Member name of the struct list in the list elements. 32503b705cfSriastradh * 32603b705cfSriastradh */ 32703b705cfSriastradh#define list_for_each_entry(pos, head, member) \ 3283d456b80Smrg for (pos = NULL, \ 3293d456b80Smrg pos = __container_of((head)->next, pos, member); \ 33003b705cfSriastradh &pos->member != (head); \ 33103b705cfSriastradh pos = __container_of(pos->member.next, pos, member)) 33203b705cfSriastradh 33303b705cfSriastradh#define list_for_each_entry_reverse(pos, head, member) \ 3343d456b80Smrg for (pos = NULL, \ 3353d456b80Smrg pos = __container_of((head)->prev, pos, member); \ 33603b705cfSriastradh &pos->member != (head); \ 33703b705cfSriastradh pos = __container_of(pos->member.prev, pos, member)) 33803b705cfSriastradh 33903b705cfSriastradh/** 34003b705cfSriastradh * Loop through the list, keeping a backup pointer to the element. This 34103b705cfSriastradh * macro allows for the deletion of a list element while looping through the 34203b705cfSriastradh * list. 34303b705cfSriastradh * 34403b705cfSriastradh * See list_for_each_entry for more details. 34503b705cfSriastradh */ 34603b705cfSriastradh#define list_for_each_entry_safe(pos, tmp, head, member) \ 3473d456b80Smrg for (pos = NULL, \ 3483d456b80Smrg pos = __container_of((head)->next, pos, member), \ 34903b705cfSriastradh tmp = __container_of(pos->member.next, pos, member); \ 35003b705cfSriastradh &pos->member != (head); \ 35103b705cfSriastradh pos = tmp, tmp = __container_of(pos->member.next, tmp, member)) 35203b705cfSriastradh 35303b705cfSriastradh#else 35403b705cfSriastradh 35503b705cfSriastradh#include <list.h> 35603b705cfSriastradh 35703b705cfSriastradhstatic inline void 35803b705cfSriastradhlist_add_tail(struct list *entry, struct list *head) 35903b705cfSriastradh{ 36003b705cfSriastradh __list_add(entry, head->prev, head); 36103b705cfSriastradh} 36203b705cfSriastradh 36303b705cfSriastradhstatic inline void 36403b705cfSriastradh_list_del(struct list *entry) 36503b705cfSriastradh{ 36603b705cfSriastradh assert(entry->prev->next == entry); 36703b705cfSriastradh assert(entry->next->prev == entry); 36803b705cfSriastradh __list_del(entry->prev, entry->next); 36903b705cfSriastradh} 37003b705cfSriastradh 37103b705cfSriastradhstatic inline void list_replace(struct list *old, 37203b705cfSriastradh struct list *new) 37303b705cfSriastradh{ 37403b705cfSriastradh new->next = old->next; 37503b705cfSriastradh new->next->prev = new; 37603b705cfSriastradh new->prev = old->prev; 37703b705cfSriastradh new->prev->next = new; 37803b705cfSriastradh} 37903b705cfSriastradh 38003b705cfSriastradhstatic inline void list_move(struct list *list, struct list *head) 38103b705cfSriastradh{ 38203b705cfSriastradh if (list->prev != head) { 38303b705cfSriastradh _list_del(list); 38403b705cfSriastradh list_add(list, head); 38503b705cfSriastradh } 38603b705cfSriastradh} 38703b705cfSriastradh 38803b705cfSriastradhstatic inline void list_move_tail(struct list *list, struct list *head) 38903b705cfSriastradh{ 39003b705cfSriastradh _list_del(list); 39103b705cfSriastradh list_add_tail(list, head); 39203b705cfSriastradh} 39303b705cfSriastradh 39403b705cfSriastradh#define list_last_entry(ptr, type, member) \ 39503b705cfSriastradh list_entry((ptr)->prev, type, member) 39603b705cfSriastradh 39763ef14f0Smrg#define list_for_each_entry_reverse(pos, head, member) \ 39803b705cfSriastradh for (pos = __container_of((head)->prev, pos, member); \ 39903b705cfSriastradh &pos->member != (head); \ 40003b705cfSriastradh pos = __container_of(pos->member.prev, pos, member)) 40103b705cfSriastradh 40203b705cfSriastradh#endif 40303b705cfSriastradh 40463ef14f0Smrg#define list_for_each_entry_safe_from(pos, tmp, head, member) \ 40563ef14f0Smrg for (tmp = __container_of(pos->member.next, pos, member); \ 40663ef14f0Smrg &pos->member != (head); \ 40763ef14f0Smrg pos = tmp, tmp = __container_of(tmp->member.next, tmp, member)) 40863ef14f0Smrg 40903b705cfSriastradh#undef container_of 41003b705cfSriastradh#define container_of(ptr, type, member) \ 41103b705cfSriastradh ((type *)((char *)(ptr) - (char *) &((type *)0)->member)) 41203b705cfSriastradh 41363ef14f0Smrgstatic inline void __list_splice(const struct list *list, 41463ef14f0Smrg struct list *prev, 41563ef14f0Smrg struct list *next) 41663ef14f0Smrg{ 41763ef14f0Smrg struct list *first = list->next; 41863ef14f0Smrg struct list *last = list->prev; 41963ef14f0Smrg 42063ef14f0Smrg first->prev = prev; 42163ef14f0Smrg prev->next = first; 42263ef14f0Smrg 42363ef14f0Smrg last->next = next; 42463ef14f0Smrg next->prev = last; 42563ef14f0Smrg} 42663ef14f0Smrg 42763ef14f0Smrgstatic inline void list_splice(const struct list *list, 42863ef14f0Smrg struct list *head) 42963ef14f0Smrg{ 43063ef14f0Smrg if (!list_is_empty(list)) 43163ef14f0Smrg __list_splice(list, head, head->next); 43263ef14f0Smrg} 43363ef14f0Smrg 43463ef14f0Smrgstatic inline void list_splice_tail(const struct list *list, 43563ef14f0Smrg struct list *head) 43663ef14f0Smrg{ 43763ef14f0Smrg if (!list_is_empty(list)) 43863ef14f0Smrg __list_splice(list, head->prev, head); 43963ef14f0Smrg} 44063ef14f0Smrg 44142542f5fSchristosstatic inline int list_is_singular(const struct list *list) 44242542f5fSchristos{ 44342542f5fSchristos return list->next == list->prev; 44442542f5fSchristos} 44542542f5fSchristos 44603b705cfSriastradh#endif /* _INTEL_LIST_H_ */ 44703b705cfSriastradh 448