gdunlap/sched-sim.hg

annotate list.h @ 7:e274ac3f81ff

c01: Allow wake to preempt running processes
author George Dunlap <gdunlap@xensource.com>
date Tue Oct 20 18:00:17 2009 +0100 (2009-10-20)
parents d27bb3c56e71
children
rev   line source
gdunlap@0 1 /******************************************************************************
gdunlap@0 2 * list.h
gdunlap@0 3 *
gdunlap@0 4 * Useful linked-list definitions taken from the Linux kernel (2.6.18).
gdunlap@0 5 */
gdunlap@0 6
gdunlap@0 7 #ifndef __XEN_LIST_H__
gdunlap@0 8 #define __XEN_LIST_H__
gdunlap@0 9
gdunlap@0 10 #if __GNUC__ > 3
gdunlap@0 11 #define offsetof(a,b) __builtin_offsetof(a,b)
gdunlap@0 12 #else
gdunlap@0 13 #define offsetof(a,b) ((unsigned long)&(((a *)0)->b))
gdunlap@0 14 #endif
gdunlap@0 15
gdunlap@0 16 /**
gdunlap@0 17 * container_of - cast a member of a structure out to the containing structure
gdunlap@0 18 *
gdunlap@0 19 * @ptr: the pointer to the member.
gdunlap@0 20 * @type: the type of the container struct this is embedded in.
gdunlap@0 21 * @member: the name of the member within the struct.
gdunlap@0 22 *
gdunlap@0 23 */
gdunlap@0 24 #define container_of(ptr, type, member) ({ \
gdunlap@0 25 typeof( ((type *)0)->member ) *__mptr = (ptr); \
gdunlap@0 26 (type *)( (char *)__mptr - offsetof(type,member) );})
gdunlap@0 27
gdunlap@0 28 #define prefetch(_x) (_x)
gdunlap@0 29
gdunlap@0 30 /* These are non-NULL pointers that will result in page faults
gdunlap@0 31 * under normal circumstances, used to verify that nobody uses
gdunlap@0 32 * non-initialized list entries.
gdunlap@0 33 */
gdunlap@0 34 #define LIST_POISON1 ((void *) 0x00100100)
gdunlap@0 35 #define LIST_POISON2 ((void *) 0x00200200)
gdunlap@0 36
gdunlap@0 37 /*
gdunlap@0 38 * Simple doubly linked list implementation.
gdunlap@0 39 *
gdunlap@0 40 * Some of the internal functions ("__xxx") are useful when
gdunlap@0 41 * manipulating whole lists rather than single entries, as
gdunlap@0 42 * sometimes we already know the next/prev entries and we can
gdunlap@0 43 * generate better code by using them directly rather than
gdunlap@0 44 * using the generic single-entry routines.
gdunlap@0 45 */
gdunlap@0 46
gdunlap@0 47 struct list_head {
gdunlap@0 48 struct list_head *next, *prev;
gdunlap@0 49 };
gdunlap@0 50
gdunlap@0 51 #define LIST_HEAD_INIT(name) { &(name), &(name) }
gdunlap@0 52
gdunlap@0 53 #define LIST_HEAD(name) \
gdunlap@0 54 struct list_head name = LIST_HEAD_INIT(name)
gdunlap@0 55
gdunlap@0 56 static inline void INIT_LIST_HEAD(struct list_head *list)
gdunlap@0 57 {
gdunlap@0 58 list->next = list;
gdunlap@0 59 list->prev = list;
gdunlap@0 60 }
gdunlap@0 61
gdunlap@0 62 /*
gdunlap@0 63 * Insert a new entry between two known consecutive entries.
gdunlap@0 64 *
gdunlap@0 65 * This is only for internal list manipulation where we know
gdunlap@0 66 * the prev/next entries already!
gdunlap@0 67 */
gdunlap@0 68 static inline void __list_add(struct list_head *new,
gdunlap@0 69 struct list_head *prev,
gdunlap@0 70 struct list_head *next)
gdunlap@0 71 {
gdunlap@0 72 next->prev = new;
gdunlap@0 73 new->next = next;
gdunlap@0 74 new->prev = prev;
gdunlap@0 75 prev->next = new;
gdunlap@0 76 }
gdunlap@0 77
gdunlap@0 78 /**
gdunlap@0 79 * list_add - add a new entry
gdunlap@0 80 * @new: new entry to be added
gdunlap@0 81 * @head: list head to add it after
gdunlap@0 82 *
gdunlap@0 83 * Insert a new entry after the specified head.
gdunlap@0 84 * This is good for implementing stacks.
gdunlap@0 85 */
gdunlap@0 86 static inline void list_add(struct list_head *new, struct list_head *head)
gdunlap@0 87 {
gdunlap@0 88 __list_add(new, head, head->next);
gdunlap@0 89 }
gdunlap@0 90
gdunlap@0 91 /**
gdunlap@0 92 * list_add_tail - add a new entry
gdunlap@0 93 * @new: new entry to be added
gdunlap@0 94 * @head: list head to add it before
gdunlap@0 95 *
gdunlap@0 96 * Insert a new entry before the specified head.
gdunlap@0 97 * This is useful for implementing queues.
gdunlap@0 98 */
gdunlap@0 99 static inline void list_add_tail(struct list_head *new, struct list_head *head)
gdunlap@0 100 {
gdunlap@0 101 __list_add(new, head->prev, head);
gdunlap@0 102 }
gdunlap@0 103
gdunlap@0 104 /*
gdunlap@0 105 * Insert a new entry between two known consecutive entries.
gdunlap@0 106 *
gdunlap@0 107 * This is only for internal list manipulation where we know
gdunlap@0 108 * the prev/next entries already!
gdunlap@0 109 */
gdunlap@0 110 static inline void __list_add_rcu(struct list_head *new,
gdunlap@0 111 struct list_head *prev,
gdunlap@0 112 struct list_head *next)
gdunlap@0 113 {
gdunlap@0 114 new->next = next;
gdunlap@0 115 new->prev = prev;
gdunlap@0 116 next->prev = new;
gdunlap@0 117 prev->next = new;
gdunlap@0 118 }
gdunlap@0 119
gdunlap@0 120 /**
gdunlap@0 121 * list_add_rcu - add a new entry to rcu-protected list
gdunlap@0 122 * @new: new entry to be added
gdunlap@0 123 * @head: list head to add it after
gdunlap@0 124 *
gdunlap@0 125 * Insert a new entry after the specified head.
gdunlap@0 126 * This is good for implementing stacks.
gdunlap@0 127 *
gdunlap@0 128 * The caller must take whatever precautions are necessary
gdunlap@0 129 * (such as holding appropriate locks) to avoid racing
gdunlap@0 130 * with another list-mutation primitive, such as list_add_rcu()
gdunlap@0 131 * or list_del_rcu(), running on this same list.
gdunlap@0 132 * However, it is perfectly legal to run concurrently with
gdunlap@0 133 * the _rcu list-traversal primitives, such as
gdunlap@0 134 * list_for_each_entry_rcu().
gdunlap@0 135 */
gdunlap@0 136 static inline void list_add_rcu(struct list_head *new, struct list_head *head)
gdunlap@0 137 {
gdunlap@0 138 __list_add_rcu(new, head, head->next);
gdunlap@0 139 }
gdunlap@0 140
gdunlap@0 141 /**
gdunlap@0 142 * list_add_tail_rcu - add a new entry to rcu-protected list
gdunlap@0 143 * @new: new entry to be added
gdunlap@0 144 * @head: list head to add it before
gdunlap@0 145 *
gdunlap@0 146 * Insert a new entry before the specified head.
gdunlap@0 147 * This is useful for implementing queues.
gdunlap@0 148 *
gdunlap@0 149 * The caller must take whatever precautions are necessary
gdunlap@0 150 * (such as holding appropriate locks) to avoid racing
gdunlap@0 151 * with another list-mutation primitive, such as list_add_tail_rcu()
gdunlap@0 152 * or list_del_rcu(), running on this same list.
gdunlap@0 153 * However, it is perfectly legal to run concurrently with
gdunlap@0 154 * the _rcu list-traversal primitives, such as
gdunlap@0 155 * list_for_each_entry_rcu().
gdunlap@0 156 */
gdunlap@0 157 static inline void list_add_tail_rcu(struct list_head *new,
gdunlap@0 158 struct list_head *head)
gdunlap@0 159 {
gdunlap@0 160 __list_add_rcu(new, head->prev, head);
gdunlap@0 161 }
gdunlap@0 162
gdunlap@0 163 /*
gdunlap@0 164 * Delete a list entry by making the prev/next entries
gdunlap@0 165 * point to each other.
gdunlap@0 166 *
gdunlap@0 167 * This is only for internal list manipulation where we know
gdunlap@0 168 * the prev/next entries already!
gdunlap@0 169 */
gdunlap@0 170 static inline void __list_del(struct list_head *prev,
gdunlap@0 171 struct list_head *next)
gdunlap@0 172 {
gdunlap@0 173 next->prev = prev;
gdunlap@0 174 prev->next = next;
gdunlap@0 175 }
gdunlap@0 176
gdunlap@0 177 /**
gdunlap@0 178 * list_del - deletes entry from list.
gdunlap@0 179 * @entry: the element to delete from the list.
gdunlap@0 180 * Note: list_empty on entry does not return true after this, the entry is
gdunlap@0 181 * in an undefined state.
gdunlap@0 182 */
gdunlap@0 183 static inline void list_del(struct list_head *entry)
gdunlap@0 184 {
gdunlap@0 185 ASSERT(entry->next->prev == entry);
gdunlap@0 186 ASSERT(entry->prev->next == entry);
gdunlap@0 187 __list_del(entry->prev, entry->next);
gdunlap@0 188 entry->next = LIST_POISON1;
gdunlap@0 189 entry->prev = LIST_POISON2;
gdunlap@0 190 }
gdunlap@0 191
gdunlap@0 192 /**
gdunlap@0 193 * list_del_rcu - deletes entry from list without re-initialization
gdunlap@0 194 * @entry: the element to delete from the list.
gdunlap@0 195 *
gdunlap@0 196 * Note: list_empty on entry does not return true after this,
gdunlap@0 197 * the entry is in an undefined state. It is useful for RCU based
gdunlap@0 198 * lockfree traversal.
gdunlap@0 199 *
gdunlap@0 200 * In particular, it means that we can not poison the forward
gdunlap@0 201 * pointers that may still be used for walking the list.
gdunlap@0 202 *
gdunlap@0 203 * The caller must take whatever precautions are necessary
gdunlap@0 204 * (such as holding appropriate locks) to avoid racing
gdunlap@0 205 * with another list-mutation primitive, such as list_del_rcu()
gdunlap@0 206 * or list_add_rcu(), running on this same list.
gdunlap@0 207 * However, it is perfectly legal to run concurrently with
gdunlap@0 208 * the _rcu list-traversal primitives, such as
gdunlap@0 209 * list_for_each_entry_rcu().
gdunlap@0 210 *
gdunlap@0 211 * Note that the caller is not permitted to immediately free
gdunlap@0 212 * the newly deleted entry. Instead, either synchronize_rcu()
gdunlap@0 213 * or call_rcu() must be used to defer freeing until an RCU
gdunlap@0 214 * grace period has elapsed.
gdunlap@0 215 */
gdunlap@0 216 static inline void list_del_rcu(struct list_head *entry)
gdunlap@0 217 {
gdunlap@0 218 __list_del(entry->prev, entry->next);
gdunlap@0 219 entry->prev = LIST_POISON2;
gdunlap@0 220 }
gdunlap@0 221
gdunlap@0 222 /**
gdunlap@0 223 * list_replace - replace old entry by new one
gdunlap@0 224 * @old : the element to be replaced
gdunlap@0 225 * @new : the new element to insert
gdunlap@0 226 * Note: if 'old' was empty, it will be overwritten.
gdunlap@0 227 */
gdunlap@0 228 static inline void list_replace(struct list_head *old,
gdunlap@0 229 struct list_head *new)
gdunlap@0 230 {
gdunlap@0 231 new->next = old->next;
gdunlap@0 232 new->next->prev = new;
gdunlap@0 233 new->prev = old->prev;
gdunlap@0 234 new->prev->next = new;
gdunlap@0 235 }
gdunlap@0 236
gdunlap@0 237 static inline void list_replace_init(struct list_head *old,
gdunlap@0 238 struct list_head *new)
gdunlap@0 239 {
gdunlap@0 240 list_replace(old, new);
gdunlap@0 241 INIT_LIST_HEAD(old);
gdunlap@0 242 }
gdunlap@0 243
gdunlap@0 244 /*
gdunlap@0 245 * list_replace_rcu - replace old entry by new one
gdunlap@0 246 * @old : the element to be replaced
gdunlap@0 247 * @new : the new element to insert
gdunlap@0 248 *
gdunlap@0 249 * The old entry will be replaced with the new entry atomically.
gdunlap@0 250 * Note: 'old' should not be empty.
gdunlap@0 251 */
gdunlap@0 252 static inline void list_replace_rcu(struct list_head *old,
gdunlap@0 253 struct list_head *new)
gdunlap@0 254 {
gdunlap@0 255 new->next = old->next;
gdunlap@0 256 new->prev = old->prev;
gdunlap@0 257 new->next->prev = new;
gdunlap@0 258 new->prev->next = new;
gdunlap@0 259 old->prev = LIST_POISON2;
gdunlap@0 260 }
gdunlap@0 261
gdunlap@0 262 /**
gdunlap@0 263 * list_del_init - deletes entry from list and reinitialize it.
gdunlap@0 264 * @entry: the element to delete from the list.
gdunlap@0 265 */
gdunlap@0 266 static inline void list_del_init(struct list_head *entry)
gdunlap@0 267 {
gdunlap@0 268 __list_del(entry->prev, entry->next);
gdunlap@0 269 INIT_LIST_HEAD(entry);
gdunlap@0 270 }
gdunlap@0 271
gdunlap@0 272 /**
gdunlap@0 273 * list_move - delete from one list and add as another's head
gdunlap@0 274 * @list: the entry to move
gdunlap@0 275 * @head: the head that will precede our entry
gdunlap@0 276 */
gdunlap@0 277 static inline void list_move(struct list_head *list, struct list_head *head)
gdunlap@0 278 {
gdunlap@0 279 __list_del(list->prev, list->next);
gdunlap@0 280 list_add(list, head);
gdunlap@0 281 }
gdunlap@0 282
gdunlap@0 283 /**
gdunlap@0 284 * list_move_tail - delete from one list and add as another's tail
gdunlap@0 285 * @list: the entry to move
gdunlap@0 286 * @head: the head that will follow our entry
gdunlap@0 287 */
gdunlap@0 288 static inline void list_move_tail(struct list_head *list,
gdunlap@0 289 struct list_head *head)
gdunlap@0 290 {
gdunlap@0 291 __list_del(list->prev, list->next);
gdunlap@0 292 list_add_tail(list, head);
gdunlap@0 293 }
gdunlap@0 294
gdunlap@0 295 /**
gdunlap@0 296 * list_is_last - tests whether @list is the last entry in list @head
gdunlap@0 297 * @list: the entry to test
gdunlap@0 298 * @head: the head of the list
gdunlap@0 299 */
gdunlap@0 300 static inline int list_is_last(const struct list_head *list,
gdunlap@0 301 const struct list_head *head)
gdunlap@0 302 {
gdunlap@0 303 return list->next == head;
gdunlap@0 304 }
gdunlap@0 305
gdunlap@0 306 /**
gdunlap@0 307 * list_empty - tests whether a list is empty
gdunlap@0 308 * @head: the list to test.
gdunlap@0 309 */
gdunlap@0 310 static inline int list_empty(const struct list_head *head)
gdunlap@0 311 {
gdunlap@0 312 return head->next == head;
gdunlap@0 313 }
gdunlap@0 314
gdunlap@0 315 /**
gdunlap@0 316 * list_empty_careful - tests whether a list is empty and not being modified
gdunlap@0 317 * @head: the list to test
gdunlap@0 318 *
gdunlap@0 319 * Description:
gdunlap@0 320 * tests whether a list is empty _and_ checks that no other CPU might be
gdunlap@0 321 * in the process of modifying either member (next or prev)
gdunlap@0 322 *
gdunlap@0 323 * NOTE: using list_empty_careful() without synchronization
gdunlap@0 324 * can only be safe if the only activity that can happen
gdunlap@0 325 * to the list entry is list_del_init(). Eg. it cannot be used
gdunlap@0 326 * if another CPU could re-list_add() it.
gdunlap@0 327 */
gdunlap@0 328 static inline int list_empty_careful(const struct list_head *head)
gdunlap@0 329 {
gdunlap@0 330 struct list_head *next = head->next;
gdunlap@0 331 return (next == head) && (next == head->prev);
gdunlap@0 332 }
gdunlap@0 333
gdunlap@0 334 static inline void __list_splice(struct list_head *list,
gdunlap@0 335 struct list_head *head)
gdunlap@0 336 {
gdunlap@0 337 struct list_head *first = list->next;
gdunlap@0 338 struct list_head *last = list->prev;
gdunlap@0 339 struct list_head *at = head->next;
gdunlap@0 340
gdunlap@0 341 first->prev = head;
gdunlap@0 342 head->next = first;
gdunlap@0 343
gdunlap@0 344 last->next = at;
gdunlap@0 345 at->prev = last;
gdunlap@0 346 }
gdunlap@0 347
gdunlap@0 348 /**
gdunlap@0 349 * list_splice - join two lists
gdunlap@0 350 * @list: the new list to add.
gdunlap@0 351 * @head: the place to add it in the first list.
gdunlap@0 352 */
gdunlap@0 353 static inline void list_splice(struct list_head *list, struct list_head *head)
gdunlap@0 354 {
gdunlap@0 355 if (!list_empty(list))
gdunlap@0 356 __list_splice(list, head);
gdunlap@0 357 }
gdunlap@0 358
gdunlap@0 359 /**
gdunlap@0 360 * list_splice_init - join two lists and reinitialise the emptied list.
gdunlap@0 361 * @list: the new list to add.
gdunlap@0 362 * @head: the place to add it in the first list.
gdunlap@0 363 *
gdunlap@0 364 * The list at @list is reinitialised
gdunlap@0 365 */
gdunlap@0 366 static inline void list_splice_init(struct list_head *list,
gdunlap@0 367 struct list_head *head)
gdunlap@0 368 {
gdunlap@0 369 if (!list_empty(list)) {
gdunlap@0 370 __list_splice(list, head);
gdunlap@0 371 INIT_LIST_HEAD(list);
gdunlap@0 372 }
gdunlap@0 373 }
gdunlap@0 374
gdunlap@0 375 /**
gdunlap@0 376 * list_entry - get the struct for this entry
gdunlap@0 377 * @ptr: the &struct list_head pointer.
gdunlap@0 378 * @type: the type of the struct this is embedded in.
gdunlap@0 379 * @member: the name of the list_struct within the struct.
gdunlap@0 380 */
gdunlap@0 381 #define list_entry(ptr, type, member) \
gdunlap@0 382 container_of(ptr, type, member)
gdunlap@0 383
gdunlap@0 384 /**
gdunlap@0 385 * list_for_each - iterate over a list
gdunlap@0 386 * @pos: the &struct list_head to use as a loop cursor.
gdunlap@0 387 * @head: the head for your list.
gdunlap@0 388 */
gdunlap@0 389 #define list_for_each(pos, head) \
gdunlap@0 390 for (pos = (head)->next; prefetch(pos->next), pos != (head); \
gdunlap@0 391 pos = pos->next)
gdunlap@0 392
gdunlap@0 393 /**
gdunlap@0 394 * __list_for_each - iterate over a list
gdunlap@0 395 * @pos: the &struct list_head to use as a loop cursor.
gdunlap@0 396 * @head: the head for your list.
gdunlap@0 397 *
gdunlap@0 398 * This variant differs from list_for_each() in that it's the
gdunlap@0 399 * simplest possible list iteration code, no prefetching is done.
gdunlap@0 400 * Use this for code that knows the list to be very short (empty
gdunlap@0 401 * or 1 entry) most of the time.
gdunlap@0 402 */
gdunlap@0 403 #define __list_for_each(pos, head) \
gdunlap@0 404 for (pos = (head)->next; pos != (head); pos = pos->next)
gdunlap@0 405
gdunlap@0 406 /**
gdunlap@0 407 * list_for_each_prev - iterate over a list backwards
gdunlap@0 408 * @pos: the &struct list_head to use as a loop cursor.
gdunlap@0 409 * @head: the head for your list.
gdunlap@0 410 */
gdunlap@0 411 #define list_for_each_prev(pos, head) \
gdunlap@0 412 for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
gdunlap@0 413 pos = pos->prev)
gdunlap@0 414
gdunlap@0 415 /**
gdunlap@0 416 * list_for_each_safe - iterate over a list safe against removal of list entry
gdunlap@0 417 * @pos: the &struct list_head to use as a loop cursor.
gdunlap@0 418 * @n: another &struct list_head to use as temporary storage
gdunlap@0 419 * @head: the head for your list.
gdunlap@0 420 */
gdunlap@0 421 #define list_for_each_safe(pos, n, head) \
gdunlap@0 422 for (pos = (head)->next, n = pos->next; pos != (head); \
gdunlap@0 423 pos = n, n = pos->next)
gdunlap@0 424
gdunlap@0 425 /**
gdunlap@0 426 * list_for_each_backwards_safe - iterate backwards over a list safe
gdunlap@0 427 * against removal of list entry
gdunlap@0 428 * @pos: the &struct list_head to use as a loop counter.
gdunlap@0 429 * @n: another &struct list_head to use as temporary storage
gdunlap@0 430 * @head: the head for your list.
gdunlap@0 431 */
gdunlap@0 432 #define list_for_each_backwards_safe(pos, n, head) \
gdunlap@0 433 for ( pos = (head)->prev, n = pos->prev; pos != (head); \
gdunlap@0 434 pos = n, n = pos->prev )
gdunlap@0 435
gdunlap@0 436 /**
gdunlap@0 437 * list_for_each_entry - iterate over list of given type
gdunlap@0 438 * @pos: the type * to use as a loop cursor.
gdunlap@0 439 * @head: the head for your list.
gdunlap@0 440 * @member: the name of the list_struct within the struct.
gdunlap@0 441 */
gdunlap@0 442 #define list_for_each_entry(pos, head, member) \
gdunlap@0 443 for (pos = list_entry((head)->next, typeof(*pos), member); \
gdunlap@0 444 prefetch(pos->member.next), &pos->member != (head); \
gdunlap@0 445 pos = list_entry(pos->member.next, typeof(*pos), member))
gdunlap@0 446
gdunlap@0 447 /**
gdunlap@0 448 * list_for_each_entry_reverse - iterate backwards over list of given type.
gdunlap@0 449 * @pos: the type * to use as a loop cursor.
gdunlap@0 450 * @head: the head for your list.
gdunlap@0 451 * @member: the name of the list_struct within the struct.
gdunlap@0 452 */
gdunlap@0 453 #define list_for_each_entry_reverse(pos, head, member) \
gdunlap@0 454 for (pos = list_entry((head)->prev, typeof(*pos), member); \
gdunlap@0 455 prefetch(pos->member.prev), &pos->member != (head); \
gdunlap@0 456 pos = list_entry(pos->member.prev, typeof(*pos), member))
gdunlap@0 457
gdunlap@0 458 /**
gdunlap@0 459 * list_prepare_entry - prepare a pos entry for use in
gdunlap@0 460 * list_for_each_entry_continue
gdunlap@0 461 * @pos: the type * to use as a start point
gdunlap@0 462 * @head: the head of the list
gdunlap@0 463 * @member: the name of the list_struct within the struct.
gdunlap@0 464 *
gdunlap@0 465 * Prepares a pos entry for use as a start point in
gdunlap@0 466 * list_for_each_entry_continue.
gdunlap@0 467 */
gdunlap@0 468 #define list_prepare_entry(pos, head, member) \
gdunlap@0 469 ((pos) ? : list_entry(head, typeof(*pos), member))
gdunlap@0 470
gdunlap@0 471 /**
gdunlap@0 472 * list_for_each_entry_continue - continue iteration over list of given type
gdunlap@0 473 * @pos: the type * to use as a loop cursor.
gdunlap@0 474 * @head: the head for your list.
gdunlap@0 475 * @member: the name of the list_struct within the struct.
gdunlap@0 476 *
gdunlap@0 477 * Continue to iterate over list of given type, continuing after
gdunlap@0 478 * the current position.
gdunlap@0 479 */
gdunlap@0 480 #define list_for_each_entry_continue(pos, head, member) \
gdunlap@0 481 for (pos = list_entry(pos->member.next, typeof(*pos), member); \
gdunlap@0 482 prefetch(pos->member.next), &pos->member != (head); \
gdunlap@0 483 pos = list_entry(pos->member.next, typeof(*pos), member))
gdunlap@0 484
gdunlap@0 485 /**
gdunlap@0 486 * list_for_each_entry_from - iterate over list of given type from the
gdunlap@0 487 * current point
gdunlap@0 488 * @pos: the type * to use as a loop cursor.
gdunlap@0 489 * @head: the head for your list.
gdunlap@0 490 * @member: the name of the list_struct within the struct.
gdunlap@0 491 *
gdunlap@0 492 * Iterate over list of given type, continuing from current position.
gdunlap@0 493 */
gdunlap@0 494 #define list_for_each_entry_from(pos, head, member) \
gdunlap@0 495 for (; prefetch(pos->member.next), &pos->member != (head); \
gdunlap@0 496 pos = list_entry(pos->member.next, typeof(*pos), member))
gdunlap@0 497
gdunlap@0 498 /**
gdunlap@0 499 * list_for_each_entry_safe - iterate over list of given type safe
gdunlap@0 500 * against removal of list entry
gdunlap@0 501 * @pos: the type * to use as a loop cursor.
gdunlap@0 502 * @n: another type * to use as temporary storage
gdunlap@0 503 * @head: the head for your list.
gdunlap@0 504 * @member: the name of the list_struct within the struct.
gdunlap@0 505 */
gdunlap@0 506 #define list_for_each_entry_safe(pos, n, head, member) \
gdunlap@0 507 for (pos = list_entry((head)->next, typeof(*pos), member), \
gdunlap@0 508 n = list_entry(pos->member.next, typeof(*pos), member); \
gdunlap@0 509 &pos->member != (head); \
gdunlap@0 510 pos = n, n = list_entry(n->member.next, typeof(*n), member))
gdunlap@0 511
gdunlap@0 512 /**
gdunlap@0 513 * list_for_each_entry_safe_continue
gdunlap@0 514 * @pos: the type * to use as a loop cursor.
gdunlap@0 515 * @n: another type * to use as temporary storage
gdunlap@0 516 * @head: the head for your list.
gdunlap@0 517 * @member: the name of the list_struct within the struct.
gdunlap@0 518 *
gdunlap@0 519 * Iterate over list of given type, continuing after current point,
gdunlap@0 520 * safe against removal of list entry.
gdunlap@0 521 */
gdunlap@0 522 #define list_for_each_entry_safe_continue(pos, n, head, member) \
gdunlap@0 523 for (pos = list_entry(pos->member.next, typeof(*pos), member), \
gdunlap@0 524 n = list_entry(pos->member.next, typeof(*pos), member); \
gdunlap@0 525 &pos->member != (head); \
gdunlap@0 526 pos = n, n = list_entry(n->member.next, typeof(*n), member))
gdunlap@0 527
gdunlap@0 528 /**
gdunlap@0 529 * list_for_each_entry_safe_from
gdunlap@0 530 * @pos: the type * to use as a loop cursor.
gdunlap@0 531 * @n: another type * to use as temporary storage
gdunlap@0 532 * @head: the head for your list.
gdunlap@0 533 * @member: the name of the list_struct within the struct.
gdunlap@0 534 *
gdunlap@0 535 * Iterate over list of given type from current point, safe against
gdunlap@0 536 * removal of list entry.
gdunlap@0 537 */
gdunlap@0 538 #define list_for_each_entry_safe_from(pos, n, head, member) \
gdunlap@0 539 for (n = list_entry(pos->member.next, typeof(*pos), member); \
gdunlap@0 540 &pos->member != (head); \
gdunlap@0 541 pos = n, n = list_entry(n->member.next, typeof(*n), member))
gdunlap@0 542
gdunlap@0 543 /**
gdunlap@0 544 * list_for_each_entry_safe_reverse
gdunlap@0 545 * @pos: the type * to use as a loop cursor.
gdunlap@0 546 * @n: another type * to use as temporary storage
gdunlap@0 547 * @head: the head for your list.
gdunlap@0 548 * @member: the name of the list_struct within the struct.
gdunlap@0 549 *
gdunlap@0 550 * Iterate backwards over list of given type, safe against removal
gdunlap@0 551 * of list entry.
gdunlap@0 552 */
gdunlap@0 553 #define list_for_each_entry_safe_reverse(pos, n, head, member) \
gdunlap@0 554 for (pos = list_entry((head)->prev, typeof(*pos), member), \
gdunlap@0 555 n = list_entry(pos->member.prev, typeof(*pos), member); \
gdunlap@0 556 &pos->member != (head); \
gdunlap@0 557 pos = n, n = list_entry(n->member.prev, typeof(*n), member))
gdunlap@0 558
gdunlap@0 559 /**
gdunlap@0 560 * list_for_each_rcu - iterate over an rcu-protected list
gdunlap@0 561 * @pos: the &struct list_head to use as a loop cursor.
gdunlap@0 562 * @head: the head for your list.
gdunlap@0 563 *
gdunlap@0 564 * This list-traversal primitive may safely run concurrently with
gdunlap@0 565 * the _rcu list-mutation primitives such as list_add_rcu()
gdunlap@0 566 * as long as the traversal is guarded by rcu_read_lock().
gdunlap@0 567 */
gdunlap@0 568 #define list_for_each_rcu(pos, head) \
gdunlap@0 569 for (pos = (head)->next; \
gdunlap@0 570 prefetch(rcu_dereference(pos)->next), pos != (head); \
gdunlap@0 571 pos = pos->next)
gdunlap@0 572
gdunlap@0 573 #define __list_for_each_rcu(pos, head) \
gdunlap@0 574 for (pos = (head)->next; \
gdunlap@0 575 rcu_dereference(pos) != (head); \
gdunlap@0 576 pos = pos->next)
gdunlap@0 577
gdunlap@0 578 /**
gdunlap@0 579 * list_for_each_safe_rcu
gdunlap@0 580 * @pos: the &struct list_head to use as a loop cursor.
gdunlap@0 581 * @n: another &struct list_head to use as temporary storage
gdunlap@0 582 * @head: the head for your list.
gdunlap@0 583 *
gdunlap@0 584 * Iterate over an rcu-protected list, safe against removal of list entry.
gdunlap@0 585 *
gdunlap@0 586 * This list-traversal primitive may safely run concurrently with
gdunlap@0 587 * the _rcu list-mutation primitives such as list_add_rcu()
gdunlap@0 588 * as long as the traversal is guarded by rcu_read_lock().
gdunlap@0 589 */
gdunlap@0 590 #define list_for_each_safe_rcu(pos, n, head) \
gdunlap@0 591 for (pos = (head)->next; \
gdunlap@0 592 n = rcu_dereference(pos)->next, pos != (head); \
gdunlap@0 593 pos = n)
gdunlap@0 594
gdunlap@0 595 /**
gdunlap@0 596 * list_for_each_entry_rcu - iterate over rcu list of given type
gdunlap@0 597 * @pos: the type * to use as a loop cursor.
gdunlap@0 598 * @head: the head for your list.
gdunlap@0 599 * @member: the name of the list_struct within the struct.
gdunlap@0 600 *
gdunlap@0 601 * This list-traversal primitive may safely run concurrently with
gdunlap@0 602 * the _rcu list-mutation primitives such as list_add_rcu()
gdunlap@0 603 * as long as the traversal is guarded by rcu_read_lock().
gdunlap@0 604 */
gdunlap@0 605 #define list_for_each_entry_rcu(pos, head, member) \
gdunlap@0 606 for (pos = list_entry((head)->next, typeof(*pos), member); \
gdunlap@0 607 prefetch(rcu_dereference(pos)->member.next), \
gdunlap@0 608 &pos->member != (head); \
gdunlap@0 609 pos = list_entry(pos->member.next, typeof(*pos), member))
gdunlap@0 610
gdunlap@0 611 /**
gdunlap@0 612 * list_for_each_continue_rcu
gdunlap@0 613 * @pos: the &struct list_head to use as a loop cursor.
gdunlap@0 614 * @head: the head for your list.
gdunlap@0 615 *
gdunlap@0 616 * Iterate over an rcu-protected list, continuing after current point.
gdunlap@0 617 *
gdunlap@0 618 * This list-traversal primitive may safely run concurrently with
gdunlap@0 619 * the _rcu list-mutation primitives such as list_add_rcu()
gdunlap@0 620 * as long as the traversal is guarded by rcu_read_lock().
gdunlap@0 621 */
gdunlap@0 622 #define list_for_each_continue_rcu(pos, head) \
gdunlap@0 623 for ((pos) = (pos)->next; \
gdunlap@0 624 prefetch(rcu_dereference((pos))->next), (pos) != (head); \
gdunlap@0 625 (pos) = (pos)->next)
gdunlap@0 626
gdunlap@0 627 /*
gdunlap@0 628 * Double linked lists with a single pointer list head.
gdunlap@0 629 * Mostly useful for hash tables where the two pointer list head is
gdunlap@0 630 * too wasteful.
gdunlap@0 631 * You lose the ability to access the tail in O(1).
gdunlap@0 632 */
gdunlap@0 633
gdunlap@0 634 struct hlist_head {
gdunlap@0 635 struct hlist_node *first;
gdunlap@0 636 };
gdunlap@0 637
gdunlap@0 638 struct hlist_node {
gdunlap@0 639 struct hlist_node *next, **pprev;
gdunlap@0 640 };
gdunlap@0 641
gdunlap@0 642 #define HLIST_HEAD_INIT { .first = NULL }
gdunlap@0 643 #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
gdunlap@0 644 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
gdunlap@0 645 static inline void INIT_HLIST_NODE(struct hlist_node *h)
gdunlap@0 646 {
gdunlap@0 647 h->next = NULL;
gdunlap@0 648 h->pprev = NULL;
gdunlap@0 649 }
gdunlap@0 650
gdunlap@0 651 static inline int hlist_unhashed(const struct hlist_node *h)
gdunlap@0 652 {
gdunlap@0 653 return !h->pprev;
gdunlap@0 654 }
gdunlap@0 655
gdunlap@0 656 static inline int hlist_empty(const struct hlist_head *h)
gdunlap@0 657 {
gdunlap@0 658 return !h->first;
gdunlap@0 659 }
gdunlap@0 660
gdunlap@0 661 static inline void __hlist_del(struct hlist_node *n)
gdunlap@0 662 {
gdunlap@0 663 struct hlist_node *next = n->next;
gdunlap@0 664 struct hlist_node **pprev = n->pprev;
gdunlap@0 665 *pprev = next;
gdunlap@0 666 if (next)
gdunlap@0 667 next->pprev = pprev;
gdunlap@0 668 }
gdunlap@0 669
gdunlap@0 670 static inline void hlist_del(struct hlist_node *n)
gdunlap@0 671 {
gdunlap@0 672 __hlist_del(n);
gdunlap@0 673 n->next = LIST_POISON1;
gdunlap@0 674 n->pprev = LIST_POISON2;
gdunlap@0 675 }
gdunlap@0 676
gdunlap@0 677 /**
gdunlap@0 678 * hlist_del_rcu - deletes entry from hash list without re-initialization
gdunlap@0 679 * @n: the element to delete from the hash list.
gdunlap@0 680 *
gdunlap@0 681 * Note: list_unhashed() on entry does not return true after this,
gdunlap@0 682 * the entry is in an undefined state. It is useful for RCU based
gdunlap@0 683 * lockfree traversal.
gdunlap@0 684 *
gdunlap@0 685 * In particular, it means that we can not poison the forward
gdunlap@0 686 * pointers that may still be used for walking the hash list.
gdunlap@0 687 *
gdunlap@0 688 * The caller must take whatever precautions are necessary
gdunlap@0 689 * (such as holding appropriate locks) to avoid racing
gdunlap@0 690 * with another list-mutation primitive, such as hlist_add_head_rcu()
gdunlap@0 691 * or hlist_del_rcu(), running on this same list.
gdunlap@0 692 * However, it is perfectly legal to run concurrently with
gdunlap@0 693 * the _rcu list-traversal primitives, such as
gdunlap@0 694 * hlist_for_each_entry().
gdunlap@0 695 */
gdunlap@0 696 static inline void hlist_del_rcu(struct hlist_node *n)
gdunlap@0 697 {
gdunlap@0 698 __hlist_del(n);
gdunlap@0 699 n->pprev = LIST_POISON2;
gdunlap@0 700 }
gdunlap@0 701
gdunlap@0 702 static inline void hlist_del_init(struct hlist_node *n)
gdunlap@0 703 {
gdunlap@0 704 if (!hlist_unhashed(n)) {
gdunlap@0 705 __hlist_del(n);
gdunlap@0 706 INIT_HLIST_NODE(n);
gdunlap@0 707 }
gdunlap@0 708 }
gdunlap@0 709
gdunlap@0 710 /*
gdunlap@0 711 * hlist_replace_rcu - replace old entry by new one
gdunlap@0 712 * @old : the element to be replaced
gdunlap@0 713 * @new : the new element to insert
gdunlap@0 714 *
gdunlap@0 715 * The old entry will be replaced with the new entry atomically.
gdunlap@0 716 */
gdunlap@0 717 static inline void hlist_replace_rcu(struct hlist_node *old,
gdunlap@0 718 struct hlist_node *new)
gdunlap@0 719 {
gdunlap@0 720 struct hlist_node *next = old->next;
gdunlap@0 721
gdunlap@0 722 new->next = next;
gdunlap@0 723 new->pprev = old->pprev;
gdunlap@0 724 if (next)
gdunlap@0 725 new->next->pprev = &new->next;
gdunlap@0 726 *new->pprev = new;
gdunlap@0 727 old->pprev = LIST_POISON2;
gdunlap@0 728 }
gdunlap@0 729
gdunlap@0 730 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
gdunlap@0 731 {
gdunlap@0 732 struct hlist_node *first = h->first;
gdunlap@0 733 n->next = first;
gdunlap@0 734 if (first)
gdunlap@0 735 first->pprev = &n->next;
gdunlap@0 736 h->first = n;
gdunlap@0 737 n->pprev = &h->first;
gdunlap@0 738 }
gdunlap@0 739
gdunlap@0 740 /**
gdunlap@0 741 * hlist_add_head_rcu
gdunlap@0 742 * @n: the element to add to the hash list.
gdunlap@0 743 * @h: the list to add to.
gdunlap@0 744 *
gdunlap@0 745 * Description:
gdunlap@0 746 * Adds the specified element to the specified hlist,
gdunlap@0 747 * while permitting racing traversals.
gdunlap@0 748 *
gdunlap@0 749 * The caller must take whatever precautions are necessary
gdunlap@0 750 * (such as holding appropriate locks) to avoid racing
gdunlap@0 751 * with another list-mutation primitive, such as hlist_add_head_rcu()
gdunlap@0 752 * or hlist_del_rcu(), running on this same list.
gdunlap@0 753 * However, it is perfectly legal to run concurrently with
gdunlap@0 754 * the _rcu list-traversal primitives, such as
gdunlap@0 755 * hlist_for_each_entry_rcu(), used to prevent memory-consistency
gdunlap@0 756 * problems on Alpha CPUs. Regardless of the type of CPU, the
gdunlap@0 757 * list-traversal primitive must be guarded by rcu_read_lock().
gdunlap@0 758 */
gdunlap@0 759 static inline void hlist_add_head_rcu(struct hlist_node *n,
gdunlap@0 760 struct hlist_head *h)
gdunlap@0 761 {
gdunlap@0 762 struct hlist_node *first = h->first;
gdunlap@0 763 n->next = first;
gdunlap@0 764 n->pprev = &h->first;
gdunlap@0 765 if (first)
gdunlap@0 766 first->pprev = &n->next;
gdunlap@0 767 h->first = n;
gdunlap@0 768 }
gdunlap@0 769
gdunlap@0 770 /* next must be != NULL */
gdunlap@0 771 static inline void hlist_add_before(struct hlist_node *n,
gdunlap@0 772 struct hlist_node *next)
gdunlap@0 773 {
gdunlap@0 774 n->pprev = next->pprev;
gdunlap@0 775 n->next = next;
gdunlap@0 776 next->pprev = &n->next;
gdunlap@0 777 *(n->pprev) = n;
gdunlap@0 778 }
gdunlap@0 779
gdunlap@0 780 static inline void hlist_add_after(struct hlist_node *n,
gdunlap@0 781 struct hlist_node *next)
gdunlap@0 782 {
gdunlap@0 783 next->next = n->next;
gdunlap@0 784 n->next = next;
gdunlap@0 785 next->pprev = &n->next;
gdunlap@0 786
gdunlap@0 787 if(next->next)
gdunlap@0 788 next->next->pprev = &next->next;
gdunlap@0 789 }
gdunlap@0 790
gdunlap@0 791 /**
gdunlap@0 792 * hlist_add_before_rcu
gdunlap@0 793 * @n: the new element to add to the hash list.
gdunlap@0 794 * @next: the existing element to add the new element before.
gdunlap@0 795 *
gdunlap@0 796 * Description:
gdunlap@0 797 * Adds the specified element to the specified hlist
gdunlap@0 798 * before the specified node while permitting racing traversals.
gdunlap@0 799 *
gdunlap@0 800 * The caller must take whatever precautions are necessary
gdunlap@0 801 * (such as holding appropriate locks) to avoid racing
gdunlap@0 802 * with another list-mutation primitive, such as hlist_add_head_rcu()
gdunlap@0 803 * or hlist_del_rcu(), running on this same list.
gdunlap@0 804 * However, it is perfectly legal to run concurrently with
gdunlap@0 805 * the _rcu list-traversal primitives, such as
gdunlap@0 806 * hlist_for_each_entry_rcu(), used to prevent memory-consistency
gdunlap@0 807 * problems on Alpha CPUs.
gdunlap@0 808 */
gdunlap@0 809 static inline void hlist_add_before_rcu(struct hlist_node *n,
gdunlap@0 810 struct hlist_node *next)
gdunlap@0 811 {
gdunlap@0 812 n->pprev = next->pprev;
gdunlap@0 813 n->next = next;
gdunlap@0 814 next->pprev = &n->next;
gdunlap@0 815 *(n->pprev) = n;
gdunlap@0 816 }
gdunlap@0 817
gdunlap@0 818 /**
gdunlap@0 819 * hlist_add_after_rcu
gdunlap@0 820 * @prev: the existing element to add the new element after.
gdunlap@0 821 * @n: the new element to add to the hash list.
gdunlap@0 822 *
gdunlap@0 823 * Description:
gdunlap@0 824 * Adds the specified element to the specified hlist
gdunlap@0 825 * after the specified node while permitting racing traversals.
gdunlap@0 826 *
gdunlap@0 827 * The caller must take whatever precautions are necessary
gdunlap@0 828 * (such as holding appropriate locks) to avoid racing
gdunlap@0 829 * with another list-mutation primitive, such as hlist_add_head_rcu()
gdunlap@0 830 * or hlist_del_rcu(), running on this same list.
gdunlap@0 831 * However, it is perfectly legal to run concurrently with
gdunlap@0 832 * the _rcu list-traversal primitives, such as
gdunlap@0 833 * hlist_for_each_entry_rcu(), used to prevent memory-consistency
gdunlap@0 834 * problems on Alpha CPUs.
gdunlap@0 835 */
gdunlap@0 836 static inline void hlist_add_after_rcu(struct hlist_node *prev,
gdunlap@0 837 struct hlist_node *n)
gdunlap@0 838 {
gdunlap@0 839 n->next = prev->next;
gdunlap@0 840 n->pprev = &prev->next;
gdunlap@0 841 prev->next = n;
gdunlap@0 842 if (n->next)
gdunlap@0 843 n->next->pprev = &n->next;
gdunlap@0 844 }
gdunlap@0 845
gdunlap@0 846 #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
gdunlap@0 847
gdunlap@0 848 #define hlist_for_each(pos, head) \
gdunlap@0 849 for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
gdunlap@0 850 pos = pos->next)
gdunlap@0 851
gdunlap@0 852 #define hlist_for_each_safe(pos, n, head) \
gdunlap@0 853 for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
gdunlap@0 854 pos = n)
gdunlap@0 855
gdunlap@0 856 /**
gdunlap@0 857 * hlist_for_each_entry - iterate over list of given type
gdunlap@0 858 * @tpos: the type * to use as a loop cursor.
gdunlap@0 859 * @pos: the &struct hlist_node to use as a loop cursor.
gdunlap@0 860 * @head: the head for your list.
gdunlap@0 861 * @member: the name of the hlist_node within the struct.
gdunlap@0 862 */
gdunlap@0 863 #define hlist_for_each_entry(tpos, pos, head, member) \
gdunlap@0 864 for (pos = (head)->first; \
gdunlap@0 865 pos && ({ prefetch(pos->next); 1;}) && \
gdunlap@0 866 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
gdunlap@0 867 pos = pos->next)
gdunlap@0 868
gdunlap@0 869 /**
gdunlap@0 870 * hlist_for_each_entry_continue - iterate over a hlist continuing
gdunlap@0 871 * after current point
gdunlap@0 872 * @tpos: the type * to use as a loop cursor.
gdunlap@0 873 * @pos: the &struct hlist_node to use as a loop cursor.
gdunlap@0 874 * @member: the name of the hlist_node within the struct.
gdunlap@0 875 */
gdunlap@0 876 #define hlist_for_each_entry_continue(tpos, pos, member) \
gdunlap@0 877 for (pos = (pos)->next; \
gdunlap@0 878 pos && ({ prefetch(pos->next); 1;}) && \
gdunlap@0 879 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
gdunlap@0 880 pos = pos->next)
gdunlap@0 881
gdunlap@0 882 /**
gdunlap@0 883 * hlist_for_each_entry_from - iterate over a hlist continuing from
gdunlap@0 884 * current point
gdunlap@0 885 * @tpos: the type * to use as a loop cursor.
gdunlap@0 886 * @pos: the &struct hlist_node to use as a loop cursor.
gdunlap@0 887 * @member: the name of the hlist_node within the struct.
gdunlap@0 888 */
gdunlap@0 889 #define hlist_for_each_entry_from(tpos, pos, member) \
gdunlap@0 890 for (; pos && ({ prefetch(pos->next); 1;}) && \
gdunlap@0 891 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
gdunlap@0 892 pos = pos->next)
gdunlap@0 893
gdunlap@0 894 /**
gdunlap@0 895 * hlist_for_each_entry_safe - iterate over list of given type safe
gdunlap@0 896 * against removal of list entry
gdunlap@0 897 * @tpos: the type * to use as a loop cursor.
gdunlap@0 898 * @pos: the &struct hlist_node to use as a loop cursor.
gdunlap@0 899 * @n: another &struct hlist_node to use as temporary storage
gdunlap@0 900 * @head: the head for your list.
gdunlap@0 901 * @member: the name of the hlist_node within the struct.
gdunlap@0 902 */
gdunlap@0 903 #define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
gdunlap@0 904 for (pos = (head)->first; \
gdunlap@0 905 pos && ({ n = pos->next; 1; }) && \
gdunlap@0 906 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
gdunlap@0 907 pos = n)
gdunlap@0 908
gdunlap@0 909
gdunlap@0 910 /**
gdunlap@0 911 * hlist_for_each_entry_rcu - iterate over rcu list of given type
gdunlap@0 912 * @tpos: the type * to use as a loop cursor.
gdunlap@0 913 * @pos: the &struct hlist_node to use as a loop cursor.
gdunlap@0 914 * @head: the head for your list.
gdunlap@0 915 * @member: the name of the hlist_node within the struct.
gdunlap@0 916 *
gdunlap@0 917 * This list-traversal primitive may safely run concurrently with
gdunlap@0 918 * the _rcu list-mutation primitives such as hlist_add_head_rcu()
gdunlap@0 919 * as long as the traversal is guarded by rcu_read_lock().
gdunlap@0 920 */
gdunlap@0 921 #define hlist_for_each_entry_rcu(tpos, pos, head, member) \
gdunlap@0 922 for (pos = (head)->first; \
gdunlap@0 923 rcu_dereference(pos) && ({ prefetch(pos->next); 1;}) && \
gdunlap@0 924 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
gdunlap@0 925 pos = pos->next)
gdunlap@0 926
gdunlap@0 927 #endif /* __XEN_LIST_H__ */
gdunlap@0 928