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