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