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