ql.c 4.4 KB

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