witness.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #include "test/jemalloc_test.h"
  2. static witness_lock_error_t *witness_lock_error_orig;
  3. static witness_owner_error_t *witness_owner_error_orig;
  4. static witness_not_owner_error_t *witness_not_owner_error_orig;
  5. static witness_depth_error_t *witness_depth_error_orig;
  6. static bool saw_lock_error;
  7. static bool saw_owner_error;
  8. static bool saw_not_owner_error;
  9. static bool saw_depth_error;
  10. static void
  11. witness_lock_error_intercept(const witness_list_t *witnesses,
  12. const witness_t *witness) {
  13. saw_lock_error = true;
  14. }
  15. static void
  16. witness_owner_error_intercept(const witness_t *witness) {
  17. saw_owner_error = true;
  18. }
  19. static void
  20. witness_not_owner_error_intercept(const witness_t *witness) {
  21. saw_not_owner_error = true;
  22. }
  23. static void
  24. witness_depth_error_intercept(const witness_list_t *witnesses,
  25. witness_rank_t rank_inclusive, unsigned depth) {
  26. saw_depth_error = true;
  27. }
  28. static int
  29. witness_comp(const witness_t *a, void *oa, const witness_t *b, void *ob) {
  30. assert_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
  31. assert(oa == (void *)a);
  32. assert(ob == (void *)b);
  33. return strcmp(a->name, b->name);
  34. }
  35. static int
  36. witness_comp_reverse(const witness_t *a, void *oa, const witness_t *b,
  37. void *ob) {
  38. assert_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
  39. assert(oa == (void *)a);
  40. assert(ob == (void *)b);
  41. return -strcmp(a->name, b->name);
  42. }
  43. TEST_BEGIN(test_witness) {
  44. witness_t a, b;
  45. witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
  46. test_skip_if(!config_debug);
  47. witness_assert_lockless(&witness_tsdn);
  48. witness_assert_depth(&witness_tsdn, 0);
  49. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 0);
  50. witness_init(&a, "a", 1, NULL, NULL);
  51. witness_assert_not_owner(&witness_tsdn, &a);
  52. witness_lock(&witness_tsdn, &a);
  53. witness_assert_owner(&witness_tsdn, &a);
  54. witness_assert_depth(&witness_tsdn, 1);
  55. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 1);
  56. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)2U, 0);
  57. witness_init(&b, "b", 2, NULL, NULL);
  58. witness_assert_not_owner(&witness_tsdn, &b);
  59. witness_lock(&witness_tsdn, &b);
  60. witness_assert_owner(&witness_tsdn, &b);
  61. witness_assert_depth(&witness_tsdn, 2);
  62. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 2);
  63. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)2U, 1);
  64. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)3U, 0);
  65. witness_unlock(&witness_tsdn, &a);
  66. witness_assert_depth(&witness_tsdn, 1);
  67. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 1);
  68. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)2U, 1);
  69. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)3U, 0);
  70. witness_unlock(&witness_tsdn, &b);
  71. witness_assert_lockless(&witness_tsdn);
  72. witness_assert_depth(&witness_tsdn, 0);
  73. witness_assert_depth_to_rank(&witness_tsdn, (witness_rank_t)1U, 0);
  74. }
  75. TEST_END
  76. TEST_BEGIN(test_witness_comp) {
  77. witness_t a, b, c, d;
  78. witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
  79. test_skip_if(!config_debug);
  80. witness_assert_lockless(&witness_tsdn);
  81. witness_init(&a, "a", 1, witness_comp, &a);
  82. witness_assert_not_owner(&witness_tsdn, &a);
  83. witness_lock(&witness_tsdn, &a);
  84. witness_assert_owner(&witness_tsdn, &a);
  85. witness_assert_depth(&witness_tsdn, 1);
  86. witness_init(&b, "b", 1, witness_comp, &b);
  87. witness_assert_not_owner(&witness_tsdn, &b);
  88. witness_lock(&witness_tsdn, &b);
  89. witness_assert_owner(&witness_tsdn, &b);
  90. witness_assert_depth(&witness_tsdn, 2);
  91. witness_unlock(&witness_tsdn, &b);
  92. witness_assert_depth(&witness_tsdn, 1);
  93. witness_lock_error_orig = witness_lock_error;
  94. witness_lock_error = witness_lock_error_intercept;
  95. saw_lock_error = false;
  96. witness_init(&c, "c", 1, witness_comp_reverse, &c);
  97. witness_assert_not_owner(&witness_tsdn, &c);
  98. assert_false(saw_lock_error, "Unexpected witness lock error");
  99. witness_lock(&witness_tsdn, &c);
  100. assert_true(saw_lock_error, "Expected witness lock error");
  101. witness_unlock(&witness_tsdn, &c);
  102. witness_assert_depth(&witness_tsdn, 1);
  103. saw_lock_error = false;
  104. witness_init(&d, "d", 1, NULL, NULL);
  105. witness_assert_not_owner(&witness_tsdn, &d);
  106. assert_false(saw_lock_error, "Unexpected witness lock error");
  107. witness_lock(&witness_tsdn, &d);
  108. assert_true(saw_lock_error, "Expected witness lock error");
  109. witness_unlock(&witness_tsdn, &d);
  110. witness_assert_depth(&witness_tsdn, 1);
  111. witness_unlock(&witness_tsdn, &a);
  112. witness_assert_lockless(&witness_tsdn);
  113. witness_lock_error = witness_lock_error_orig;
  114. }
  115. TEST_END
  116. TEST_BEGIN(test_witness_reversal) {
  117. witness_t a, b;
  118. witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
  119. test_skip_if(!config_debug);
  120. witness_lock_error_orig = witness_lock_error;
  121. witness_lock_error = witness_lock_error_intercept;
  122. saw_lock_error = false;
  123. witness_assert_lockless(&witness_tsdn);
  124. witness_init(&a, "a", 1, NULL, NULL);
  125. witness_init(&b, "b", 2, NULL, NULL);
  126. witness_lock(&witness_tsdn, &b);
  127. witness_assert_depth(&witness_tsdn, 1);
  128. assert_false(saw_lock_error, "Unexpected witness lock error");
  129. witness_lock(&witness_tsdn, &a);
  130. assert_true(saw_lock_error, "Expected witness lock error");
  131. witness_unlock(&witness_tsdn, &a);
  132. witness_assert_depth(&witness_tsdn, 1);
  133. witness_unlock(&witness_tsdn, &b);
  134. witness_assert_lockless(&witness_tsdn);
  135. witness_lock_error = witness_lock_error_orig;
  136. }
  137. TEST_END
  138. TEST_BEGIN(test_witness_recursive) {
  139. witness_t a;
  140. witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
  141. test_skip_if(!config_debug);
  142. witness_not_owner_error_orig = witness_not_owner_error;
  143. witness_not_owner_error = witness_not_owner_error_intercept;
  144. saw_not_owner_error = false;
  145. witness_lock_error_orig = witness_lock_error;
  146. witness_lock_error = witness_lock_error_intercept;
  147. saw_lock_error = false;
  148. witness_assert_lockless(&witness_tsdn);
  149. witness_init(&a, "a", 1, NULL, NULL);
  150. witness_lock(&witness_tsdn, &a);
  151. assert_false(saw_lock_error, "Unexpected witness lock error");
  152. assert_false(saw_not_owner_error, "Unexpected witness not owner error");
  153. witness_lock(&witness_tsdn, &a);
  154. assert_true(saw_lock_error, "Expected witness lock error");
  155. assert_true(saw_not_owner_error, "Expected witness not owner error");
  156. witness_unlock(&witness_tsdn, &a);
  157. witness_assert_lockless(&witness_tsdn);
  158. witness_owner_error = witness_owner_error_orig;
  159. witness_lock_error = witness_lock_error_orig;
  160. }
  161. TEST_END
  162. TEST_BEGIN(test_witness_unlock_not_owned) {
  163. witness_t a;
  164. witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
  165. test_skip_if(!config_debug);
  166. witness_owner_error_orig = witness_owner_error;
  167. witness_owner_error = witness_owner_error_intercept;
  168. saw_owner_error = false;
  169. witness_assert_lockless(&witness_tsdn);
  170. witness_init(&a, "a", 1, NULL, NULL);
  171. assert_false(saw_owner_error, "Unexpected owner error");
  172. witness_unlock(&witness_tsdn, &a);
  173. assert_true(saw_owner_error, "Expected owner error");
  174. witness_assert_lockless(&witness_tsdn);
  175. witness_owner_error = witness_owner_error_orig;
  176. }
  177. TEST_END
  178. TEST_BEGIN(test_witness_depth) {
  179. witness_t a;
  180. witness_tsdn_t witness_tsdn = { WITNESS_TSD_INITIALIZER };
  181. test_skip_if(!config_debug);
  182. witness_depth_error_orig = witness_depth_error;
  183. witness_depth_error = witness_depth_error_intercept;
  184. saw_depth_error = false;
  185. witness_assert_lockless(&witness_tsdn);
  186. witness_assert_depth(&witness_tsdn, 0);
  187. witness_init(&a, "a", 1, NULL, NULL);
  188. assert_false(saw_depth_error, "Unexpected depth error");
  189. witness_assert_lockless(&witness_tsdn);
  190. witness_assert_depth(&witness_tsdn, 0);
  191. witness_lock(&witness_tsdn, &a);
  192. witness_assert_lockless(&witness_tsdn);
  193. witness_assert_depth(&witness_tsdn, 0);
  194. assert_true(saw_depth_error, "Expected depth error");
  195. witness_unlock(&witness_tsdn, &a);
  196. witness_assert_lockless(&witness_tsdn);
  197. witness_assert_depth(&witness_tsdn, 0);
  198. witness_depth_error = witness_depth_error_orig;
  199. }
  200. TEST_END
  201. int
  202. main(void) {
  203. return test(
  204. test_witness,
  205. test_witness_comp,
  206. test_witness_reversal,
  207. test_witness_recursive,
  208. test_witness_unlock_not_owned,
  209. test_witness_depth);
  210. }