PKUOS - Pintos
Pintos source browser for PKU Operating System course
list.c
Go to the documentation of this file.
1/** Test program for lib/kernel/list.c.
2
3 Attempts to test the list functionality that is not
4 sufficiently tested elsewhere in Pintos.
5
6 This is not a test we will run on your submitted projects.
7 It is here for completeness.
8*/
9
10#undef NDEBUG
11#include <debug.h>
12#include <list.h>
13#include <random.h>
14#include <stdio.h>
15#include "threads/test.h"
16
17/** Maximum number of elements in a linked list that we will
18 test. */
19#define MAX_SIZE 64
20
21/** A linked list element. */
22struct value
23 {
24 struct list_elem elem; /**< List element. */
25 int value; /**< Item value. */
26 };
27
28static void shuffle (struct value[], size_t);
29static bool value_less (const struct list_elem *, const struct list_elem *,
30 void *);
31static void verify_list_fwd (struct list *, int size);
32static void verify_list_bkwd (struct list *, int size);
33
34/** Test the linked list implementation. */
35void
36test (void)
37{
38 int size;
39
40 printf ("testing various size lists:");
41 for (size = 0; size < MAX_SIZE; size++)
42 {
43 int repeat;
44
45 printf (" %d", size);
46 for (repeat = 0; repeat < 10; repeat++)
47 {
48 static struct value values[MAX_SIZE * 4];
49 struct list list;
50 struct list_elem *e;
51 int i, ofs;
52
53 /* Put values 0...SIZE in random order in VALUES. */
54 for (i = 0; i < size; i++)
55 values[i].value = i;
56 shuffle (values, size);
57
58 /* Assemble list. */
59 list_init (&list);
60 for (i = 0; i < size; i++)
61 list_push_back (&list, &values[i].elem);
62
63 /* Verify correct minimum and maximum elements. */
65 ASSERT (size ? list_entry (e, struct value, elem)->value == 0
66 : e == list_begin (&list));
68 ASSERT (size ? list_entry (e, struct value, elem)->value == size - 1
69 : e == list_begin (&list));
70
71 /* Sort and verify list. */
73 verify_list_fwd (&list, size);
74
75 /* Reverse and verify list. */
77 verify_list_bkwd (&list, size);
78
79 /* Shuffle, insert using list_insert_ordered(),
80 and verify ordering. */
81 shuffle (values, size);
82 list_init (&list);
83 for (i = 0; i < size; i++)
84 list_insert_ordered (&list, &values[i].elem,
86 verify_list_fwd (&list, size);
87
88 /* Duplicate some items, uniquify, and verify. */
89 ofs = size;
90 for (e = list_begin (&list); e != list_end (&list);
91 e = list_next (e))
92 {
93 struct value *v = list_entry (e, struct value, elem);
94 int copies = random_ulong () % 4;
95 while (copies-- > 0)
96 {
97 values[ofs].value = v->value;
98 list_insert (e, &values[ofs++].elem);
99 }
100 }
101 ASSERT ((size_t) ofs < sizeof values / sizeof *values);
103 verify_list_fwd (&list, size);
104 }
105 }
106
107 printf (" done\n");
108 printf ("list: PASS\n");
109}
110
111/** Shuffles the CNT elements in ARRAY into random order. */
112static void
113shuffle (struct value *array, size_t cnt)
114{
115 size_t i;
116
117 for (i = 0; i < cnt; i++)
118 {
119 size_t j = i + random_ulong () % (cnt - i);
120 struct value t = array[j];
121 array[j] = array[i];
122 array[i] = t;
123 }
124}
125
126/** Returns true if value A is less than value B, false
127 otherwise. */
128static bool
129value_less (const struct list_elem *a_, const struct list_elem *b_,
130 void *aux UNUSED)
131{
132 const struct value *a = list_entry (a_, struct value, elem);
133 const struct value *b = list_entry (b_, struct value, elem);
134
135 return a->value < b->value;
136}
137
138/** Verifies that LIST contains the values 0...SIZE when traversed
139 in forward order. */
140static void
141verify_list_fwd (struct list *list, int size)
142{
143 struct list_elem *e;
144 int i;
145
146 for (i = 0, e = list_begin (list);
147 i < size && e != list_end (list);
148 i++, e = list_next (e))
149 {
150 struct value *v = list_entry (e, struct value, elem);
151 ASSERT (i == v->value);
152 }
153 ASSERT (i == size);
154 ASSERT (e == list_end (list));
155}
156
157/** Verifies that LIST contains the values 0...SIZE when traversed
158 in reverse order. */
159static void
160verify_list_bkwd (struct list *list, int size)
161{
162 struct list_elem *e;
163 int i;
164
165 for (i = 0, e = list_rbegin (list);
166 i < size && e != list_rend (list);
167 i++, e = list_prev (e))
168 {
169 struct value *v = list_entry (e, struct value, elem);
170 ASSERT (i == v->value);
171 }
172 ASSERT (i == size);
173 ASSERT (e == list_rend (list));
174}
#define ASSERT(CONDITION)
This is outside the header guard so that debug.h may be included multiple times with different settin...
Definition: debug.h:31
#define UNUSED
GCC lets us add "attributes" to functions, function parameters, etc.
Definition: debug.h:7
struct list_elem * list_begin(struct list *list)
Returns the beginning of LIST.
Definition: list.c:72
struct list_elem * list_min(struct list *list, list_less_func *less, void *aux)
Returns the element in LIST with the smallest value according to LESS given auxiliary data AUX.
Definition: list.c:512
struct list_elem * list_rbegin(struct list *list)
Returns the LIST's reverse beginning, for iterating through LIST in reverse order,...
Definition: list.c:103
void list_unique(struct list *list, struct list *duplicates, list_less_func *less, void *aux)
Iterates through LIST and removes all but the first in each set of adjacent elements that are equal a...
Definition: list.c:466
struct list_elem * list_prev(struct list_elem *elem)
Returns the element before ELEM in its list.
Definition: list.c:113
struct list_elem * list_end(struct list *list)
Returns LIST's tail.
Definition: list.c:94
void list_insert(struct list_elem *before, struct list_elem *elem)
Inserts ELEM just before BEFORE, which may be either an interior element or a tail.
Definition: list.c:169
struct list_elem * list_max(struct list *list, list_less_func *less, void *aux)
Returns the element in LIST with the largest value according to LESS given auxiliary data AUX.
Definition: list.c:493
void list_init(struct list *list)
Initializes LIST as an empty list.
Definition: list.c:61
struct list_elem * list_rend(struct list *list)
Returns LIST's head.
Definition: list.c:133
void list_push_back(struct list *list, struct list_elem *elem)
Inserts ELEM at the end of LIST, so that it becomes the back in LIST.
Definition: list.c:217
struct list_elem * list_next(struct list_elem *elem)
Returns the element after ELEM in its list.
Definition: list.c:82
void list_reverse(struct list *list)
Reverses the order of LIST.
Definition: list.c:326
void list_sort(struct list *list, list_less_func *less, void *aux)
Sorts LIST according to LESS given auxiliary data AUX, using a natural iterative merge sort that runs...
Definition: list.c:405
void list_insert_ordered(struct list *list, struct list_elem *elem, list_less_func *less, void *aux)
Inserts ELEM in the proper position in LIST, which must be sorted according to LESS given auxiliary d...
Definition: list.c:446
int printf(const char *format,...)
Writes formatted output to the console.
Definition: stdio.c:79
#define list_entry(LIST_ELEM, STRUCT, MEMBER)
Converts pointer to list element LIST_ELEM into a pointer to the structure that LIST_ELEM is embedded...
Definition: list.h:108
unsigned long random_ulong(void)
Returns a pseudo-random unsigned long.
Definition: random.c:78
#define NULL
Definition: stddef.h:4
Doubly linked list.
Definition: list.h:91
List.
Definition: list.h:98
A linked list element.
Definition: list.c:23
struct list_elem elem
List element.
Definition: list.c:24
int value
Item value.
Definition: list.c:25
#define MAX_SIZE
Test program for lib/kernel/list.c.
Definition: list.c:19
static void shuffle(struct value[], size_t)
static bool value_less(const struct list_elem *, const struct list_elem *, void *)
static void verify_list_bkwd(struct list *, int size)
Verifies that LIST contains the values 0...SIZE when traversed in reverse order.
Definition: list.c:160
void test(void)
Test the linked list implementation.
Definition: list.c:36
static void verify_list_fwd(struct list *, int size)
Verifies that LIST contains the values 0...SIZE when traversed in forward order.
Definition: list.c:141