summaryrefslogtreecommitdiff
path: root/examples/redis-unstable/deps/jemalloc/test/stress
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/deps/jemalloc/test/stress')
-rw-r--r--examples/redis-unstable/deps/jemalloc/test/stress/batch_alloc.c198
-rw-r--r--examples/redis-unstable/deps/jemalloc/test/stress/fill_flush.c76
-rw-r--r--examples/redis-unstable/deps/jemalloc/test/stress/hookbench.c73
-rw-r--r--examples/redis-unstable/deps/jemalloc/test/stress/large_microbench.c33
-rw-r--r--examples/redis-unstable/deps/jemalloc/test/stress/mallctl.c74
-rw-r--r--examples/redis-unstable/deps/jemalloc/test/stress/microbench.c126
6 files changed, 580 insertions, 0 deletions
diff --git a/examples/redis-unstable/deps/jemalloc/test/stress/batch_alloc.c b/examples/redis-unstable/deps/jemalloc/test/stress/batch_alloc.c
new file mode 100644
index 0000000..427e1cb
--- /dev/null
+++ b/examples/redis-unstable/deps/jemalloc/test/stress/batch_alloc.c
@@ -0,0 +1,198 @@
1#include "test/jemalloc_test.h"
2#include "test/bench.h"
3
4#define MIBLEN 8
5static size_t mib[MIBLEN];
6static size_t miblen = MIBLEN;
7
8#define TINY_BATCH 10
9#define TINY_BATCH_ITER (10 * 1000 * 1000)
10#define HUGE_BATCH (1000 * 1000)
11#define HUGE_BATCH_ITER 100
12#define LEN (100 * 1000 * 1000)
13static void *batch_ptrs[LEN];
14static size_t batch_ptrs_next = 0;
15static void *item_ptrs[LEN];
16static size_t item_ptrs_next = 0;
17
18#define SIZE 7
19
20typedef struct batch_alloc_packet_s batch_alloc_packet_t;
21struct batch_alloc_packet_s {
22 void **ptrs;
23 size_t num;
24 size_t size;
25 int flags;
26};
27
28static void
29batch_alloc_wrapper(size_t batch) {
30 batch_alloc_packet_t batch_alloc_packet =
31 {batch_ptrs + batch_ptrs_next, batch, SIZE, 0};
32 size_t filled;
33 size_t len = sizeof(size_t);
34 assert_d_eq(mallctlbymib(mib, miblen, &filled, &len,
35 &batch_alloc_packet, sizeof(batch_alloc_packet)), 0, "");
36 assert_zu_eq(filled, batch, "");
37}
38
39static void
40item_alloc_wrapper(size_t batch) {
41 for (size_t i = item_ptrs_next, end = i + batch; i < end; ++i) {
42 item_ptrs[i] = malloc(SIZE);
43 }
44}
45
46static void
47release_and_clear(void **ptrs, size_t len) {
48 for (size_t i = 0; i < len; ++i) {
49 void *p = ptrs[i];
50 assert_ptr_not_null(p, "allocation failed");
51 sdallocx(p, SIZE, 0);
52 ptrs[i] = NULL;
53 }
54}
55
56static void
57batch_alloc_without_free(size_t batch) {
58 batch_alloc_wrapper(batch);
59 batch_ptrs_next += batch;
60}
61
62static void
63item_alloc_without_free(size_t batch) {
64 item_alloc_wrapper(batch);
65 item_ptrs_next += batch;
66}
67
68static void
69batch_alloc_with_free(size_t batch) {
70 batch_alloc_wrapper(batch);
71 release_and_clear(batch_ptrs + batch_ptrs_next, batch);
72 batch_ptrs_next += batch;
73}
74
75static void
76item_alloc_with_free(size_t batch) {
77 item_alloc_wrapper(batch);
78 release_and_clear(item_ptrs + item_ptrs_next, batch);
79 item_ptrs_next += batch;
80}
81
82static void
83compare_without_free(size_t batch, size_t iter,
84 void (*batch_alloc_without_free_func)(void),
85 void (*item_alloc_without_free_func)(void)) {
86 assert(batch_ptrs_next == 0);
87 assert(item_ptrs_next == 0);
88 assert(batch * iter <= LEN);
89 for (size_t i = 0; i < iter; ++i) {
90 batch_alloc_without_free_func();
91 item_alloc_without_free_func();
92 }
93 release_and_clear(batch_ptrs, batch_ptrs_next);
94 batch_ptrs_next = 0;
95 release_and_clear(item_ptrs, item_ptrs_next);
96 item_ptrs_next = 0;
97 compare_funcs(0, iter,
98 "batch allocation", batch_alloc_without_free_func,
99 "item allocation", item_alloc_without_free_func);
100 release_and_clear(batch_ptrs, batch_ptrs_next);
101 batch_ptrs_next = 0;
102 release_and_clear(item_ptrs, item_ptrs_next);
103 item_ptrs_next = 0;
104}
105
106static void
107compare_with_free(size_t batch, size_t iter,
108 void (*batch_alloc_with_free_func)(void),
109 void (*item_alloc_with_free_func)(void)) {
110 assert(batch_ptrs_next == 0);
111 assert(item_ptrs_next == 0);
112 assert(batch * iter <= LEN);
113 for (size_t i = 0; i < iter; ++i) {
114 batch_alloc_with_free_func();
115 item_alloc_with_free_func();
116 }
117 batch_ptrs_next = 0;
118 item_ptrs_next = 0;
119 compare_funcs(0, iter,
120 "batch allocation", batch_alloc_with_free_func,
121 "item allocation", item_alloc_with_free_func);
122 batch_ptrs_next = 0;
123 item_ptrs_next = 0;
124}
125
126static void
127batch_alloc_without_free_tiny() {
128 batch_alloc_without_free(TINY_BATCH);
129}
130
131static void
132item_alloc_without_free_tiny() {
133 item_alloc_without_free(TINY_BATCH);
134}
135
136TEST_BEGIN(test_tiny_batch_without_free) {
137 compare_without_free(TINY_BATCH, TINY_BATCH_ITER,
138 batch_alloc_without_free_tiny, item_alloc_without_free_tiny);
139}
140TEST_END
141
142static void
143batch_alloc_with_free_tiny() {
144 batch_alloc_with_free(TINY_BATCH);
145}
146
147static void
148item_alloc_with_free_tiny() {
149 item_alloc_with_free(TINY_BATCH);
150}
151
152TEST_BEGIN(test_tiny_batch_with_free) {
153 compare_with_free(TINY_BATCH, TINY_BATCH_ITER,
154 batch_alloc_with_free_tiny, item_alloc_with_free_tiny);
155}
156TEST_END
157
158static void
159batch_alloc_without_free_huge() {
160 batch_alloc_without_free(HUGE_BATCH);
161}
162
163static void
164item_alloc_without_free_huge() {
165 item_alloc_without_free(HUGE_BATCH);
166}
167
168TEST_BEGIN(test_huge_batch_without_free) {
169 compare_without_free(HUGE_BATCH, HUGE_BATCH_ITER,
170 batch_alloc_without_free_huge, item_alloc_without_free_huge);
171}
172TEST_END
173
174static void
175batch_alloc_with_free_huge() {
176 batch_alloc_with_free(HUGE_BATCH);
177}
178
179static void
180item_alloc_with_free_huge() {
181 item_alloc_with_free(HUGE_BATCH);
182}
183
184TEST_BEGIN(test_huge_batch_with_free) {
185 compare_with_free(HUGE_BATCH, HUGE_BATCH_ITER,
186 batch_alloc_with_free_huge, item_alloc_with_free_huge);
187}
188TEST_END
189
190int main(void) {
191 assert_d_eq(mallctlnametomib("experimental.batch_alloc", mib, &miblen),
192 0, "");
193 return test_no_reentrancy(
194 test_tiny_batch_without_free,
195 test_tiny_batch_with_free,
196 test_huge_batch_without_free,
197 test_huge_batch_with_free);
198}
diff --git a/examples/redis-unstable/deps/jemalloc/test/stress/fill_flush.c b/examples/redis-unstable/deps/jemalloc/test/stress/fill_flush.c
new file mode 100644
index 0000000..a2db044
--- /dev/null
+++ b/examples/redis-unstable/deps/jemalloc/test/stress/fill_flush.c
@@ -0,0 +1,76 @@
1#include "test/jemalloc_test.h"
2#include "test/bench.h"
3
4#define SMALL_ALLOC_SIZE 128
5#define LARGE_ALLOC_SIZE SC_LARGE_MINCLASS
6#define NALLOCS 1000
7
8/*
9 * We make this volatile so the 1-at-a-time variants can't leave the allocation
10 * in a register, just to try to get the cache behavior closer.
11 */
12void *volatile allocs[NALLOCS];
13
14static void
15array_alloc_dalloc_small(void) {
16 for (int i = 0; i < NALLOCS; i++) {
17 void *p = mallocx(SMALL_ALLOC_SIZE, 0);
18 assert_ptr_not_null(p, "mallocx shouldn't fail");
19 allocs[i] = p;
20 }
21 for (int i = 0; i < NALLOCS; i++) {
22 sdallocx(allocs[i], SMALL_ALLOC_SIZE, 0);
23 }
24}
25
26static void
27item_alloc_dalloc_small(void) {
28 for (int i = 0; i < NALLOCS; i++) {
29 void *p = mallocx(SMALL_ALLOC_SIZE, 0);
30 assert_ptr_not_null(p, "mallocx shouldn't fail");
31 allocs[i] = p;
32 sdallocx(allocs[i], SMALL_ALLOC_SIZE, 0);
33 }
34}
35
36TEST_BEGIN(test_array_vs_item_small) {
37 compare_funcs(1 * 1000, 10 * 1000,
38 "array of small allocations", array_alloc_dalloc_small,
39 "small item allocation", item_alloc_dalloc_small);
40}
41TEST_END
42
43static void
44array_alloc_dalloc_large(void) {
45 for (int i = 0; i < NALLOCS; i++) {
46 void *p = mallocx(LARGE_ALLOC_SIZE, 0);
47 assert_ptr_not_null(p, "mallocx shouldn't fail");
48 allocs[i] = p;
49 }
50 for (int i = 0; i < NALLOCS; i++) {
51 sdallocx(allocs[i], LARGE_ALLOC_SIZE, 0);
52 }
53}
54
55static void
56item_alloc_dalloc_large(void) {
57 for (int i = 0; i < NALLOCS; i++) {
58 void *p = mallocx(LARGE_ALLOC_SIZE, 0);
59 assert_ptr_not_null(p, "mallocx shouldn't fail");
60 allocs[i] = p;
61 sdallocx(allocs[i], LARGE_ALLOC_SIZE, 0);
62 }
63}
64
65TEST_BEGIN(test_array_vs_item_large) {
66 compare_funcs(100, 1000,
67 "array of large allocations", array_alloc_dalloc_large,
68 "large item allocation", item_alloc_dalloc_large);
69}
70TEST_END
71
72int main(void) {
73 return test_no_reentrancy(
74 test_array_vs_item_small,
75 test_array_vs_item_large);
76}
diff --git a/examples/redis-unstable/deps/jemalloc/test/stress/hookbench.c b/examples/redis-unstable/deps/jemalloc/test/stress/hookbench.c
new file mode 100644
index 0000000..97e90b0
--- /dev/null
+++ b/examples/redis-unstable/deps/jemalloc/test/stress/hookbench.c
@@ -0,0 +1,73 @@
1#include "test/jemalloc_test.h"
2
3static void
4noop_alloc_hook(void *extra, hook_alloc_t type, void *result,
5 uintptr_t result_raw, uintptr_t args_raw[3]) {
6}
7
8static void
9noop_dalloc_hook(void *extra, hook_dalloc_t type, void *address,
10 uintptr_t args_raw[3]) {
11}
12
13static void
14noop_expand_hook(void *extra, hook_expand_t type, void *address,
15 size_t old_usize, size_t new_usize, uintptr_t result_raw,
16 uintptr_t args_raw[4]) {
17}
18
19static void
20malloc_free_loop(int iters) {
21 for (int i = 0; i < iters; i++) {
22 void *p = mallocx(1, 0);
23 free(p);
24 }
25}
26
27static void
28test_hooked(int iters) {
29 hooks_t hooks = {&noop_alloc_hook, &noop_dalloc_hook, &noop_expand_hook,
30 NULL};
31
32 int err;
33 void *handles[HOOK_MAX];
34 size_t sz = sizeof(handles[0]);
35
36 for (int i = 0; i < HOOK_MAX; i++) {
37 err = mallctl("experimental.hooks.install", &handles[i],
38 &sz, &hooks, sizeof(hooks));
39 assert(err == 0);
40
41 timedelta_t timer;
42 timer_start(&timer);
43 malloc_free_loop(iters);
44 timer_stop(&timer);
45 malloc_printf("With %d hook%s: %"FMTu64"us\n", i + 1,
46 i + 1 == 1 ? "" : "s", timer_usec(&timer));
47 }
48 for (int i = 0; i < HOOK_MAX; i++) {
49 err = mallctl("experimental.hooks.remove", NULL, NULL,
50 &handles[i], sizeof(handles[i]));
51 assert(err == 0);
52 }
53}
54
55static void
56test_unhooked(int iters) {
57 timedelta_t timer;
58 timer_start(&timer);
59 malloc_free_loop(iters);
60 timer_stop(&timer);
61
62 malloc_printf("Without hooks: %"FMTu64"us\n", timer_usec(&timer));
63}
64
65int
66main(void) {
67 /* Initialize */
68 free(mallocx(1, 0));
69 int iters = 10 * 1000 * 1000;
70 malloc_printf("Benchmarking hooks with %d iterations:\n", iters);
71 test_hooked(iters);
72 test_unhooked(iters);
73}
diff --git a/examples/redis-unstable/deps/jemalloc/test/stress/large_microbench.c b/examples/redis-unstable/deps/jemalloc/test/stress/large_microbench.c
new file mode 100644
index 0000000..c66b33a
--- /dev/null
+++ b/examples/redis-unstable/deps/jemalloc/test/stress/large_microbench.c
@@ -0,0 +1,33 @@
1#include "test/jemalloc_test.h"
2#include "test/bench.h"
3
4static void
5large_mallocx_free(void) {
6 /*
7 * We go a bit larger than the large minclass on its own to better
8 * expose costs from things like zeroing.
9 */
10 void *p = mallocx(SC_LARGE_MINCLASS, MALLOCX_TCACHE_NONE);
11 assert_ptr_not_null(p, "mallocx shouldn't fail");
12 free(p);
13}
14
15static void
16small_mallocx_free(void) {
17 void *p = mallocx(16, 0);
18 assert_ptr_not_null(p, "mallocx shouldn't fail");
19 free(p);
20}
21
22TEST_BEGIN(test_large_vs_small) {
23 compare_funcs(100*1000, 1*1000*1000, "large mallocx",
24 large_mallocx_free, "small mallocx", small_mallocx_free);
25}
26TEST_END
27
28int
29main(void) {
30 return test_no_reentrancy(
31 test_large_vs_small);
32}
33
diff --git a/examples/redis-unstable/deps/jemalloc/test/stress/mallctl.c b/examples/redis-unstable/deps/jemalloc/test/stress/mallctl.c
new file mode 100644
index 0000000..d29b311
--- /dev/null
+++ b/examples/redis-unstable/deps/jemalloc/test/stress/mallctl.c
@@ -0,0 +1,74 @@
1#include "test/jemalloc_test.h"
2#include "test/bench.h"
3
4static void
5mallctl_short(void) {
6 const char *version;
7 size_t sz = sizeof(version);
8 int err = mallctl("version", &version, &sz, NULL, 0);
9 assert_d_eq(err, 0, "mallctl failure");
10}
11
12size_t mib_short[1];
13
14static void
15mallctlbymib_short(void) {
16 size_t miblen = sizeof(mib_short)/sizeof(mib_short[0]);
17 const char *version;
18 size_t sz = sizeof(version);
19 int err = mallctlbymib(mib_short, miblen, &version, &sz, NULL, 0);
20 assert_d_eq(err, 0, "mallctlbymib failure");
21}
22
23TEST_BEGIN(test_mallctl_vs_mallctlbymib_short) {
24 size_t miblen = sizeof(mib_short)/sizeof(mib_short[0]);
25
26 int err = mallctlnametomib("version", mib_short, &miblen);
27 assert_d_eq(err, 0, "mallctlnametomib failure");
28 compare_funcs(10*1000*1000, 10*1000*1000, "mallctl_short",
29 mallctl_short, "mallctlbymib_short", mallctlbymib_short);
30}
31TEST_END
32
33static void
34mallctl_long(void) {
35 uint64_t nmalloc;
36 size_t sz = sizeof(nmalloc);
37 int err = mallctl("stats.arenas.0.bins.0.nmalloc", &nmalloc, &sz, NULL,
38 0);
39 assert_d_eq(err, 0, "mallctl failure");
40}
41
42size_t mib_long[6];
43
44static void
45mallctlbymib_long(void) {
46 size_t miblen = sizeof(mib_long)/sizeof(mib_long[0]);
47 uint64_t nmalloc;
48 size_t sz = sizeof(nmalloc);
49 int err = mallctlbymib(mib_long, miblen, &nmalloc, &sz, NULL, 0);
50 assert_d_eq(err, 0, "mallctlbymib failure");
51}
52
53TEST_BEGIN(test_mallctl_vs_mallctlbymib_long) {
54 /*
55 * We want to use the longest mallctl we have; that needs stats support
56 * to be allowed.
57 */
58 test_skip_if(!config_stats);
59
60 size_t miblen = sizeof(mib_long)/sizeof(mib_long[0]);
61 int err = mallctlnametomib("stats.arenas.0.bins.0.nmalloc", mib_long,
62 &miblen);
63 assert_d_eq(err, 0, "mallctlnametomib failure");
64 compare_funcs(10*1000*1000, 10*1000*1000, "mallctl_long",
65 mallctl_long, "mallctlbymib_long", mallctlbymib_long);
66}
67TEST_END
68
69int
70main(void) {
71 return test_no_reentrancy(
72 test_mallctl_vs_mallctlbymib_short,
73 test_mallctl_vs_mallctlbymib_long);
74}
diff --git a/examples/redis-unstable/deps/jemalloc/test/stress/microbench.c b/examples/redis-unstable/deps/jemalloc/test/stress/microbench.c
new file mode 100644
index 0000000..062e32f
--- /dev/null
+++ b/examples/redis-unstable/deps/jemalloc/test/stress/microbench.c
@@ -0,0 +1,126 @@
1#include "test/jemalloc_test.h"
2#include "test/bench.h"
3
4static void
5malloc_free(void) {
6 /* The compiler can optimize away free(malloc(1))! */
7 void *p = malloc(1);
8 if (p == NULL) {
9 test_fail("Unexpected malloc() failure");
10 return;
11 }
12 free(p);
13}
14
15static void
16mallocx_free(void) {
17 void *p = mallocx(1, 0);
18 if (p == NULL) {
19 test_fail("Unexpected mallocx() failure");
20 return;
21 }
22 free(p);
23}
24
25TEST_BEGIN(test_malloc_vs_mallocx) {
26 compare_funcs(10*1000*1000, 100*1000*1000, "malloc",
27 malloc_free, "mallocx", mallocx_free);
28}
29TEST_END
30
31static void
32malloc_dallocx(void) {
33 void *p = malloc(1);
34 if (p == NULL) {
35 test_fail("Unexpected malloc() failure");
36 return;
37 }
38 dallocx(p, 0);
39}
40
41static void
42malloc_sdallocx(void) {
43 void *p = malloc(1);
44 if (p == NULL) {
45 test_fail("Unexpected malloc() failure");
46 return;
47 }
48 sdallocx(p, 1, 0);
49}
50
51TEST_BEGIN(test_free_vs_dallocx) {
52 compare_funcs(10*1000*1000, 100*1000*1000, "free", malloc_free,
53 "dallocx", malloc_dallocx);
54}
55TEST_END
56
57TEST_BEGIN(test_dallocx_vs_sdallocx) {
58 compare_funcs(10*1000*1000, 100*1000*1000, "dallocx", malloc_dallocx,
59 "sdallocx", malloc_sdallocx);
60}
61TEST_END
62
63static void
64malloc_mus_free(void) {
65 void *p;
66
67 p = malloc(1);
68 if (p == NULL) {
69 test_fail("Unexpected malloc() failure");
70 return;
71 }
72 TEST_MALLOC_SIZE(p);
73 free(p);
74}
75
76static void
77malloc_sallocx_free(void) {
78 void *p;
79
80 p = malloc(1);
81 if (p == NULL) {
82 test_fail("Unexpected malloc() failure");
83 return;
84 }
85 if (sallocx(p, 0) < 1) {
86 test_fail("Unexpected sallocx() failure");
87 }
88 free(p);
89}
90
91TEST_BEGIN(test_mus_vs_sallocx) {
92 compare_funcs(10*1000*1000, 100*1000*1000, "malloc_usable_size",
93 malloc_mus_free, "sallocx", malloc_sallocx_free);
94}
95TEST_END
96
97static void
98malloc_nallocx_free(void) {
99 void *p;
100
101 p = malloc(1);
102 if (p == NULL) {
103 test_fail("Unexpected malloc() failure");
104 return;
105 }
106 if (nallocx(1, 0) < 1) {
107 test_fail("Unexpected nallocx() failure");
108 }
109 free(p);
110}
111
112TEST_BEGIN(test_sallocx_vs_nallocx) {
113 compare_funcs(10*1000*1000, 100*1000*1000, "sallocx",
114 malloc_sallocx_free, "nallocx", malloc_nallocx_free);
115}
116TEST_END
117
118int
119main(void) {
120 return test_no_reentrancy(
121 test_malloc_vs_mallocx,
122 test_free_vs_dallocx,
123 test_dallocx_vs_sdallocx,
124 test_mus_vs_sallocx,
125 test_sallocx_vs_nallocx);
126}