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