Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
list.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Linus Torvalds
3  * Copyright (c) 2011, 2012 The University of Utah
4  *
5  * This file contains list-implementation code taken from Linux
6  * (primarily the Linux source file `include/linux/list.h') and
7  * de-kernelized for user-space programs.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * version 2 as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef _LINUX_LIST_H
24 #define _LINUX_LIST_H
25 
26 /* Taken from Linux kernel code, but de-kernelized for userspace. */
27 #include <stddef.h>
28 
29 /*
30  * These are non-NULL pointers that will result in page faults
31  * under normal circumstances, used to verify that nobody uses
32  * non-initialized list entries.
33  */
34 #define LIST_POISON1 ((void *) 0x00100100)
35 #define LIST_POISON2 ((void *) 0x00200200)
36 
37 #define container_of(ptr, type, member) ({ \
38  const typeof( ((type *)0)->member ) *__mptr = (ptr); \
39  (type *)( (char *)__mptr - offsetof(type,member) );})
40 
41 /*
42  * Simple doubly linked list implementation.
43  *
44  * Some of the internal functions ("__xxx") are useful when
45  * manipulating whole lists rather than single entries, as
46  * sometimes we already know the next/prev entries and we can
47  * generate better code by using them directly rather than
48  * using the generic single-entry routines.
49  */
50 
51 struct list_head {
52  struct list_head *next, *prev;
53 };
54 
55 #define LIST_HEAD_INIT(name) { &(name), &(name) }
56 
57 #define LIST_HEAD(name) \
58  struct list_head name = LIST_HEAD_INIT(name)
59 
60 #define INIT_LIST_HEAD(ptr) do { \
61  (ptr)->next = (ptr); (ptr)->prev = (ptr); \
62 } while (0)
63 
64 #define list_top(head, type, member) \
65 ({ \
66  struct list_head *_head = (head); \
67  list_empty(_head) ? NULL : list_entry(_head->next, type, member); \
68 })
69 
70 /*
71  * Insert a new entry between two known consecutive entries.
72  *
73  * This is only for internal list manipulation where we know
74  * the prev/next entries already!
75  */
76 static inline void __list_add(struct list_head *newn,
77  struct list_head *prev,
78  struct list_head *next)
79 {
80  next->prev = newn;
81  newn->next = next;
82  newn->prev = prev;
83  prev->next = newn;
84 }
85 
94 static inline void list_add(struct list_head *newn, struct list_head *head)
95 {
96  __list_add(newn, head, head->next);
97 }
98 
107 static inline void list_add_tail(struct list_head *newn, struct list_head *head)
108 {
109  __list_add(newn, head->prev, head);
110 }
111 
118 static inline void list_replace(struct list_head *old, struct list_head *newn)
119 {
120  newn->next = old->next;
121  newn->next->prev = newn;
122  newn->prev = old->prev;
123  newn->prev->next = newn;
124 }
125 
126 /*
127  * Insert a new entry between two known consecutive entries.
128  *
129  * This is only for internal list manipulation where we know
130  * the prev/next entries already!
131  */
132 static __inline__ void __list_add_rcu(struct list_head * newn,
133  struct list_head * prev,
134  struct list_head * next)
135 {
136  newn->next = next;
137  newn->prev = prev;
138  next->prev = newn;
139  prev->next = newn;
140 }
141 
150 static __inline__ void list_add_rcu(struct list_head *newn, struct list_head *head)
151 {
152  __list_add_rcu(newn, head, head->next);
153 }
154 
163 static __inline__ void list_add_tail_rcu(struct list_head *newn, struct list_head *head)
164 {
165  __list_add_rcu(newn, head->prev, head);
166 }
167 
168 /*
169  * Delete a list entry by making the prev/next entries
170  * point to each other.
171  *
172  * This is only for internal list manipulation where we know
173  * the prev/next entries already!
174  */
175 static inline void __list_del(struct list_head * prev, struct list_head * next)
176 {
177  next->prev = prev;
178  prev->next = next;
179 }
180 
187 static inline void list_del(struct list_head *entry)
188 {
189  __list_del(entry->prev, entry->next);
190  entry->next = (struct list_head *)LIST_POISON1;
191  entry->prev = (struct list_head *)LIST_POISON2;
192 }
193 
205 static inline void list_del_rcu(struct list_head *entry)
206 {
207  __list_del(entry->prev, entry->next);
208  entry->prev = (struct list_head *)LIST_POISON2;
209 }
210 
215 static inline void list_del_init(struct list_head *entry)
216 {
217  __list_del(entry->prev, entry->next);
218  INIT_LIST_HEAD(entry);
219 }
220 
226 static inline void list_move(struct list_head *list, struct list_head *head)
227 {
228  __list_del(list->prev, list->next);
229  list_add(list, head);
230 }
231 
237 static inline void list_move_tail(struct list_head *list,
238  struct list_head *head)
239 {
240  __list_del(list->prev, list->next);
241  list_add_tail(list, head);
242 }
243 
248 static inline int list_empty(struct list_head *head)
249 {
250  return head->next == head;
251 }
252 
253 static inline void __list_splice(struct list_head *list,
254  struct list_head *head)
255 {
256  struct list_head *first = list->next;
257  struct list_head *last = list->prev;
258  struct list_head *at = head->next;
259 
260  first->prev = head;
261  head->next = first;
262 
263  last->next = at;
264  at->prev = last;
265 }
266 
272 static inline void list_splice(struct list_head *list, struct list_head *head)
273 {
274  if (!list_empty(list))
275  __list_splice(list, head);
276 }
277 
285 static inline void list_splice_init(struct list_head *list,
286  struct list_head *head)
287 {
288  if (!list_empty(list)) {
289  __list_splice(list, head);
290  INIT_LIST_HEAD(list);
291  }
292 }
293 
300 #define list_entry(ptr, type, member) \
301  container_of(ptr, type, member)
302 
308 #define list_for_each(pos, head) \
309  for (pos = (head)->next; pos != (head); pos = pos->next)
310 
316 #define list_for_each_prev(pos, head) \
317  for (pos = (head)->prev; pos != (head); pos = pos->prev)
318 
325 #define list_for_each_safe(pos, n, head) \
326  for (pos = (head)->next, n = pos->next; pos != (head); \
327  pos = n, n = pos->next)
328 
335 #define list_for_each_entry(pos, head, member) \
336  for (pos = list_entry((head)->next, typeof(*pos), member); \
337  &pos->member != (head); \
338  pos = list_entry(pos->member.next, typeof(*pos), member))
339 
349 #define list_for_each_entry_dual(pos, pos2, head, head2, member, member2) \
350  for (pos = list_entry((head)->next, typeof(*pos), member), \
351  pos2 = list_entry((head2)->next, typeof(*pos2), member2); \
352  &pos->member != (head) && &pos2->member2 != (head2); \
353  pos = list_entry(pos->member.next, typeof(*pos), member), \
354  pos2 = list_entry(pos2->member2.next, typeof(*pos2), member2))
355 
362 #define list_for_each_entry_reverse(pos, head, member) \
363  for (pos = list_entry((head)->prev, typeof(*pos), member); \
364  &pos->member != (head); \
365  pos = list_entry(pos->member.prev, typeof(*pos), member))
366 
367 
375 #define list_for_each_entry_continue(pos, head, member) \
376  for (pos = list_entry(pos->member.next, typeof(*pos), member); \
377  &pos->member != (head); \
378  pos = list_entry(pos->member.next, typeof(*pos), member))
379 
387 #define list_for_each_entry_safe(pos, n, head, member) \
388  for (pos = list_entry((head)->next, typeof(*pos), member), \
389  n = list_entry(pos->member.next, typeof(*pos), member); \
390  &pos->member != (head); \
391  pos = n, n = list_entry(n->member.next, typeof(*n), member))
392 
393 
394 /*
395  * Double linked lists with a single pointer list head.
396  * Mostly useful for hash tables where the two pointer list head is
397  * too wasteful.
398  * You lose the ability to access the tail in O(1).
399  */
400 
401 struct hlist_head {
402  struct hlist_node *first;
403 };
404 
405 struct hlist_node {
406  struct hlist_node *next, **pprev;
407 };
408 
409 #define HLIST_HEAD_INIT { .first = NULL }
410 #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
411 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
412 #define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
413 
414 static __inline__ int hlist_unhashed(struct hlist_node *h)
415 {
416  return !h->pprev;
417 }
418 
419 static __inline__ int hlist_empty(struct hlist_head *h)
420 {
421  return !h->first;
422 }
423 
424 static __inline__ void __hlist_del(struct hlist_node *n)
425 {
426  struct hlist_node *next = n->next;
427  struct hlist_node **pprev = n->pprev;
428  *pprev = next;
429  if (next)
430  next->pprev = pprev;
431 }
432 
433 static __inline__ void hlist_del(struct hlist_node *n)
434 {
435  __hlist_del(n);
436  n->next = (struct hlist_node *)LIST_POISON1;
437  n->pprev = (struct hlist_node **)LIST_POISON2;
438 }
439 
451 static inline void hlist_del_rcu(struct hlist_node *n)
452 {
453  __hlist_del(n);
454  n->pprev = (struct hlist_node **)LIST_POISON2;
455 }
456 
457 static __inline__ void hlist_del_init(struct hlist_node *n)
458 {
459  if (n->pprev) {
460  __hlist_del(n);
461  INIT_HLIST_NODE(n);
462  }
463 }
464 
465 #define hlist_del_rcu_init hlist_del_init
466 
467 static __inline__ void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
468 {
469  struct hlist_node *first = h->first;
470  n->next = first;
471  if (first)
472  first->pprev = &n->next;
473  h->first = n;
474  n->pprev = &h->first;
475 }
476 
477 static __inline__ void hlist_add_head_rcu(struct hlist_node *n, struct hlist_head *h)
478 {
479  struct hlist_node *first = h->first;
480  n->next = first;
481  n->pprev = &h->first;
482  if (first)
483  first->pprev = &n->next;
484  h->first = n;
485 }
486 
487 /* next must be != NULL */
488 static __inline__ void hlist_add_before(struct hlist_node *n, struct hlist_node *next)
489 {
490  n->pprev = next->pprev;
491  n->next = next;
492  next->pprev = &n->next;
493  *(n->pprev) = n;
494 }
495 
496 static __inline__ void hlist_add_after(struct hlist_node *n,
497  struct hlist_node *next)
498 {
499  next->next = n->next;
500  *(next->pprev) = n;
501  n->next = next;
502 }
503 
504 #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
505 
506 /* Cannot easily do prefetch unfortunately */
507 #define hlist_for_each(pos, head) \
508  for (pos = (head)->first; pos; pos = pos->next)
509 
510 #define hlist_for_each_safe(pos, n, head) \
511  for (pos = (head)->first; n = pos ? pos->next : 0, pos; \
512  pos = n)
513 
521 #define hlist_for_each_entry(tpos, pos, head, member) \
522  for (pos = (head)->first; \
523  pos && ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
524  pos = pos->next)
525 
532 #define hlist_for_each_entry_continue(tpos, pos, member) \
533  for (pos = (pos)->next; \
534  pos && ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
535  pos = pos->next)
536 
543 #define hlist_for_each_entry_from(tpos, pos, member) \
544  for (; pos && ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
545  pos = pos->next)
546 
555 #define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
556  for (pos = (head)->first; \
557  pos && ({ n = pos->next; 1; }) && \
558  ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
559  pos = n)
560 
561 #endif /* _LINUX_LIST_H */
struct hlist_node * next
Definition: list.h:406
#define INIT_HLIST_NODE(ptr)
Definition: list.h:412
struct list_head * next
Definition: list.h:52
#define LIST_POISON2
Definition: list.h:35
struct list_head * prev
Definition: list.h:52
Definition: list.h:51
#define LIST_POISON1
Definition: list.h:34
struct hlist_node * first
Definition: list.h:402
struct hlist_node ** pprev
Definition: list.h:406
#define INIT_LIST_HEAD(ptr)
Definition: list.h:60