1 1.1 christos #include "test/jemalloc_test.h" 2 1.1 christos 3 1.1 christos #include "jemalloc/internal/ql.h" 4 1.1 christos 5 1.1 christos /* Number of ring entries, in [2..26]. */ 6 1.1 christos #define NENTRIES 9 7 1.1 christos 8 1.1 christos typedef struct list_s list_t; 9 1.1 christos typedef ql_head(list_t) list_head_t; 10 1.1 christos 11 1.1 christos struct list_s { 12 1.1 christos ql_elm(list_t) link; 13 1.1 christos char id; 14 1.1 christos }; 15 1.1 christos 16 1.1 christos static void 17 1.1 christos test_empty_list(list_head_t *head) { 18 1.1 christos list_t *t; 19 1.1 christos unsigned i; 20 1.1 christos 21 1.1 christos assert_ptr_null(ql_first(head), "Unexpected element for empty list"); 22 1.1 christos assert_ptr_null(ql_last(head, link), 23 1.1 christos "Unexpected element for empty list"); 24 1.1 christos 25 1.1 christos i = 0; 26 1.1 christos ql_foreach(t, head, link) { 27 1.1 christos i++; 28 1.1 christos } 29 1.1 christos assert_u_eq(i, 0, "Unexpected element for empty list"); 30 1.1 christos 31 1.1 christos i = 0; 32 1.1 christos ql_reverse_foreach(t, head, link) { 33 1.1 christos i++; 34 1.1 christos } 35 1.1 christos assert_u_eq(i, 0, "Unexpected element for empty list"); 36 1.1 christos } 37 1.1 christos 38 1.1 christos TEST_BEGIN(test_ql_empty) { 39 1.1 christos list_head_t head; 40 1.1 christos 41 1.1 christos ql_new(&head); 42 1.1 christos test_empty_list(&head); 43 1.1 christos } 44 1.1 christos TEST_END 45 1.1 christos 46 1.1 christos static void 47 1.1 christos init_entries(list_t *entries, unsigned nentries) { 48 1.1 christos unsigned i; 49 1.1 christos 50 1.1 christos for (i = 0; i < nentries; i++) { 51 1.1 christos entries[i].id = 'a' + i; 52 1.1 christos ql_elm_new(&entries[i], link); 53 1.1 christos } 54 1.1 christos } 55 1.1 christos 56 1.1 christos static void 57 1.1 christos test_entries_list(list_head_t *head, list_t *entries, unsigned nentries) { 58 1.1 christos list_t *t; 59 1.1 christos unsigned i; 60 1.1 christos 61 1.1 christos assert_c_eq(ql_first(head)->id, entries[0].id, "Element id mismatch"); 62 1.1 christos assert_c_eq(ql_last(head, link)->id, entries[nentries-1].id, 63 1.1 christos "Element id mismatch"); 64 1.1 christos 65 1.1 christos i = 0; 66 1.1 christos ql_foreach(t, head, link) { 67 1.1 christos assert_c_eq(t->id, entries[i].id, "Element id mismatch"); 68 1.1 christos i++; 69 1.1 christos } 70 1.1 christos 71 1.1 christos i = 0; 72 1.1 christos ql_reverse_foreach(t, head, link) { 73 1.1 christos assert_c_eq(t->id, entries[nentries-i-1].id, 74 1.1 christos "Element id mismatch"); 75 1.1 christos i++; 76 1.1 christos } 77 1.1 christos 78 1.1 christos for (i = 0; i < nentries-1; i++) { 79 1.1 christos t = ql_next(head, &entries[i], link); 80 1.1 christos assert_c_eq(t->id, entries[i+1].id, "Element id mismatch"); 81 1.1 christos } 82 1.1 christos assert_ptr_null(ql_next(head, &entries[nentries-1], link), 83 1.1 christos "Unexpected element"); 84 1.1 christos 85 1.1 christos assert_ptr_null(ql_prev(head, &entries[0], link), "Unexpected element"); 86 1.1 christos for (i = 1; i < nentries; i++) { 87 1.1 christos t = ql_prev(head, &entries[i], link); 88 1.1 christos assert_c_eq(t->id, entries[i-1].id, "Element id mismatch"); 89 1.1 christos } 90 1.1 christos } 91 1.1 christos 92 1.1 christos TEST_BEGIN(test_ql_tail_insert) { 93 1.1 christos list_head_t head; 94 1.1 christos list_t entries[NENTRIES]; 95 1.1 christos unsigned i; 96 1.1 christos 97 1.1 christos ql_new(&head); 98 1.1 christos init_entries(entries, sizeof(entries)/sizeof(list_t)); 99 1.1 christos for (i = 0; i < NENTRIES; i++) { 100 1.1 christos ql_tail_insert(&head, &entries[i], link); 101 1.1 christos } 102 1.1 christos 103 1.1 christos test_entries_list(&head, entries, NENTRIES); 104 1.1 christos } 105 1.1 christos TEST_END 106 1.1 christos 107 1.1 christos TEST_BEGIN(test_ql_tail_remove) { 108 1.1 christos list_head_t head; 109 1.1 christos list_t entries[NENTRIES]; 110 1.1 christos unsigned i; 111 1.1 christos 112 1.1 christos ql_new(&head); 113 1.1 christos init_entries(entries, sizeof(entries)/sizeof(list_t)); 114 1.1 christos for (i = 0; i < NENTRIES; i++) { 115 1.1 christos ql_tail_insert(&head, &entries[i], link); 116 1.1 christos } 117 1.1 christos 118 1.1 christos for (i = 0; i < NENTRIES; i++) { 119 1.1 christos test_entries_list(&head, entries, NENTRIES-i); 120 1.1 christos ql_tail_remove(&head, list_t, link); 121 1.1 christos } 122 1.1 christos test_empty_list(&head); 123 1.1 christos } 124 1.1 christos TEST_END 125 1.1 christos 126 1.1 christos TEST_BEGIN(test_ql_head_insert) { 127 1.1 christos list_head_t head; 128 1.1 christos list_t entries[NENTRIES]; 129 1.1 christos unsigned i; 130 1.1 christos 131 1.1 christos ql_new(&head); 132 1.1 christos init_entries(entries, sizeof(entries)/sizeof(list_t)); 133 1.1 christos for (i = 0; i < NENTRIES; i++) { 134 1.1 christos ql_head_insert(&head, &entries[NENTRIES-i-1], link); 135 1.1 christos } 136 1.1 christos 137 1.1 christos test_entries_list(&head, entries, NENTRIES); 138 1.1 christos } 139 1.1 christos TEST_END 140 1.1 christos 141 1.1 christos TEST_BEGIN(test_ql_head_remove) { 142 1.1 christos list_head_t head; 143 1.1 christos list_t entries[NENTRIES]; 144 1.1 christos unsigned i; 145 1.1 christos 146 1.1 christos ql_new(&head); 147 1.1 christos init_entries(entries, sizeof(entries)/sizeof(list_t)); 148 1.1 christos for (i = 0; i < NENTRIES; i++) { 149 1.1 christos ql_head_insert(&head, &entries[NENTRIES-i-1], link); 150 1.1 christos } 151 1.1 christos 152 1.1 christos for (i = 0; i < NENTRIES; i++) { 153 1.1 christos test_entries_list(&head, &entries[i], NENTRIES-i); 154 1.1 christos ql_head_remove(&head, list_t, link); 155 1.1 christos } 156 1.1 christos test_empty_list(&head); 157 1.1 christos } 158 1.1 christos TEST_END 159 1.1 christos 160 1.1 christos TEST_BEGIN(test_ql_insert) { 161 1.1 christos list_head_t head; 162 1.1 christos list_t entries[8]; 163 1.1 christos list_t *a, *b, *c, *d, *e, *f, *g, *h; 164 1.1 christos 165 1.1 christos ql_new(&head); 166 1.1 christos init_entries(entries, sizeof(entries)/sizeof(list_t)); 167 1.1 christos a = &entries[0]; 168 1.1 christos b = &entries[1]; 169 1.1 christos c = &entries[2]; 170 1.1 christos d = &entries[3]; 171 1.1 christos e = &entries[4]; 172 1.1 christos f = &entries[5]; 173 1.1 christos g = &entries[6]; 174 1.1 christos h = &entries[7]; 175 1.1 christos 176 1.1 christos /* 177 1.1 christos * ql_remove(), ql_before_insert(), and ql_after_insert() are used 178 1.1 christos * internally by other macros that are already tested, so there's no 179 1.1 christos * need to test them completely. However, insertion/deletion from the 180 1.1 christos * middle of lists is not otherwise tested; do so here. 181 1.1 christos */ 182 1.1 christos ql_tail_insert(&head, f, link); 183 1.1 christos ql_before_insert(&head, f, b, link); 184 1.1 christos ql_before_insert(&head, f, c, link); 185 1.1 christos ql_after_insert(f, h, link); 186 1.1 christos ql_after_insert(f, g, link); 187 1.1 christos ql_before_insert(&head, b, a, link); 188 1.1 christos ql_after_insert(c, d, link); 189 1.1 christos ql_before_insert(&head, f, e, link); 190 1.1 christos 191 1.1 christos test_entries_list(&head, entries, sizeof(entries)/sizeof(list_t)); 192 1.1 christos } 193 1.1 christos TEST_END 194 1.1 christos 195 1.1 christos int 196 1.1 christos main(void) { 197 1.1 christos return test( 198 1.1 christos test_ql_empty, 199 1.1 christos test_ql_tail_insert, 200 1.1 christos test_ql_tail_remove, 201 1.1 christos test_ql_head_insert, 202 1.1 christos test_ql_head_remove, 203 1.1 christos test_ql_insert); 204 1.1 christos } 205