diff --git a/test/stress/batch_alloc.c b/test/stress/batch_alloc.c index b203e05e..14a870e7 100644 --- a/test/stress/batch_alloc.c +++ b/test/stress/batch_alloc.c @@ -1,10 +1,15 @@ #include "test/jemalloc_test.h" #include "test/bench.h" -#define BATCH (1000 * 1000) -#define HUGE_BATCH (100 * BATCH) -static void *batch_ptrs[HUGE_BATCH]; -static void *item_ptrs[HUGE_BATCH]; +#define TINY_BATCH 10 +#define TINY_BATCH_ITER (10 * 1000 * 1000) +#define HUGE_BATCH (1000 * 1000) +#define HUGE_BATCH_ITER 100 +#define LEN (100 * 1000 * 1000) +static void *batch_ptrs[LEN]; +static size_t batch_ptrs_next = 0; +static void *item_ptrs[LEN]; +static size_t item_ptrs_next = 0; #define SIZE 7 @@ -18,7 +23,8 @@ struct batch_alloc_packet_s { static void batch_alloc_wrapper(size_t batch) { - batch_alloc_packet_t batch_alloc_packet = {batch_ptrs, batch, SIZE, 0}; + batch_alloc_packet_t batch_alloc_packet = + {batch_ptrs + batch_ptrs_next, batch, SIZE, 0}; size_t filled; size_t len = sizeof(size_t); assert_d_eq(mallctl("experimental.batch_alloc", &filled, &len, @@ -28,14 +34,14 @@ batch_alloc_wrapper(size_t batch) { static void item_alloc_wrapper(size_t batch) { - for (size_t i = 0; i < batch; ++i) { + for (size_t i = item_ptrs_next, end = i + batch; i < end; ++i) { item_ptrs[i] = malloc(SIZE); } } static void -release_and_clear(void **ptrs, size_t batch) { - for (size_t i = 0; i < batch; ++i) { +release_and_clear(void **ptrs, size_t len) { + for (size_t i = 0; i < len; ++i) { void *p = ptrs[i]; assert_ptr_not_null(p, "allocation failed"); sdallocx(p, SIZE, 0); @@ -44,45 +50,143 @@ release_and_clear(void **ptrs, size_t batch) { } static void -batch_alloc_small_can_repeat() { - batch_alloc_wrapper(BATCH); - release_and_clear(batch_ptrs, BATCH); +batch_alloc_without_free(size_t batch) { + batch_alloc_wrapper(batch); + batch_ptrs_next += batch; } static void -item_alloc_small_can_repeat() { - item_alloc_wrapper(BATCH); - release_and_clear(item_ptrs, BATCH); +item_alloc_without_free(size_t batch) { + item_alloc_wrapper(batch); + item_ptrs_next += batch; } -TEST_BEGIN(test_small_batch_with_free) { - compare_funcs(10, 100, - "batch allocation", batch_alloc_small_can_repeat, - "item allocation", item_alloc_small_can_repeat); +static void +batch_alloc_with_free(size_t batch) { + batch_alloc_wrapper(batch); + release_and_clear(batch_ptrs + batch_ptrs_next, batch); + batch_ptrs_next += batch; +} + +static void +item_alloc_with_free(size_t batch) { + item_alloc_wrapper(batch); + release_and_clear(item_ptrs + item_ptrs_next, batch); + item_ptrs_next += batch; +} + +static void +compare_without_free(size_t batch, size_t iter, + void (*batch_alloc_without_free_func)(void), + void (*item_alloc_without_free_func)(void)) { + assert(batch_ptrs_next == 0); + assert(item_ptrs_next == 0); + assert(batch * iter <= LEN); + for (size_t i = 0; i < iter; ++i) { + batch_alloc_without_free_func(); + item_alloc_without_free_func(); + } + release_and_clear(batch_ptrs, batch_ptrs_next); + batch_ptrs_next = 0; + release_and_clear(item_ptrs, item_ptrs_next); + item_ptrs_next = 0; + compare_funcs(0, iter, + "batch allocation", batch_alloc_without_free_func, + "item allocation", item_alloc_without_free_func); + release_and_clear(batch_ptrs, batch_ptrs_next); + batch_ptrs_next = 0; + release_and_clear(item_ptrs, item_ptrs_next); + item_ptrs_next = 0; +} + +static void +compare_with_free(size_t batch, size_t iter, + void (*batch_alloc_with_free_func)(void), + void (*item_alloc_with_free_func)(void)) { + assert(batch_ptrs_next == 0); + assert(item_ptrs_next == 0); + assert(batch * iter <= LEN); + for (size_t i = 0; i < iter; ++i) { + batch_alloc_with_free_func(); + item_alloc_with_free_func(); + } + batch_ptrs_next = 0; + item_ptrs_next = 0; + compare_funcs(0, iter, + "batch allocation", batch_alloc_with_free_func, + "item allocation", item_alloc_with_free_func); + batch_ptrs_next = 0; + item_ptrs_next = 0; +} + +static void +batch_alloc_without_free_tiny() { + batch_alloc_without_free(TINY_BATCH); +} + +static void +item_alloc_without_free_tiny() { + item_alloc_without_free(TINY_BATCH); +} + +TEST_BEGIN(test_tiny_batch_without_free) { + compare_without_free(TINY_BATCH, TINY_BATCH_ITER, + batch_alloc_without_free_tiny, item_alloc_without_free_tiny); } TEST_END static void -batch_alloc_huge_cannot_repeat() { - batch_alloc_wrapper(HUGE_BATCH); +batch_alloc_with_free_tiny() { + batch_alloc_with_free(TINY_BATCH); } static void -item_alloc_huge_cannot_repeat() { - item_alloc_wrapper(HUGE_BATCH); +item_alloc_with_free_tiny() { + item_alloc_with_free(TINY_BATCH); +} + +TEST_BEGIN(test_tiny_batch_with_free) { + compare_with_free(TINY_BATCH, TINY_BATCH_ITER, + batch_alloc_with_free_tiny, item_alloc_with_free_tiny); +} +TEST_END + +static void +batch_alloc_without_free_huge() { + batch_alloc_without_free(HUGE_BATCH); +} + +static void +item_alloc_without_free_huge() { + item_alloc_without_free(HUGE_BATCH); } TEST_BEGIN(test_huge_batch_without_free) { - compare_funcs(0, 1, - "batch allocation", batch_alloc_huge_cannot_repeat, - "item allocation", item_alloc_huge_cannot_repeat); - release_and_clear(batch_ptrs, HUGE_BATCH); - release_and_clear(item_ptrs, HUGE_BATCH); + compare_without_free(HUGE_BATCH, HUGE_BATCH_ITER, + batch_alloc_without_free_huge, item_alloc_without_free_huge); +} +TEST_END + +static void +batch_alloc_with_free_huge() { + batch_alloc_with_free(HUGE_BATCH); +} + +static void +item_alloc_with_free_huge() { + item_alloc_with_free(HUGE_BATCH); +} + +TEST_BEGIN(test_huge_batch_with_free) { + compare_with_free(HUGE_BATCH, HUGE_BATCH_ITER, + batch_alloc_with_free_huge, item_alloc_with_free_huge); } TEST_END int main(void) { return test_no_reentrancy( - test_small_batch_with_free, - test_huge_batch_without_free); + test_tiny_batch_without_free, + test_tiny_batch_with_free, + test_huge_batch_without_free, + test_huge_batch_with_free); }