xref: /netbsd-src/external/bsd/jemalloc/dist/test/unit/huge.c (revision 7bdf38e5b7a28439665f2fdeff81e36913eef7dd)
1*7bdf38e5Schristos #include "test/jemalloc_test.h"
2*7bdf38e5Schristos 
3*7bdf38e5Schristos /* Threshold: 2 << 20 = 2097152. */
4*7bdf38e5Schristos const char *malloc_conf = "oversize_threshold:2097152";
5*7bdf38e5Schristos 
6*7bdf38e5Schristos #define HUGE_SZ (2 << 20)
7*7bdf38e5Schristos #define SMALL_SZ (8)
8*7bdf38e5Schristos 
9*7bdf38e5Schristos TEST_BEGIN(huge_bind_thread) {
10*7bdf38e5Schristos 	unsigned arena1, arena2;
11*7bdf38e5Schristos 	size_t sz = sizeof(unsigned);
12*7bdf38e5Schristos 
13*7bdf38e5Schristos 	/* Bind to a manual arena. */
14*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.create", &arena1, &sz, NULL, 0), 0,
15*7bdf38e5Schristos 	    "Failed to create arena");
16*7bdf38e5Schristos 	expect_d_eq(mallctl("thread.arena", NULL, NULL, &arena1,
17*7bdf38e5Schristos 	    sizeof(arena1)), 0, "Fail to bind thread");
18*7bdf38e5Schristos 
19*7bdf38e5Schristos 	void *ptr = mallocx(HUGE_SZ, 0);
20*7bdf38e5Schristos 	expect_ptr_not_null(ptr, "Fail to allocate huge size");
21*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
22*7bdf38e5Schristos 	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
23*7bdf38e5Schristos 	expect_u_eq(arena1, arena2, "Wrong arena used after binding");
24*7bdf38e5Schristos 	dallocx(ptr, 0);
25*7bdf38e5Schristos 
26*7bdf38e5Schristos 	/* Switch back to arena 0. */
27*7bdf38e5Schristos 	test_skip_if(have_percpu_arena &&
28*7bdf38e5Schristos 	    PERCPU_ARENA_ENABLED(opt_percpu_arena));
29*7bdf38e5Schristos 	arena2 = 0;
30*7bdf38e5Schristos 	expect_d_eq(mallctl("thread.arena", NULL, NULL, &arena2,
31*7bdf38e5Schristos 	    sizeof(arena2)), 0, "Fail to bind thread");
32*7bdf38e5Schristos 	ptr = mallocx(SMALL_SZ, MALLOCX_TCACHE_NONE);
33*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
34*7bdf38e5Schristos 	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
35*7bdf38e5Schristos 	expect_u_eq(arena2, 0, "Wrong arena used after binding");
36*7bdf38e5Schristos 	dallocx(ptr, MALLOCX_TCACHE_NONE);
37*7bdf38e5Schristos 
38*7bdf38e5Schristos 	/* Then huge allocation should use the huge arena. */
39*7bdf38e5Schristos 	ptr = mallocx(HUGE_SZ, 0);
40*7bdf38e5Schristos 	expect_ptr_not_null(ptr, "Fail to allocate huge size");
41*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
42*7bdf38e5Schristos 	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
43*7bdf38e5Schristos 	expect_u_ne(arena2, 0, "Wrong arena used after binding");
44*7bdf38e5Schristos 	expect_u_ne(arena1, arena2, "Wrong arena used after binding");
45*7bdf38e5Schristos 	dallocx(ptr, 0);
46*7bdf38e5Schristos }
47*7bdf38e5Schristos TEST_END
48*7bdf38e5Schristos 
49*7bdf38e5Schristos TEST_BEGIN(huge_mallocx) {
50*7bdf38e5Schristos 	unsigned arena1, arena2;
51*7bdf38e5Schristos 	size_t sz = sizeof(unsigned);
52*7bdf38e5Schristos 
53*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.create", &arena1, &sz, NULL, 0), 0,
54*7bdf38e5Schristos 	    "Failed to create arena");
55*7bdf38e5Schristos 	void *huge = mallocx(HUGE_SZ, MALLOCX_ARENA(arena1));
56*7bdf38e5Schristos 	expect_ptr_not_null(huge, "Fail to allocate huge size");
57*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge,
58*7bdf38e5Schristos 	    sizeof(huge)), 0, "Unexpected mallctl() failure");
59*7bdf38e5Schristos 	expect_u_eq(arena1, arena2, "Wrong arena used for mallocx");
60*7bdf38e5Schristos 	dallocx(huge, MALLOCX_ARENA(arena1));
61*7bdf38e5Schristos 
62*7bdf38e5Schristos 	void *huge2 = mallocx(HUGE_SZ, 0);
63*7bdf38e5Schristos 	expect_ptr_not_null(huge, "Fail to allocate huge size");
64*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge2,
65*7bdf38e5Schristos 	    sizeof(huge2)), 0, "Unexpected mallctl() failure");
66*7bdf38e5Schristos 	expect_u_ne(arena1, arena2,
67*7bdf38e5Schristos 	    "Huge allocation should not come from the manual arena.");
68*7bdf38e5Schristos 	expect_u_ne(arena2, 0,
69*7bdf38e5Schristos 	    "Huge allocation should not come from the arena 0.");
70*7bdf38e5Schristos 	dallocx(huge2, 0);
71*7bdf38e5Schristos }
72*7bdf38e5Schristos TEST_END
73*7bdf38e5Schristos 
74*7bdf38e5Schristos TEST_BEGIN(huge_allocation) {
75*7bdf38e5Schristos 	unsigned arena1, arena2;
76*7bdf38e5Schristos 
77*7bdf38e5Schristos 	void *ptr = mallocx(HUGE_SZ, 0);
78*7bdf38e5Schristos 	expect_ptr_not_null(ptr, "Fail to allocate huge size");
79*7bdf38e5Schristos 	size_t sz = sizeof(unsigned);
80*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.lookup", &arena1, &sz, &ptr, sizeof(ptr)),
81*7bdf38e5Schristos 	    0, "Unexpected mallctl() failure");
82*7bdf38e5Schristos 	expect_u_gt(arena1, 0, "Huge allocation should not come from arena 0");
83*7bdf38e5Schristos 	dallocx(ptr, 0);
84*7bdf38e5Schristos 
85*7bdf38e5Schristos 	ptr = mallocx(HUGE_SZ >> 1, 0);
86*7bdf38e5Schristos 	expect_ptr_not_null(ptr, "Fail to allocate half huge size");
87*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
88*7bdf38e5Schristos 	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
89*7bdf38e5Schristos 	expect_u_ne(arena1, arena2, "Wrong arena used for half huge");
90*7bdf38e5Schristos 	dallocx(ptr, 0);
91*7bdf38e5Schristos 
92*7bdf38e5Schristos 	ptr = mallocx(SMALL_SZ, MALLOCX_TCACHE_NONE);
93*7bdf38e5Schristos 	expect_ptr_not_null(ptr, "Fail to allocate small size");
94*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
95*7bdf38e5Schristos 	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
96*7bdf38e5Schristos 	expect_u_ne(arena1, arena2,
97*7bdf38e5Schristos 	    "Huge and small should be from different arenas");
98*7bdf38e5Schristos 	dallocx(ptr, 0);
99*7bdf38e5Schristos }
100*7bdf38e5Schristos TEST_END
101*7bdf38e5Schristos 
102*7bdf38e5Schristos int
103*7bdf38e5Schristos main(void) {
104*7bdf38e5Schristos 	return test(
105*7bdf38e5Schristos 	    huge_allocation,
106*7bdf38e5Schristos 	    huge_mallocx,
107*7bdf38e5Schristos 	    huge_bind_thread);
108*7bdf38e5Schristos }
109