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