Home | History | Annotate | Line # | Download | only in unit
      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