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