Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
141 Kevin 1
#ifndef __LIST_H
2
#define __LIST_H
3
/* This code is taken from the Pintos education OS.
4
 * For copyright information, see www.pintos-os.org */
5
 
6
/* Doubly linked list.
7
 
8
   This implementation of a doubly linked list does not require
9
   use of dynamically allocated memory.  Instead, each structure
10
   that is a potential list element must embed a struct list_elem
11
   member.  All of the list functions operate on these `struct
12
   list_elem's.  The list_entry macro allows conversion from a
13
   struct list_elem back to a structure object that contains it.
14
 
15
   For example, suppose there is a needed for a list of `struct
16
   foo'.  `struct foo' should contain a `struct list_elem'
17
   member, like so:
18
 
19
      struct foo
20
        {
21
          struct list_elem elem;
22
          int bar;
23
          ...other members...
24
        };
25
 
26
   Then a list of `struct foo' can be be declared and initialized
27
   like so:
28
 
29
      struct list foo_list;
30
 
31
      list_init (&foo_list);
32
 
33
   Iteration is a typical situation where it is necessary to
34
   convert from a struct list_elem back to its enclosing
35
   structure.  Here's an example using foo_list:
36
 
37
      struct list_elem *e;
38
 
39
      for (e = list_begin (&foo_list); e != list_end (&foo_list);
40
           e = list_next (e))
41
        {
42
          struct foo *f = list_entry (e, struct foo, elem);
43
          ...do something with f...
44
        }
45
 
46
   You can find real examples of list usage throughout the
47
   source; for example, malloc.c, palloc.c, and thread.c in the
48
   threads directory all use lists.
49
 
50
   The interface for this list is inspired by the list<> template
51
   in the C++ STL.  If you're familiar with list<>, you should
52
   find this easy to use.  However, it should be emphasized that
53
   these lists do *no* type checking and can't do much other
54
   correctness checking.  If you screw up, it will bite you.
55
 
56
   Glossary of list terms:
57
 
58
     - "front": The first element in a list.  Undefined in an
59
       empty list.  Returned by list_front().
60
 
61
     - "back": The last element in a list.  Undefined in an empty
62
       list.  Returned by list_back().
63
 
64
     - "tail": The element figuratively just after the last
65
       element of a list.  Well defined even in an empty list.
66
       Returned by list_end().  Used as the end sentinel for an
67
       iteration from front to back.
68
 
69
     - "beginning": In a non-empty list, the front.  In an empty
70
       list, the tail.  Returned by list_begin().  Used as the
71
       starting point for an iteration from front to back.
72
 
73
     - "head": The element figuratively just before the first
74
       element of a list.  Well defined even in an empty list.
75
       Returned by list_rend().  Used as the end sentinel for an
76
       iteration from back to front.
77
 
78
     - "reverse beginning": In a non-empty list, the back.  In an
79
       empty list, the head.  Returned by list_rbegin().  Used as
80
       the starting point for an iteration from back to front.
81
 
82
     - "interior element": An element that is not the head or
83
       tail, that is, a real list element.  An empty list does
84
       not have any interior elements.
85
*/
86
 
87
#include <stdbool.h>
88
#include <stddef.h>
89
#include <stdint.h>
90
 
91
/* List element. */
92
struct list_elem 
93
  {
94
    struct list_elem *prev;     /* Previous list element. */
95
    struct list_elem *next;     /* Next list element. */
96
  };
97
 
98
/* List. */
99
struct list 
100
  {
101
    struct list_elem head;      /* List head. */
102
    struct list_elem tail;      /* List tail. */
103
  };
104
 
105
/* Converts pointer to list element LIST_ELEM into a pointer to
106
   the structure that LIST_ELEM is embedded inside.  Supply the
107
   name of the outer structure STRUCT and the member name MEMBER
108
   of the list element.  See the big comment at the top of the
109
   file for an example. */
110
#define list_entry(LIST_ELEM, STRUCT, MEMBER)           \
111
        ((STRUCT *) ((uint8_t *) &(LIST_ELEM)->next     \
112
                     - offsetof (STRUCT, MEMBER.next)))
113
 
114
void list_init (struct list *);
115
 
116
/* List traversal. */
117
struct list_elem *list_begin (struct list *);
118
struct list_elem *list_next (struct list_elem *);
119
struct list_elem *list_end (struct list *);
120
 
121
struct list_elem *list_rbegin (struct list *);
122
struct list_elem *list_prev (struct list_elem *);
123
struct list_elem *list_rend (struct list *);
124
 
125
struct list_elem *list_head (struct list *);
126
struct list_elem *list_tail (struct list *);
127
 
128
/* List insertion. */
129
void list_insert (struct list_elem *, struct list_elem *);
130
void list_splice (struct list_elem *before,
131
                  struct list_elem *first, struct list_elem *last);
132
void list_push_front (struct list *, struct list_elem *);
133
void list_push_back (struct list *, struct list_elem *);
134
 
135
/* List removal. */
136
struct list_elem *list_remove (struct list_elem *);
137
struct list_elem *list_pop_front (struct list *);
138
struct list_elem *list_pop_back (struct list *);
139
 
140
/* List elements. */
141
struct list_elem *list_front (struct list *);
142
struct list_elem *list_back (struct list *);
143
 
144
/* List properties. */
145
size_t list_size (struct list *);
146
bool list_empty (struct list *);
147
 
148
/* Miscellaneous. */
149
void list_reverse (struct list *);
150
 
151
/* Compares the value of two list elements A and B, given
152
   auxiliary data AUX.  Returns true if A is less than B, or
153
   false if A is greater than or equal to B. */
154
typedef bool list_less_func (const struct list_elem *a,
155
                             const struct list_elem *b,
156
                             void *aux);
157
 
158
/* Operations on lists with ordered elements. */
159
void list_sort (struct list *,
160
                list_less_func *, void *aux);
161
void list_insert_ordered (struct list *, struct list_elem *,
162
                          list_less_func *, void *aux);
163
void list_unique (struct list *, struct list *duplicates,
164
                  list_less_func *, void *aux);
165
 
166
/* Max and min. */
167
struct list_elem *list_max (struct list *, list_less_func *, void *aux);
168
struct list_elem *list_min (struct list *, list_less_func *, void *aux);
169
 
170
#endif /* list.h */