summaryrefslogtreecommitdiff
path: root/test/unit/huge.c
blob: 53f6577b11dd57e2d37b321e0938d95bfee3794f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include "test/jemalloc_test.h"

/* Threshold: 2 << 20 = 2097152. */
const char *malloc_conf = "oversize_threshold:2097152";

#define HUGE_SZ (2 << 20)
#define SMALL_SZ (8)

TEST_BEGIN(huge_bind_thread) {
	unsigned arena1, arena2;
	size_t sz = sizeof(unsigned);

	/* Bind to a manual arena. */
	expect_d_eq(mallctl("arenas.create", &arena1, &sz, NULL, 0), 0,
	    "Failed to create arena");
	expect_d_eq(mallctl("thread.arena", NULL, NULL, &arena1,
	    sizeof(arena1)), 0, "Fail to bind thread");

	void *ptr = mallocx(HUGE_SZ, 0);
	expect_ptr_not_null(ptr, "Fail to allocate huge size");
	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
	expect_u_eq(arena1, arena2, "Wrong arena used after binding");
	dallocx(ptr, 0);

	/* Switch back to arena 0. */
	test_skip_if(have_percpu_arena &&
	    PERCPU_ARENA_ENABLED(opt_percpu_arena));
	arena2 = 0;
	expect_d_eq(mallctl("thread.arena", NULL, NULL, &arena2,
	    sizeof(arena2)), 0, "Fail to bind thread");
	ptr = mallocx(SMALL_SZ, MALLOCX_TCACHE_NONE);
	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
	expect_u_eq(arena2, 0, "Wrong arena used after binding");
	dallocx(ptr, MALLOCX_TCACHE_NONE);

	/* Then huge allocation should use the huge arena. */
	ptr = mallocx(HUGE_SZ, 0);
	expect_ptr_not_null(ptr, "Fail to allocate huge size");
	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
	expect_u_ne(arena2, 0, "Wrong arena used after binding");
	expect_u_ne(arena1, arena2, "Wrong arena used after binding");
	dallocx(ptr, 0);
}
TEST_END

TEST_BEGIN(huge_mallocx) {
	unsigned arena1, arena2;
	size_t sz = sizeof(unsigned);

	expect_d_eq(mallctl("arenas.create", &arena1, &sz, NULL, 0), 0,
	    "Failed to create arena");
	void *huge = mallocx(HUGE_SZ, MALLOCX_ARENA(arena1));
	expect_ptr_not_null(huge, "Fail to allocate huge size");
	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge,
	    sizeof(huge)), 0, "Unexpected mallctl() failure");
	expect_u_eq(arena1, arena2, "Wrong arena used for mallocx");
	dallocx(huge, MALLOCX_ARENA(arena1));

	void *huge2 = mallocx(HUGE_SZ, 0);
	expect_ptr_not_null(huge, "Fail to allocate huge size");
	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &huge2,
	    sizeof(huge2)), 0, "Unexpected mallctl() failure");
	expect_u_ne(arena1, arena2,
	    "Huge allocation should not come from the manual arena.");
	expect_u_ne(arena2, 0,
	    "Huge allocation should not come from the arena 0.");
	dallocx(huge2, 0);
}
TEST_END

TEST_BEGIN(huge_allocation) {
	unsigned arena1, arena2;

	void *ptr = mallocx(HUGE_SZ, 0);
	expect_ptr_not_null(ptr, "Fail to allocate huge size");
	size_t sz = sizeof(unsigned);
	expect_d_eq(mallctl("arenas.lookup", &arena1, &sz, &ptr, sizeof(ptr)),
	    0, "Unexpected mallctl() failure");
	expect_u_gt(arena1, 0, "Huge allocation should not come from arena 0");
	dallocx(ptr, 0);

	test_skip_if(have_percpu_arena &&
	    PERCPU_ARENA_ENABLED(opt_percpu_arena));

	ptr = mallocx(HUGE_SZ >> 1, 0);
	expect_ptr_not_null(ptr, "Fail to allocate half huge size");
	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
	expect_u_ne(arena1, arena2, "Wrong arena used for half huge");
	dallocx(ptr, 0);

	ptr = mallocx(SMALL_SZ, MALLOCX_TCACHE_NONE);
	expect_ptr_not_null(ptr, "Fail to allocate small size");
	expect_d_eq(mallctl("arenas.lookup", &arena2, &sz, &ptr,
	    sizeof(ptr)), 0, "Unexpected mallctl() failure");
	expect_u_ne(arena1, arena2,
	    "Huge and small should be from different arenas");
	dallocx(ptr, 0);
}
TEST_END

int
main(void) {
	return test(
	    huge_allocation,
	    huge_mallocx,
	    huge_bind_thread);
}