batch_alloc.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include "test/jemalloc_test.h"
  2. #include "test/bench.h"
  3. #define MIBLEN 8
  4. static size_t mib[MIBLEN];
  5. static size_t miblen = MIBLEN;
  6. #define TINY_BATCH 10
  7. #define TINY_BATCH_ITER (10 * 1000 * 1000)
  8. #define HUGE_BATCH (1000 * 1000)
  9. #define HUGE_BATCH_ITER 100
  10. #define LEN (100 * 1000 * 1000)
  11. static void *batch_ptrs[LEN];
  12. static size_t batch_ptrs_next = 0;
  13. static void *item_ptrs[LEN];
  14. static size_t item_ptrs_next = 0;
  15. #define SIZE 7
  16. typedef struct batch_alloc_packet_s batch_alloc_packet_t;
  17. struct batch_alloc_packet_s {
  18. void **ptrs;
  19. size_t num;
  20. size_t size;
  21. int flags;
  22. };
  23. static void
  24. batch_alloc_wrapper(size_t batch) {
  25. batch_alloc_packet_t batch_alloc_packet =
  26. {batch_ptrs + batch_ptrs_next, batch, SIZE, 0};
  27. size_t filled;
  28. size_t len = sizeof(size_t);
  29. assert_d_eq(mallctlbymib(mib, miblen, &filled, &len,
  30. &batch_alloc_packet, sizeof(batch_alloc_packet)), 0, "");
  31. assert_zu_eq(filled, batch, "");
  32. }
  33. static void
  34. item_alloc_wrapper(size_t batch) {
  35. for (size_t i = item_ptrs_next, end = i + batch; i < end; ++i) {
  36. item_ptrs[i] = malloc(SIZE);
  37. }
  38. }
  39. static void
  40. release_and_clear(void **ptrs, size_t len) {
  41. for (size_t i = 0; i < len; ++i) {
  42. void *p = ptrs[i];
  43. assert_ptr_not_null(p, "allocation failed");
  44. sdallocx(p, SIZE, 0);
  45. ptrs[i] = NULL;
  46. }
  47. }
  48. static void
  49. batch_alloc_without_free(size_t batch) {
  50. batch_alloc_wrapper(batch);
  51. batch_ptrs_next += batch;
  52. }
  53. static void
  54. item_alloc_without_free(size_t batch) {
  55. item_alloc_wrapper(batch);
  56. item_ptrs_next += batch;
  57. }
  58. static void
  59. batch_alloc_with_free(size_t batch) {
  60. batch_alloc_wrapper(batch);
  61. release_and_clear(batch_ptrs + batch_ptrs_next, batch);
  62. batch_ptrs_next += batch;
  63. }
  64. static void
  65. item_alloc_with_free(size_t batch) {
  66. item_alloc_wrapper(batch);
  67. release_and_clear(item_ptrs + item_ptrs_next, batch);
  68. item_ptrs_next += batch;
  69. }
  70. static void
  71. compare_without_free(size_t batch, size_t iter,
  72. void (*batch_alloc_without_free_func)(void),
  73. void (*item_alloc_without_free_func)(void)) {
  74. assert(batch_ptrs_next == 0);
  75. assert(item_ptrs_next == 0);
  76. assert(batch * iter <= LEN);
  77. for (size_t i = 0; i < iter; ++i) {
  78. batch_alloc_without_free_func();
  79. item_alloc_without_free_func();
  80. }
  81. release_and_clear(batch_ptrs, batch_ptrs_next);
  82. batch_ptrs_next = 0;
  83. release_and_clear(item_ptrs, item_ptrs_next);
  84. item_ptrs_next = 0;
  85. compare_funcs(0, iter,
  86. "batch allocation", batch_alloc_without_free_func,
  87. "item allocation", item_alloc_without_free_func);
  88. release_and_clear(batch_ptrs, batch_ptrs_next);
  89. batch_ptrs_next = 0;
  90. release_and_clear(item_ptrs, item_ptrs_next);
  91. item_ptrs_next = 0;
  92. }
  93. static void
  94. compare_with_free(size_t batch, size_t iter,
  95. void (*batch_alloc_with_free_func)(void),
  96. void (*item_alloc_with_free_func)(void)) {
  97. assert(batch_ptrs_next == 0);
  98. assert(item_ptrs_next == 0);
  99. assert(batch * iter <= LEN);
  100. for (size_t i = 0; i < iter; ++i) {
  101. batch_alloc_with_free_func();
  102. item_alloc_with_free_func();
  103. }
  104. batch_ptrs_next = 0;
  105. item_ptrs_next = 0;
  106. compare_funcs(0, iter,
  107. "batch allocation", batch_alloc_with_free_func,
  108. "item allocation", item_alloc_with_free_func);
  109. batch_ptrs_next = 0;
  110. item_ptrs_next = 0;
  111. }
  112. static void
  113. batch_alloc_without_free_tiny() {
  114. batch_alloc_without_free(TINY_BATCH);
  115. }
  116. static void
  117. item_alloc_without_free_tiny() {
  118. item_alloc_without_free(TINY_BATCH);
  119. }
  120. TEST_BEGIN(test_tiny_batch_without_free) {
  121. compare_without_free(TINY_BATCH, TINY_BATCH_ITER,
  122. batch_alloc_without_free_tiny, item_alloc_without_free_tiny);
  123. }
  124. TEST_END
  125. static void
  126. batch_alloc_with_free_tiny() {
  127. batch_alloc_with_free(TINY_BATCH);
  128. }
  129. static void
  130. item_alloc_with_free_tiny() {
  131. item_alloc_with_free(TINY_BATCH);
  132. }
  133. TEST_BEGIN(test_tiny_batch_with_free) {
  134. compare_with_free(TINY_BATCH, TINY_BATCH_ITER,
  135. batch_alloc_with_free_tiny, item_alloc_with_free_tiny);
  136. }
  137. TEST_END
  138. static void
  139. batch_alloc_without_free_huge() {
  140. batch_alloc_without_free(HUGE_BATCH);
  141. }
  142. static void
  143. item_alloc_without_free_huge() {
  144. item_alloc_without_free(HUGE_BATCH);
  145. }
  146. TEST_BEGIN(test_huge_batch_without_free) {
  147. compare_without_free(HUGE_BATCH, HUGE_BATCH_ITER,
  148. batch_alloc_without_free_huge, item_alloc_without_free_huge);
  149. }
  150. TEST_END
  151. static void
  152. batch_alloc_with_free_huge() {
  153. batch_alloc_with_free(HUGE_BATCH);
  154. }
  155. static void
  156. item_alloc_with_free_huge() {
  157. item_alloc_with_free(HUGE_BATCH);
  158. }
  159. TEST_BEGIN(test_huge_batch_with_free) {
  160. compare_with_free(HUGE_BATCH, HUGE_BATCH_ITER,
  161. batch_alloc_with_free_huge, item_alloc_with_free_huge);
  162. }
  163. TEST_END
  164. int main(void) {
  165. assert_d_eq(mallctlnametomib("experimental.batch_alloc", mib, &miblen),
  166. 0, "");
  167. return test_no_reentrancy(
  168. test_tiny_batch_without_free,
  169. test_tiny_batch_with_free,
  170. test_huge_batch_without_free,
  171. test_huge_batch_with_free);
  172. }