kernel-list.h revision 65f0aab98b20b5994a726ab90d355248bcddfffd
1311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifndef _LINUX_LIST_H 2311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define _LINUX_LIST_H 3311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 4311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/* 5311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Simple doubly linked list implementation. 6311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * 7311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Some of the internal functions ("__xxx") are useful when 8311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * manipulating whole lists rather than single entries, as 9311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * sometimes we already know the next/prev entries and we can 10311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * generate better code by using them directly rather than 11311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * using the generic single-entry routines. 12311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff */ 13311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 14311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstruct list_head { 15311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct list_head *next, *prev; 16311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}; 17311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 18311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define LIST_HEAD_INIT(name) { &(name), &(name) } 19311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 20311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define LIST_HEAD(name) \ 21311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct list_head name = { &name, &name } 22311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 23311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define INIT_LIST_HEAD(ptr) do { \ 24311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff (ptr)->next = (ptr); (ptr)->prev = (ptr); \ 25311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} while (0) 26311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 27311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#if (!defined(__GNUC__) && !defined(__WATCOMC__)) 28311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define __inline__ 29311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif 30311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 31311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/* 32311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Insert a new entry between two known consecutive entries. 33311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * 34311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * This is only for internal list manipulation where we know 35311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * the prev/next entries already! 36311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff */ 37311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ void __list_add(struct list_head * new, 38311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct list_head * prev, 39311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct list_head * next) 40311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{ 41311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff next->prev = new; 42311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff new->next = next; 43311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff new->prev = prev; 44311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff prev->next = new; 45311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 46732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com 47311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/* 48311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Insert a new entry after the specified head.. 49baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff */ 50baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiffstatic __inline__ void list_add(struct list_head *new, struct list_head *head) 51baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff{ 52baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff __list_add(new, head, head->next); 53baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff} 54baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff 55baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff/* 56732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com * Insert a new entry at the tail 57baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff */ 58baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiffstatic __inline__ void list_add_tail(struct list_head *new, struct list_head *head) 59311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{ 60311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff __list_add(new, head->prev, head); 61311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 62311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 63311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/* 64311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Delete a list entry by making the prev/next entries 65311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * point to each other. 66311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * 67311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * This is only for internal list manipulation where we know 68311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * the prev/next entries already! 69311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff */ 70311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ void __list_del(struct list_head * prev, 71311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct list_head * next) 72311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{ 73311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff next->prev = prev; 74311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff prev->next = next; 75311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 76311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 77311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ void list_del(struct list_head *entry) 78311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{ 79311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff __list_del(entry->prev, entry->next); 80311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 81311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 82311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ int list_empty(struct list_head *head) 83311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{ 84311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff return head->next == head; 85311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 86311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 87311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/* 88311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Splice in "list" into "head" 89311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff */ 90311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ void list_splice(struct list_head *list, struct list_head *head) 91311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{ 92311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct list_head *first = list->next; 93311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 94311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff if (first != list) { 95311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct list_head *last = list->prev; 96311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff struct list_head *at = head->next; 97311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 98311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff first->prev = head; 99311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff head->next = first; 100311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff 101311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff last->next = at; 102311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff at->prev = last; 103311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff } 104311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} 10528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 10628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#define list_entry(ptr, type, member) \ 10728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 10828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 10928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#define list_for_each(pos, head) \ 11028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff for (pos = (head)->next; pos != (head); pos = pos->next) 11128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff 112732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com#endif 11328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff