diff --git a/Makefile.in b/Makefile.in index a964f07e..195084d6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -332,10 +332,15 @@ TESTS_STRESS := $(srcroot)test/stress/batch_alloc.c \ $(srcroot)test/stress/large_microbench.c \ $(srcroot)test/stress/mallctl.c \ $(srcroot)test/stress/microbench.c +ifeq (@enable_cxx@, 1) +TESTS_STRESS_CPP := $(srcroot)test/stress/cpp/microbench.cpp +else +TESTS_STRESS_CPP := +endif TESTS := $(TESTS_UNIT) $(TESTS_INTEGRATION) $(TESTS_INTEGRATION_CPP) \ - $(TESTS_ANALYZE) $(TESTS_STRESS) + $(TESTS_ANALYZE) $(TESTS_STRESS) $(TESTS_STRESS_CPP) PRIVATE_NAMESPACE_HDRS := $(objroot)include/jemalloc/internal/private_namespace.h $(objroot)include/jemalloc/internal/private_namespace_jet.h PRIVATE_NAMESPACE_GEN_HDRS := $(PRIVATE_NAMESPACE_HDRS:%.h=%.gen.h) @@ -362,9 +367,10 @@ TESTS_INTEGRATION_OBJS := $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%.$(O)) TESTS_INTEGRATION_CPP_OBJS := $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%.$(O)) TESTS_ANALYZE_OBJS := $(TESTS_ANALYZE:$(srcroot)%.c=$(objroot)%.$(O)) TESTS_STRESS_OBJS := $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%.$(O)) +TESTS_STRESS_CPP_OBJS := $(TESTS_STRESS_CPP:$(srcroot)%.cpp=$(objroot)%.$(O)) TESTS_OBJS := $(TESTS_UNIT_OBJS) $(TESTS_INTEGRATION_OBJS) $(TESTS_ANALYZE_OBJS) \ $(TESTS_STRESS_OBJS) -TESTS_CPP_OBJS := $(TESTS_INTEGRATION_CPP_OBJS) +TESTS_CPP_OBJS := $(TESTS_INTEGRATION_CPP_OBJS) $(TESTS_STRESS_CPP_OBJS) .PHONY: all dist build_doc_html build_doc_man build_doc .PHONY: install_bin install_include install_lib @@ -454,6 +460,7 @@ $(TESTS_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST $(TESTS_INTEGRATION_CPP_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_CPP_TEST $(TESTS_ANALYZE_OBJS): CPPFLAGS += -DJEMALLOC_ANALYZE_TEST $(TESTS_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST +$(TESTS_STRESS_CPP_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_CPP_TEST $(TESTS_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c $(TESTS_CPP_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.cpp $(TESTS_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include @@ -474,7 +481,7 @@ $(TESTS_OBJS) $(TESTS_CPP_OBJS): $(objroot)test/include/test/jemalloc_test.h endif $(C_OBJS) $(CPP_OBJS) $(C_PIC_OBJS) $(CPP_PIC_OBJS) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(TESTS_INTEGRATION_OBJS) $(TESTS_INTEGRATION_CPP_OBJS): $(objroot)include/jemalloc/internal/private_namespace.h -$(C_JET_OBJS) $(C_TESTLIB_UNIT_OBJS) $(C_TESTLIB_ANALYZE_OBJS) $(C_TESTLIB_STRESS_OBJS) $(TESTS_UNIT_OBJS) $(TESTS_ANALYZE_OBJS) $(TESTS_STRESS_OBJS): $(objroot)include/jemalloc/internal/private_namespace_jet.h +$(C_JET_OBJS) $(C_TESTLIB_UNIT_OBJS) $(C_TESTLIB_ANALYZE_OBJS) $(C_TESTLIB_STRESS_OBJS) $(TESTS_UNIT_OBJS) $(TESTS_ANALYZE_OBJS) $(TESTS_STRESS_OBJS) $(TESTS_STRESS_CPP_OBJS): $(objroot)include/jemalloc/internal/private_namespace_jet.h $(C_SYM_OBJS) $(C_OBJS) $(C_PIC_OBJS) $(C_JET_SYM_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): %.$(O): @mkdir -p $(@D) @@ -664,7 +671,7 @@ endif tests_unit: $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%$(EXE)) tests_integration: $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%$(EXE)) $(TESTS_INTEGRATION_CPP:$(srcroot)%.cpp=$(objroot)%$(EXE)) tests_analyze: $(TESTS_ANALYZE:$(srcroot)%.c=$(objroot)%$(EXE)) -tests_stress: $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%$(EXE)) +tests_stress: $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%$(EXE)) $(TESTS_STRESS_CPP:$(srcroot)%.cpp=$(objroot)%$(EXE)) tests: tests_unit tests_integration tests_analyze tests_stress check_unit_dir: @@ -697,6 +704,7 @@ else endif stress: tests_stress stress_dir $(SHELL) $(objroot)test/test.sh $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%) + $(SHELL) $(objroot)test/test.sh $(TESTS_STRESS_CPP:$(srcroot)%.cpp=$(objroot)%) check: check_unit check_integration check_integration_decay check_integration_prof clean: diff --git a/test/include/test/bench.h b/test/include/test/bench.h index c2f78a71..7421b4d2 100644 --- a/test/include/test/bench.h +++ b/test/include/test/bench.h @@ -23,7 +23,7 @@ fmt_nsecs(uint64_t usec, uint64_t iters, char *buf) { uint64_t nsecs_per_iter1000 = nsec1000 / iters; uint64_t intpart = nsecs_per_iter1000 / 1000; uint64_t fracpart = nsecs_per_iter1000 % 1000; - malloc_snprintf(buf, FMT_NSECS_BUF_SIZE, "%"FMTu64".%03"FMTu64, intpart, + malloc_snprintf(buf, FMT_NSECS_BUF_SIZE, "%" FMTu64 ".%03" FMTu64, intpart, fracpart); } @@ -40,8 +40,8 @@ compare_funcs(uint64_t nwarmup, uint64_t niter, const char *name_a, return; } - time_func(&timer_a, nwarmup, niter, func_a); - time_func(&timer_b, nwarmup, niter, func_b); + time_func(&timer_a, nwarmup, niter, (void (*)())func_a); + time_func(&timer_b, nwarmup, niter, (void (*)())func_b); uint64_t usec_a = timer_usec(&timer_a); char buf_a[FMT_NSECS_BUF_SIZE]; @@ -52,8 +52,8 @@ compare_funcs(uint64_t nwarmup, uint64_t niter, const char *name_a, fmt_nsecs(usec_b, niter, buf_b); timer_ratio(&timer_a, &timer_b, ratio_buf, sizeof(ratio_buf)); - malloc_printf("%"FMTu64" iterations, %s=%"FMTu64"us (%s ns/iter), " - "%s=%"FMTu64"us (%s ns/iter), time consumption ratio=%s:1\n", + malloc_printf("%" FMTu64 " iterations, %s=%" FMTu64 "us (%s ns/iter), " + "%s=%" FMTu64 "us (%s ns/iter), time consumption ratio=%s:1\n", niter, name_a, usec_a, buf_a, name_b, usec_b, buf_b, ratio_buf); dallocx(p, 0); diff --git a/test/include/test/jemalloc_test.h.in b/test/include/test/jemalloc_test.h.in index 3f8c0da7..600d993c 100644 --- a/test/include/test/jemalloc_test.h.in +++ b/test/include/test/jemalloc_test.h.in @@ -88,7 +88,8 @@ static const bool config_debug = * public jemalloc interfaces with jet_ prefixes, so that stress tests can use * a separate allocator for their internal data structures. */ -#elif defined(JEMALLOC_STRESS_TEST) +#elif defined(JEMALLOC_STRESS_TEST) || \ + defined(JEMALLOC_STRESS_CPP_TEST) # include "jemalloc/jemalloc@install_suffix@.h" # include "jemalloc/jemalloc_protos_jet.h" diff --git a/test/stress/cpp/microbench.cpp b/test/stress/cpp/microbench.cpp new file mode 100644 index 00000000..65f41dea --- /dev/null +++ b/test/stress/cpp/microbench.cpp @@ -0,0 +1,83 @@ +#include "test/jemalloc_test.h" +#include "test/bench.h" + +static void +malloc_free(void) { + void *p = malloc(1); + expect_ptr_not_null(p, "Unexpected new failure"); + free(p); +} + +static void +new_delete(void) { + auto p = ::operator new(1); + expect_ptr_not_null(p, "Unexpected new failure"); + ::operator delete(p); +} + +static void +malloc_free_array(void) { + void *p = malloc(sizeof(int)*8); + expect_ptr_not_null(p, "Unexpected new[] failure"); + free(p); +} + +static void +new_delete_array(void) { + auto p = new int[8]; + expect_ptr_not_null(p, "Unexpected new[] failure"); + delete[] p; +} + +#if __cpp_sized_deallocation >= 201309 +static void +new_sized_delete(void) { + auto p = ::operator new(1); + expect_ptr_not_null(p, "Unexpected new failure"); + ::operator delete(p, 1); +} + +static void +malloc_sdallocx(void) { + void *p = malloc(1); + expect_ptr_not_null(p, "Unexpected new failure"); + sdallocx(p, 1, 0); +} +#endif + +TEST_BEGIN(test_free_vs_delete) { + compare_funcs(10*1000*1000, 100*1000*1000, + "malloc_free", (void *)malloc_free, + "new_delete", (void *)new_delete); +} +TEST_END + +TEST_BEGIN(test_free_array_vs_delete_array) { + compare_funcs(10*1000*1000, 100*1000*1000, + "malloc_free_array", (void *)malloc_free_array, + "delete_array", (void *)new_delete_array); +} +TEST_END + + +TEST_BEGIN(test_sized_delete_vs_sdallocx) { +#if __cpp_sized_deallocation >= 201309 + compare_funcs(10*1000*1000, 100*1000*1000, + "new_size_delete", (void *)new_sized_delete, + "malloc_sdallocx", (void *)malloc_sdallocx); +#else + malloc_printf("Skipping test_sized_delete_vs_sdallocx since \ + sized deallocation is not enabled.\n"); +#endif +} +TEST_END + + +int +main() { + return test_no_reentrancy( + test_free_vs_delete, + test_free_array_vs_delete_array, + test_sized_delete_vs_sdallocx); + +}