3 * Copyright (c) 2009, Microsoft Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
30 * Doubly-linked list manipulation routines. Implemented as macros
31 * but logically these are procedures.
35 typedef struct _LIST_ENTRY {
36 struct _LIST_ENTRY *Flink;
37 struct _LIST_ENTRY *Blink;
38 } LIST_ENTRY, *PLIST_ENTRY;
43 * PLIST_ENTRY ListHead
46 #define INITIALIZE_LIST_HEAD InitializeListHead
48 #define InitializeListHead(ListHead) (\
49 (ListHead)->Flink = (ListHead)->Blink = (ListHead))
55 * PLIST_ENTRY ListHead
58 #define IS_LIST_EMPTY IsListEmpty
60 #define IsListEmpty(ListHead) \
61 ((ListHead)->Flink == (ListHead))
70 #define NEXT_LIST_ENTRY NextListEntry
72 #define NextListEntry(Entry) \
82 #define PREV_LIST_ENTRY PrevListEntry
84 #define PrevListEntry(Entry) \
91 * PLIST_ENTRY ListHead
94 #define TOP_LIST_ENTRY TopListEntry
96 #define TopListEntry(ListHead) \
104 * PLIST_ENTRY ListHead
108 #define REMOVE_HEAD_LIST RemoveHeadList
110 #define RemoveHeadList(ListHead) \
112 {RemoveEntryList((ListHead)->Flink)}
118 * PLIST_ENTRY ListHead
121 #define REMOVE_TAIL_LIST RemoveTailList
123 #define RemoveTailList(ListHead) \
125 {RemoveEntryList((ListHead)->Blink)}
134 #define REMOVE_ENTRY_LIST RemoveEntryList
136 #define RemoveEntryList(Entry) {\
137 PLIST_ENTRY _EX_Flink = (Entry)->Flink;\
138 PLIST_ENTRY _EX_Blink = (Entry)->Blink;\
139 _EX_Blink->Flink = _EX_Flink;\
140 _EX_Flink->Blink = _EX_Blink;\
147 * PLIST_ENTRY ListHead,
148 * PLIST_ENTRY ListEntry
151 #define ATTACH_LIST AttachList
153 #define AttachList(ListHead,ListEntry) {\
154 PLIST_ENTRY _EX_ListHead = (ListHead);\
155 PLIST_ENTRY _EX_Blink = (ListHead)->Blink;\
156 (ListEntry)->Blink->Flink = _EX_ListHead;\
157 _EX_Blink->Flink = (ListEntry);\
158 _EX_ListHead->Blink = (ListEntry)->Blink;\
159 (ListEntry)->Blink = _EX_Blink;\
167 * PLIST_ENTRY ListHead,
172 #define INSERT_TAIL_LIST InsertTailList
174 #define InsertTailList(ListHead,Entry) {\
175 PLIST_ENTRY _EX_ListHead = (ListHead);\
176 PLIST_ENTRY _EX_Blink = (ListHead)->Blink;\
177 (Entry)->Flink = _EX_ListHead;\
178 (Entry)->Blink = _EX_Blink;\
179 _EX_Blink->Flink = (Entry);\
180 _EX_ListHead->Blink = (Entry);\
187 * PLIST_ENTRY ListHead,
191 #define INSERT_HEAD_LIST InsertHeadList
193 #define InsertHeadList(ListHead,Entry) {\
194 PLIST_ENTRY _EX_ListHead = (ListHead);\
195 PLIST_ENTRY _EX_Flink = (ListHead)->Flink;\
196 (Entry)->Flink = _EX_Flink;\
197 (Entry)->Blink = _EX_ListHead;\
198 _EX_Flink->Blink = (Entry);\
199 _EX_ListHead->Flink = (Entry);\
205 * IterateListEntries(
206 * PLIST_ENTRY anchor,
212 #define ITERATE_LIST_ENTRIES IterateListEntries
214 #define IterateListEntries(anchor, index, listp) \
215 (anchor) = (LIST_ENTRY *)(listp); \
216 for((index) = (anchor)->Flink; (index) != (anchor); (index) = (index)->Flink)
223 * PSINGLE_LIST_ENTRY ListHead
227 #define POP_ENTRY_LIST PopEntryList
229 #define PopEntryList(ListHead) \
232 PSINGLE_LIST_ENTRY FirstEntry;\
233 FirstEntry = (ListHead)->Next;\
234 if (FirstEntry != NULL) { \
235 (ListHead)->Next = FirstEntry->Next;\
244 * PSINGLE_LIST_ENTRY ListHead,
245 * PSINGLE_LIST_ENTRY Entry
249 #define PUSH_ENTRY_LIST PushEntryList
251 #define PushEntryList(ListHead,Entry) \
252 (Entry)->Next = (ListHead)->Next; \
253 (ListHead)->Next = (Entry)
255 #ifndef CONTAINING_RECORD
256 #define CONTAINING_RECORD(address, type, field) ((type *)( \
257 (char *)(address) - \
258 (char *)(&((type *)0)->field)))
259 #endif /* CONTAINING_RECORD */
261 #endif /* _LIST_H_ */