1#include "test/jemalloc_test.h"
2
3#ifdef JEMALLOC_PROF
4const char *malloc_conf = "prof:true,lg_prof_sample:0";
5#endif
6
7static unsigned
8get_nsizes_impl(const char *cmd)
9{
10	unsigned ret;
11	size_t z;
12
13	z = sizeof(unsigned);
14	assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
15	    "Unexpected mallctl(\"%s\", ...) failure", cmd);
16
17	return (ret);
18}
19
20static unsigned
21get_nsmall(void)
22{
23
24	return (get_nsizes_impl("arenas.nbins"));
25}
26
27static unsigned
28get_nlarge(void)
29{
30
31	return (get_nsizes_impl("arenas.nlruns"));
32}
33
34static unsigned
35get_nhuge(void)
36{
37
38	return (get_nsizes_impl("arenas.nhchunks"));
39}
40
41static size_t
42get_size_impl(const char *cmd, size_t ind)
43{
44	size_t ret;
45	size_t z;
46	size_t mib[4];
47	size_t miblen = 4;
48
49	z = sizeof(size_t);
50	assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
51	    0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
52	mib[2] = ind;
53	z = sizeof(size_t);
54	assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
55	    0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
56
57	return (ret);
58}
59
60static size_t
61get_small_size(size_t ind)
62{
63
64	return (get_size_impl("arenas.bin.0.size", ind));
65}
66
67static size_t
68get_large_size(size_t ind)
69{
70
71	return (get_size_impl("arenas.lrun.0.size", ind));
72}
73
74static size_t
75get_huge_size(size_t ind)
76{
77
78	return (get_size_impl("arenas.hchunk.0.size", ind));
79}
80
81TEST_BEGIN(test_arena_reset)
82{
83#define	NHUGE	4
84	unsigned arena_ind, nsmall, nlarge, nhuge, nptrs, i;
85	size_t sz, miblen;
86	void **ptrs;
87	int flags;
88	size_t mib[3];
89	tsdn_t *tsdn;
90
91	test_skip_if((config_valgrind && unlikely(in_valgrind)) || (config_fill
92	    && unlikely(opt_quarantine)));
93
94	sz = sizeof(unsigned);
95	assert_d_eq(mallctl("arenas.extend", (void *)&arena_ind, &sz, NULL, 0),
96	    0, "Unexpected mallctl() failure");
97
98	flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
99
100	nsmall = get_nsmall();
101	nlarge = get_nlarge();
102	nhuge = get_nhuge() > NHUGE ? NHUGE : get_nhuge();
103	nptrs = nsmall + nlarge + nhuge;
104	ptrs = (void **)malloc(nptrs * sizeof(void *));
105	assert_ptr_not_null(ptrs, "Unexpected malloc() failure");
106
107	/* Allocate objects with a wide range of sizes. */
108	for (i = 0; i < nsmall; i++) {
109		sz = get_small_size(i);
110		ptrs[i] = mallocx(sz, flags);
111		assert_ptr_not_null(ptrs[i],
112		    "Unexpected mallocx(%zu, %#x) failure", sz, flags);
113	}
114	for (i = 0; i < nlarge; i++) {
115		sz = get_large_size(i);
116		ptrs[nsmall + i] = mallocx(sz, flags);
117		assert_ptr_not_null(ptrs[i],
118		    "Unexpected mallocx(%zu, %#x) failure", sz, flags);
119	}
120	for (i = 0; i < nhuge; i++) {
121		sz = get_huge_size(i);
122		ptrs[nsmall + nlarge + i] = mallocx(sz, flags);
123		assert_ptr_not_null(ptrs[i],
124		    "Unexpected mallocx(%zu, %#x) failure", sz, flags);
125	}
126
127	tsdn = tsdn_fetch();
128
129	/* Verify allocations. */
130	for (i = 0; i < nptrs; i++) {
131		assert_zu_gt(ivsalloc(tsdn, ptrs[i], false), 0,
132		    "Allocation should have queryable size");
133	}
134
135	/* Reset. */
136	miblen = sizeof(mib)/sizeof(size_t);
137	assert_d_eq(mallctlnametomib("arena.0.reset", mib, &miblen), 0,
138	    "Unexpected mallctlnametomib() failure");
139	mib[1] = (size_t)arena_ind;
140	assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
141	    "Unexpected mallctlbymib() failure");
142
143	/* Verify allocations no longer exist. */
144	for (i = 0; i < nptrs; i++) {
145		assert_zu_eq(ivsalloc(tsdn, ptrs[i], false), 0,
146		    "Allocation should no longer exist");
147	}
148
149	free(ptrs);
150}
151TEST_END
152
153int
154main(void)
155{
156
157	return (test(
158	    test_arena_reset));
159}
160