1*1208bc7eSAndroid Build Coastguard Worker #ifndef ARENA_RESET_PROF_C_
2*1208bc7eSAndroid Build Coastguard Worker #include "test/jemalloc_test.h"
3*1208bc7eSAndroid Build Coastguard Worker #endif
4*1208bc7eSAndroid Build Coastguard Worker
5*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/extent_mmap.h"
6*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/rtree.h"
7*1208bc7eSAndroid Build Coastguard Worker
8*1208bc7eSAndroid Build Coastguard Worker #include "test/extent_hooks.h"
9*1208bc7eSAndroid Build Coastguard Worker
10*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nsizes_impl(const char * cmd)11*1208bc7eSAndroid Build Coastguard Worker get_nsizes_impl(const char *cmd) {
12*1208bc7eSAndroid Build Coastguard Worker unsigned ret;
13*1208bc7eSAndroid Build Coastguard Worker size_t z;
14*1208bc7eSAndroid Build Coastguard Worker
15*1208bc7eSAndroid Build Coastguard Worker z = sizeof(unsigned);
16*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
17*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallctl(\"%s\", ...) failure", cmd);
18*1208bc7eSAndroid Build Coastguard Worker
19*1208bc7eSAndroid Build Coastguard Worker return ret;
20*1208bc7eSAndroid Build Coastguard Worker }
21*1208bc7eSAndroid Build Coastguard Worker
22*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nsmall(void)23*1208bc7eSAndroid Build Coastguard Worker get_nsmall(void) {
24*1208bc7eSAndroid Build Coastguard Worker return get_nsizes_impl("arenas.nbins");
25*1208bc7eSAndroid Build Coastguard Worker }
26*1208bc7eSAndroid Build Coastguard Worker
27*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nlarge(void)28*1208bc7eSAndroid Build Coastguard Worker get_nlarge(void) {
29*1208bc7eSAndroid Build Coastguard Worker return get_nsizes_impl("arenas.nlextents");
30*1208bc7eSAndroid Build Coastguard Worker }
31*1208bc7eSAndroid Build Coastguard Worker
32*1208bc7eSAndroid Build Coastguard Worker static size_t
get_size_impl(const char * cmd,size_t ind)33*1208bc7eSAndroid Build Coastguard Worker get_size_impl(const char *cmd, size_t ind) {
34*1208bc7eSAndroid Build Coastguard Worker size_t ret;
35*1208bc7eSAndroid Build Coastguard Worker size_t z;
36*1208bc7eSAndroid Build Coastguard Worker size_t mib[4];
37*1208bc7eSAndroid Build Coastguard Worker size_t miblen = 4;
38*1208bc7eSAndroid Build Coastguard Worker
39*1208bc7eSAndroid Build Coastguard Worker z = sizeof(size_t);
40*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
41*1208bc7eSAndroid Build Coastguard Worker 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
42*1208bc7eSAndroid Build Coastguard Worker mib[2] = ind;
43*1208bc7eSAndroid Build Coastguard Worker z = sizeof(size_t);
44*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
45*1208bc7eSAndroid Build Coastguard Worker 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
46*1208bc7eSAndroid Build Coastguard Worker
47*1208bc7eSAndroid Build Coastguard Worker return ret;
48*1208bc7eSAndroid Build Coastguard Worker }
49*1208bc7eSAndroid Build Coastguard Worker
50*1208bc7eSAndroid Build Coastguard Worker static size_t
get_small_size(size_t ind)51*1208bc7eSAndroid Build Coastguard Worker get_small_size(size_t ind) {
52*1208bc7eSAndroid Build Coastguard Worker return get_size_impl("arenas.bin.0.size", ind);
53*1208bc7eSAndroid Build Coastguard Worker }
54*1208bc7eSAndroid Build Coastguard Worker
55*1208bc7eSAndroid Build Coastguard Worker static size_t
get_large_size(size_t ind)56*1208bc7eSAndroid Build Coastguard Worker get_large_size(size_t ind) {
57*1208bc7eSAndroid Build Coastguard Worker return get_size_impl("arenas.lextent.0.size", ind);
58*1208bc7eSAndroid Build Coastguard Worker }
59*1208bc7eSAndroid Build Coastguard Worker
60*1208bc7eSAndroid Build Coastguard Worker /* Like ivsalloc(), but safe to call on discarded allocations. */
61*1208bc7eSAndroid Build Coastguard Worker static size_t
vsalloc(tsdn_t * tsdn,const void * ptr)62*1208bc7eSAndroid Build Coastguard Worker vsalloc(tsdn_t *tsdn, const void *ptr) {
63*1208bc7eSAndroid Build Coastguard Worker rtree_ctx_t rtree_ctx_fallback;
64*1208bc7eSAndroid Build Coastguard Worker rtree_ctx_t *rtree_ctx = tsdn_rtree_ctx(tsdn, &rtree_ctx_fallback);
65*1208bc7eSAndroid Build Coastguard Worker
66*1208bc7eSAndroid Build Coastguard Worker extent_t *extent;
67*1208bc7eSAndroid Build Coastguard Worker szind_t szind;
68*1208bc7eSAndroid Build Coastguard Worker if (rtree_extent_szind_read(tsdn, &extents_rtree, rtree_ctx,
69*1208bc7eSAndroid Build Coastguard Worker (uintptr_t)ptr, false, &extent, &szind)) {
70*1208bc7eSAndroid Build Coastguard Worker return 0;
71*1208bc7eSAndroid Build Coastguard Worker }
72*1208bc7eSAndroid Build Coastguard Worker
73*1208bc7eSAndroid Build Coastguard Worker if (extent == NULL) {
74*1208bc7eSAndroid Build Coastguard Worker return 0;
75*1208bc7eSAndroid Build Coastguard Worker }
76*1208bc7eSAndroid Build Coastguard Worker if (extent_state_get(extent) != extent_state_active) {
77*1208bc7eSAndroid Build Coastguard Worker return 0;
78*1208bc7eSAndroid Build Coastguard Worker }
79*1208bc7eSAndroid Build Coastguard Worker
80*1208bc7eSAndroid Build Coastguard Worker if (szind == NSIZES) {
81*1208bc7eSAndroid Build Coastguard Worker return 0;
82*1208bc7eSAndroid Build Coastguard Worker }
83*1208bc7eSAndroid Build Coastguard Worker
84*1208bc7eSAndroid Build Coastguard Worker return sz_index2size(szind);
85*1208bc7eSAndroid Build Coastguard Worker }
86*1208bc7eSAndroid Build Coastguard Worker
87*1208bc7eSAndroid Build Coastguard Worker static unsigned
do_arena_create(extent_hooks_t * h)88*1208bc7eSAndroid Build Coastguard Worker do_arena_create(extent_hooks_t *h) {
89*1208bc7eSAndroid Build Coastguard Worker unsigned arena_ind;
90*1208bc7eSAndroid Build Coastguard Worker size_t sz = sizeof(unsigned);
91*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctl("arenas.create", (void *)&arena_ind, &sz,
92*1208bc7eSAndroid Build Coastguard Worker (void *)(h != NULL ? &h : NULL), (h != NULL ? sizeof(h) : 0)), 0,
93*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallctl() failure");
94*1208bc7eSAndroid Build Coastguard Worker return arena_ind;
95*1208bc7eSAndroid Build Coastguard Worker }
96*1208bc7eSAndroid Build Coastguard Worker
97*1208bc7eSAndroid Build Coastguard Worker static void
do_arena_reset_pre(unsigned arena_ind,void *** ptrs,unsigned * nptrs)98*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_pre(unsigned arena_ind, void ***ptrs, unsigned *nptrs) {
99*1208bc7eSAndroid Build Coastguard Worker #define NLARGE 32
100*1208bc7eSAndroid Build Coastguard Worker unsigned nsmall, nlarge, i;
101*1208bc7eSAndroid Build Coastguard Worker size_t sz;
102*1208bc7eSAndroid Build Coastguard Worker int flags;
103*1208bc7eSAndroid Build Coastguard Worker tsdn_t *tsdn;
104*1208bc7eSAndroid Build Coastguard Worker
105*1208bc7eSAndroid Build Coastguard Worker flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
106*1208bc7eSAndroid Build Coastguard Worker
107*1208bc7eSAndroid Build Coastguard Worker nsmall = get_nsmall();
108*1208bc7eSAndroid Build Coastguard Worker nlarge = get_nlarge() > NLARGE ? NLARGE : get_nlarge();
109*1208bc7eSAndroid Build Coastguard Worker *nptrs = nsmall + nlarge;
110*1208bc7eSAndroid Build Coastguard Worker *ptrs = (void **)malloc(*nptrs * sizeof(void *));
111*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(*ptrs, "Unexpected malloc() failure");
112*1208bc7eSAndroid Build Coastguard Worker
113*1208bc7eSAndroid Build Coastguard Worker /* Allocate objects with a wide range of sizes. */
114*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nsmall; i++) {
115*1208bc7eSAndroid Build Coastguard Worker sz = get_small_size(i);
116*1208bc7eSAndroid Build Coastguard Worker (*ptrs)[i] = mallocx(sz, flags);
117*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null((*ptrs)[i],
118*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallocx(%zu, %#x) failure", sz, flags);
119*1208bc7eSAndroid Build Coastguard Worker }
120*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nlarge; i++) {
121*1208bc7eSAndroid Build Coastguard Worker sz = get_large_size(i);
122*1208bc7eSAndroid Build Coastguard Worker (*ptrs)[nsmall + i] = mallocx(sz, flags);
123*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null((*ptrs)[i],
124*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallocx(%zu, %#x) failure", sz, flags);
125*1208bc7eSAndroid Build Coastguard Worker }
126*1208bc7eSAndroid Build Coastguard Worker
127*1208bc7eSAndroid Build Coastguard Worker tsdn = tsdn_fetch();
128*1208bc7eSAndroid Build Coastguard Worker
129*1208bc7eSAndroid Build Coastguard Worker /* Verify allocations. */
130*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < *nptrs; i++) {
131*1208bc7eSAndroid Build Coastguard Worker assert_zu_gt(ivsalloc(tsdn, (*ptrs)[i]), 0,
132*1208bc7eSAndroid Build Coastguard Worker "Allocation should have queryable size");
133*1208bc7eSAndroid Build Coastguard Worker }
134*1208bc7eSAndroid Build Coastguard Worker }
135*1208bc7eSAndroid Build Coastguard Worker
136*1208bc7eSAndroid Build Coastguard Worker static void
do_arena_reset_post(void ** ptrs,unsigned nptrs,unsigned arena_ind)137*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_post(void **ptrs, unsigned nptrs, unsigned arena_ind) {
138*1208bc7eSAndroid Build Coastguard Worker tsdn_t *tsdn;
139*1208bc7eSAndroid Build Coastguard Worker unsigned i;
140*1208bc7eSAndroid Build Coastguard Worker
141*1208bc7eSAndroid Build Coastguard Worker tsdn = tsdn_fetch();
142*1208bc7eSAndroid Build Coastguard Worker
143*1208bc7eSAndroid Build Coastguard Worker if (have_background_thread) {
144*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_lock(tsdn,
145*1208bc7eSAndroid Build Coastguard Worker &background_thread_info[arena_ind % ncpus].mtx);
146*1208bc7eSAndroid Build Coastguard Worker }
147*1208bc7eSAndroid Build Coastguard Worker /* Verify allocations no longer exist. */
148*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nptrs; i++) {
149*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(vsalloc(tsdn, ptrs[i]), 0,
150*1208bc7eSAndroid Build Coastguard Worker "Allocation should no longer exist");
151*1208bc7eSAndroid Build Coastguard Worker }
152*1208bc7eSAndroid Build Coastguard Worker if (have_background_thread) {
153*1208bc7eSAndroid Build Coastguard Worker malloc_mutex_unlock(tsdn,
154*1208bc7eSAndroid Build Coastguard Worker &background_thread_info[arena_ind % ncpus].mtx);
155*1208bc7eSAndroid Build Coastguard Worker }
156*1208bc7eSAndroid Build Coastguard Worker
157*1208bc7eSAndroid Build Coastguard Worker free(ptrs);
158*1208bc7eSAndroid Build Coastguard Worker }
159*1208bc7eSAndroid Build Coastguard Worker
160*1208bc7eSAndroid Build Coastguard Worker static void
do_arena_reset_destroy(const char * name,unsigned arena_ind)161*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_destroy(const char *name, unsigned arena_ind) {
162*1208bc7eSAndroid Build Coastguard Worker size_t mib[3];
163*1208bc7eSAndroid Build Coastguard Worker size_t miblen;
164*1208bc7eSAndroid Build Coastguard Worker
165*1208bc7eSAndroid Build Coastguard Worker miblen = sizeof(mib)/sizeof(size_t);
166*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlnametomib(name, mib, &miblen), 0,
167*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallctlnametomib() failure");
168*1208bc7eSAndroid Build Coastguard Worker mib[1] = (size_t)arena_ind;
169*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
170*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallctlbymib() failure");
171*1208bc7eSAndroid Build Coastguard Worker }
172*1208bc7eSAndroid Build Coastguard Worker
173*1208bc7eSAndroid Build Coastguard Worker static void
do_arena_reset(unsigned arena_ind)174*1208bc7eSAndroid Build Coastguard Worker do_arena_reset(unsigned arena_ind) {
175*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_destroy("arena.0.reset", arena_ind);
176*1208bc7eSAndroid Build Coastguard Worker }
177*1208bc7eSAndroid Build Coastguard Worker
178*1208bc7eSAndroid Build Coastguard Worker static void
do_arena_destroy(unsigned arena_ind)179*1208bc7eSAndroid Build Coastguard Worker do_arena_destroy(unsigned arena_ind) {
180*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_destroy("arena.0.destroy", arena_ind);
181*1208bc7eSAndroid Build Coastguard Worker }
182*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_arena_reset)183*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_arena_reset) {
184*1208bc7eSAndroid Build Coastguard Worker unsigned arena_ind;
185*1208bc7eSAndroid Build Coastguard Worker void **ptrs;
186*1208bc7eSAndroid Build Coastguard Worker unsigned nptrs;
187*1208bc7eSAndroid Build Coastguard Worker
188*1208bc7eSAndroid Build Coastguard Worker arena_ind = do_arena_create(NULL);
189*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_pre(arena_ind, &ptrs, &nptrs);
190*1208bc7eSAndroid Build Coastguard Worker do_arena_reset(arena_ind);
191*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_post(ptrs, nptrs, arena_ind);
192*1208bc7eSAndroid Build Coastguard Worker }
193*1208bc7eSAndroid Build Coastguard Worker TEST_END
194*1208bc7eSAndroid Build Coastguard Worker
195*1208bc7eSAndroid Build Coastguard Worker static bool
arena_i_initialized(unsigned arena_ind,bool refresh)196*1208bc7eSAndroid Build Coastguard Worker arena_i_initialized(unsigned arena_ind, bool refresh) {
197*1208bc7eSAndroid Build Coastguard Worker bool initialized;
198*1208bc7eSAndroid Build Coastguard Worker size_t mib[3];
199*1208bc7eSAndroid Build Coastguard Worker size_t miblen, sz;
200*1208bc7eSAndroid Build Coastguard Worker
201*1208bc7eSAndroid Build Coastguard Worker if (refresh) {
202*1208bc7eSAndroid Build Coastguard Worker uint64_t epoch = 1;
203*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
204*1208bc7eSAndroid Build Coastguard Worker sizeof(epoch)), 0, "Unexpected mallctl() failure");
205*1208bc7eSAndroid Build Coastguard Worker }
206*1208bc7eSAndroid Build Coastguard Worker
207*1208bc7eSAndroid Build Coastguard Worker miblen = sizeof(mib)/sizeof(size_t);
208*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlnametomib("arena.0.initialized", mib, &miblen), 0,
209*1208bc7eSAndroid Build Coastguard Worker "Unexpected mallctlnametomib() failure");
210*1208bc7eSAndroid Build Coastguard Worker mib[1] = (size_t)arena_ind;
211*1208bc7eSAndroid Build Coastguard Worker sz = sizeof(initialized);
212*1208bc7eSAndroid Build Coastguard Worker assert_d_eq(mallctlbymib(mib, miblen, (void *)&initialized, &sz, NULL,
213*1208bc7eSAndroid Build Coastguard Worker 0), 0, "Unexpected mallctlbymib() failure");
214*1208bc7eSAndroid Build Coastguard Worker
215*1208bc7eSAndroid Build Coastguard Worker return initialized;
216*1208bc7eSAndroid Build Coastguard Worker }
217*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_arena_destroy_initial)218*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_arena_destroy_initial) {
219*1208bc7eSAndroid Build Coastguard Worker assert_false(arena_i_initialized(MALLCTL_ARENAS_DESTROYED, false),
220*1208bc7eSAndroid Build Coastguard Worker "Destroyed arena stats should not be initialized");
221*1208bc7eSAndroid Build Coastguard Worker }
222*1208bc7eSAndroid Build Coastguard Worker TEST_END
223*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_arena_destroy_hooks_default)224*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_arena_destroy_hooks_default) {
225*1208bc7eSAndroid Build Coastguard Worker unsigned arena_ind, arena_ind_another, arena_ind_prev;
226*1208bc7eSAndroid Build Coastguard Worker void **ptrs;
227*1208bc7eSAndroid Build Coastguard Worker unsigned nptrs;
228*1208bc7eSAndroid Build Coastguard Worker
229*1208bc7eSAndroid Build Coastguard Worker arena_ind = do_arena_create(NULL);
230*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_pre(arena_ind, &ptrs, &nptrs);
231*1208bc7eSAndroid Build Coastguard Worker
232*1208bc7eSAndroid Build Coastguard Worker assert_false(arena_i_initialized(arena_ind, false),
233*1208bc7eSAndroid Build Coastguard Worker "Arena stats should not be initialized");
234*1208bc7eSAndroid Build Coastguard Worker assert_true(arena_i_initialized(arena_ind, true),
235*1208bc7eSAndroid Build Coastguard Worker "Arena stats should be initialized");
236*1208bc7eSAndroid Build Coastguard Worker
237*1208bc7eSAndroid Build Coastguard Worker /*
238*1208bc7eSAndroid Build Coastguard Worker * Create another arena before destroying one, to better verify arena
239*1208bc7eSAndroid Build Coastguard Worker * index reuse.
240*1208bc7eSAndroid Build Coastguard Worker */
241*1208bc7eSAndroid Build Coastguard Worker arena_ind_another = do_arena_create(NULL);
242*1208bc7eSAndroid Build Coastguard Worker
243*1208bc7eSAndroid Build Coastguard Worker do_arena_destroy(arena_ind);
244*1208bc7eSAndroid Build Coastguard Worker
245*1208bc7eSAndroid Build Coastguard Worker assert_false(arena_i_initialized(arena_ind, true),
246*1208bc7eSAndroid Build Coastguard Worker "Arena stats should not be initialized");
247*1208bc7eSAndroid Build Coastguard Worker assert_true(arena_i_initialized(MALLCTL_ARENAS_DESTROYED, false),
248*1208bc7eSAndroid Build Coastguard Worker "Destroyed arena stats should be initialized");
249*1208bc7eSAndroid Build Coastguard Worker
250*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_post(ptrs, nptrs, arena_ind);
251*1208bc7eSAndroid Build Coastguard Worker
252*1208bc7eSAndroid Build Coastguard Worker arena_ind_prev = arena_ind;
253*1208bc7eSAndroid Build Coastguard Worker arena_ind = do_arena_create(NULL);
254*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_pre(arena_ind, &ptrs, &nptrs);
255*1208bc7eSAndroid Build Coastguard Worker assert_u_eq(arena_ind, arena_ind_prev,
256*1208bc7eSAndroid Build Coastguard Worker "Arena index should have been recycled");
257*1208bc7eSAndroid Build Coastguard Worker do_arena_destroy(arena_ind);
258*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_post(ptrs, nptrs, arena_ind);
259*1208bc7eSAndroid Build Coastguard Worker
260*1208bc7eSAndroid Build Coastguard Worker do_arena_destroy(arena_ind_another);
261*1208bc7eSAndroid Build Coastguard Worker }
262*1208bc7eSAndroid Build Coastguard Worker TEST_END
263*1208bc7eSAndroid Build Coastguard Worker
264*1208bc7eSAndroid Build Coastguard Worker /*
265*1208bc7eSAndroid Build Coastguard Worker * Actually unmap extents, regardless of opt_retain, so that attempts to access
266*1208bc7eSAndroid Build Coastguard Worker * a destroyed arena's memory will segfault.
267*1208bc7eSAndroid Build Coastguard Worker */
268*1208bc7eSAndroid Build Coastguard Worker static bool
extent_dalloc_unmap(extent_hooks_t * extent_hooks,void * addr,size_t size,bool committed,unsigned arena_ind)269*1208bc7eSAndroid Build Coastguard Worker extent_dalloc_unmap(extent_hooks_t *extent_hooks, void *addr, size_t size,
270*1208bc7eSAndroid Build Coastguard Worker bool committed, unsigned arena_ind) {
271*1208bc7eSAndroid Build Coastguard Worker TRACE_HOOK("%s(extent_hooks=%p, addr=%p, size=%zu, committed=%s, "
272*1208bc7eSAndroid Build Coastguard Worker "arena_ind=%u)\n", __func__, extent_hooks, addr, size, committed ?
273*1208bc7eSAndroid Build Coastguard Worker "true" : "false", arena_ind);
274*1208bc7eSAndroid Build Coastguard Worker assert_ptr_eq(extent_hooks, &hooks,
275*1208bc7eSAndroid Build Coastguard Worker "extent_hooks should be same as pointer used to set hooks");
276*1208bc7eSAndroid Build Coastguard Worker assert_ptr_eq(extent_hooks->dalloc, extent_dalloc_unmap,
277*1208bc7eSAndroid Build Coastguard Worker "Wrong hook function");
278*1208bc7eSAndroid Build Coastguard Worker called_dalloc = true;
279*1208bc7eSAndroid Build Coastguard Worker if (!try_dalloc) {
280*1208bc7eSAndroid Build Coastguard Worker return true;
281*1208bc7eSAndroid Build Coastguard Worker }
282*1208bc7eSAndroid Build Coastguard Worker pages_unmap(addr, size);
283*1208bc7eSAndroid Build Coastguard Worker did_dalloc = true;
284*1208bc7eSAndroid Build Coastguard Worker return false;
285*1208bc7eSAndroid Build Coastguard Worker }
286*1208bc7eSAndroid Build Coastguard Worker
287*1208bc7eSAndroid Build Coastguard Worker static extent_hooks_t hooks_orig;
288*1208bc7eSAndroid Build Coastguard Worker
289*1208bc7eSAndroid Build Coastguard Worker static extent_hooks_t hooks_unmap = {
290*1208bc7eSAndroid Build Coastguard Worker extent_alloc_hook,
291*1208bc7eSAndroid Build Coastguard Worker extent_dalloc_unmap, /* dalloc */
292*1208bc7eSAndroid Build Coastguard Worker extent_destroy_hook,
293*1208bc7eSAndroid Build Coastguard Worker extent_commit_hook,
294*1208bc7eSAndroid Build Coastguard Worker extent_decommit_hook,
295*1208bc7eSAndroid Build Coastguard Worker extent_purge_lazy_hook,
296*1208bc7eSAndroid Build Coastguard Worker extent_purge_forced_hook,
297*1208bc7eSAndroid Build Coastguard Worker extent_split_hook,
298*1208bc7eSAndroid Build Coastguard Worker extent_merge_hook
299*1208bc7eSAndroid Build Coastguard Worker };
300*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_arena_destroy_hooks_unmap)301*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_arena_destroy_hooks_unmap) {
302*1208bc7eSAndroid Build Coastguard Worker unsigned arena_ind;
303*1208bc7eSAndroid Build Coastguard Worker void **ptrs;
304*1208bc7eSAndroid Build Coastguard Worker unsigned nptrs;
305*1208bc7eSAndroid Build Coastguard Worker
306*1208bc7eSAndroid Build Coastguard Worker extent_hooks_prep();
307*1208bc7eSAndroid Build Coastguard Worker try_decommit = false;
308*1208bc7eSAndroid Build Coastguard Worker memcpy(&hooks_orig, &hooks, sizeof(extent_hooks_t));
309*1208bc7eSAndroid Build Coastguard Worker memcpy(&hooks, &hooks_unmap, sizeof(extent_hooks_t));
310*1208bc7eSAndroid Build Coastguard Worker
311*1208bc7eSAndroid Build Coastguard Worker did_alloc = false;
312*1208bc7eSAndroid Build Coastguard Worker arena_ind = do_arena_create(&hooks);
313*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_pre(arena_ind, &ptrs, &nptrs);
314*1208bc7eSAndroid Build Coastguard Worker
315*1208bc7eSAndroid Build Coastguard Worker assert_true(did_alloc, "Expected alloc");
316*1208bc7eSAndroid Build Coastguard Worker
317*1208bc7eSAndroid Build Coastguard Worker assert_false(arena_i_initialized(arena_ind, false),
318*1208bc7eSAndroid Build Coastguard Worker "Arena stats should not be initialized");
319*1208bc7eSAndroid Build Coastguard Worker assert_true(arena_i_initialized(arena_ind, true),
320*1208bc7eSAndroid Build Coastguard Worker "Arena stats should be initialized");
321*1208bc7eSAndroid Build Coastguard Worker
322*1208bc7eSAndroid Build Coastguard Worker did_dalloc = false;
323*1208bc7eSAndroid Build Coastguard Worker do_arena_destroy(arena_ind);
324*1208bc7eSAndroid Build Coastguard Worker assert_true(did_dalloc, "Expected dalloc");
325*1208bc7eSAndroid Build Coastguard Worker
326*1208bc7eSAndroid Build Coastguard Worker assert_false(arena_i_initialized(arena_ind, true),
327*1208bc7eSAndroid Build Coastguard Worker "Arena stats should not be initialized");
328*1208bc7eSAndroid Build Coastguard Worker assert_true(arena_i_initialized(MALLCTL_ARENAS_DESTROYED, false),
329*1208bc7eSAndroid Build Coastguard Worker "Destroyed arena stats should be initialized");
330*1208bc7eSAndroid Build Coastguard Worker
331*1208bc7eSAndroid Build Coastguard Worker do_arena_reset_post(ptrs, nptrs, arena_ind);
332*1208bc7eSAndroid Build Coastguard Worker
333*1208bc7eSAndroid Build Coastguard Worker memcpy(&hooks, &hooks_orig, sizeof(extent_hooks_t));
334*1208bc7eSAndroid Build Coastguard Worker }
335*1208bc7eSAndroid Build Coastguard Worker TEST_END
336*1208bc7eSAndroid Build Coastguard Worker
337*1208bc7eSAndroid Build Coastguard Worker int
main(void)338*1208bc7eSAndroid Build Coastguard Worker main(void) {
339*1208bc7eSAndroid Build Coastguard Worker return test(
340*1208bc7eSAndroid Build Coastguard Worker test_arena_reset,
341*1208bc7eSAndroid Build Coastguard Worker test_arena_destroy_initial,
342*1208bc7eSAndroid Build Coastguard Worker test_arena_destroy_hooks_default,
343*1208bc7eSAndroid Build Coastguard Worker test_arena_destroy_hooks_unmap);
344*1208bc7eSAndroid Build Coastguard Worker }
345