ql.c 4.4 KB

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