1 1.1 christos #include "test/jemalloc_test.h" 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Under percpu_arena, binding a thread to a manual arena (an index at or above 5 1.1 christos * the per-CPU auto range) is one-way: percpu never reclaims it (see 6 1.1 christos * arena_choose_impl). Setting thread.arena back to an index in the auto range 7 1.1 christos * resumes per-CPU selection instead of failing with EPERM. 8 1.1 christos */ 9 1.1 christos TEST_BEGIN(test_thread_arena_resume_percpu) { 10 1.1 christos test_skip_if(!have_percpu_arena 11 1.1 christos || !PERCPU_ARENA_ENABLED(opt_percpu_arena)); 12 1.1 christos 13 1.1 christos unsigned limit = percpu_arena_ind_limit(opt_percpu_arena); 14 1.1 christos /* Bypass the tcache so every allocation and free hits the arena. */ 15 1.1 christos const int flags = MALLOCX_TCACHE_NONE; 16 1.1 christos 17 1.1 christos void *warm = mallocx(1, 0); 18 1.1 christos expect_ptr_not_null(warm, "Unexpected mallocx() failure"); 19 1.1 christos dallocx(warm, 0); 20 1.1 christos 21 1.1 christos unsigned cur; 22 1.1 christos size_t sz = sizeof(cur); 23 1.1 christos expect_d_eq(mallctl("thread.arena", (void *)&cur, &sz, NULL, 0), 0, 24 1.1 christos "Unexpected mallctl() failure"); 25 1.1 christos expect_u_lt(cur, limit, "Thread should start on a per-CPU arena"); 26 1.1 christos 27 1.1 christos unsigned manual; 28 1.1 christos sz = sizeof(manual); 29 1.1 christos expect_d_eq(mallctl("arenas.create", (void *)&manual, &sz, NULL, 0), 0, 30 1.1 christos "Unexpected arenas.create() failure"); 31 1.1 christos expect_u_ge(manual, limit, "A manual arena is outside the per-CPU range"); 32 1.1 christos 33 1.1 christos unsigned old; 34 1.1 christos sz = sizeof(old); 35 1.1 christos expect_d_eq(mallctl("thread.arena", (void *)&old, &sz, (void *)&manual, 36 1.1 christos sizeof(manual)), 0, "Binding to a manual arena should be allowed"); 37 1.1 christos sz = sizeof(cur); 38 1.1 christos expect_d_eq(mallctl("thread.arena", (void *)&cur, &sz, NULL, 0), 0, 39 1.1 christos "Unexpected mallctl() failure"); 40 1.1 christos expect_u_eq(cur, manual, "Thread should be bound to the manual arena"); 41 1.1 christos 42 1.1 christos void *p_manual = mallocx(1024, flags); 43 1.1 christos expect_ptr_not_null(p_manual, "Unexpected mallocx() failure"); 44 1.1 christos unsigned found; 45 1.1 christos sz = sizeof(found); 46 1.1 christos expect_d_eq(mallctl("arenas.lookup", (void *)&found, &sz, 47 1.1 christos (void *)&p_manual, sizeof(p_manual)), 0, 48 1.1 christos "Unexpected arenas.lookup() failure"); 49 1.1 christos expect_u_eq(found, manual, "Allocation should come from the manual arena"); 50 1.1 christos 51 1.1 christos void *scratch = mallocx(1024, flags); 52 1.1 christos expect_ptr_not_null(scratch, "Unexpected mallocx() failure"); 53 1.1 christos dallocx(scratch, flags); 54 1.1 christos 55 1.1 christos unsigned resume = 0; 56 1.1 christos expect_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&resume, 57 1.1 christos sizeof(resume)), 0, "Should resume per-CPU selection, not fail"); 58 1.1 christos sz = sizeof(cur); 59 1.1 christos expect_d_eq(mallctl("thread.arena", (void *)&cur, &sz, NULL, 0), 0, 60 1.1 christos "Unexpected mallctl() failure"); 61 1.1 christos expect_u_lt(cur, limit, "Thread should be back on a per-CPU arena"); 62 1.1 christos 63 1.1 christos void *p_percpu = mallocx(1024, flags); 64 1.1 christos expect_ptr_not_null(p_percpu, "Unexpected mallocx() failure"); 65 1.1 christos sz = sizeof(found); 66 1.1 christos expect_d_eq(mallctl("arenas.lookup", (void *)&found, &sz, 67 1.1 christos (void *)&p_percpu, sizeof(p_percpu)), 0, 68 1.1 christos "Unexpected arenas.lookup() failure"); 69 1.1 christos expect_u_lt(found, limit, "Allocation should come from a per-CPU arena"); 70 1.1 christos dallocx(p_percpu, flags); 71 1.1 christos 72 1.1 christos /* Free the manual-arena region while bound to a different arena. */ 73 1.1 christos dallocx(p_manual, flags); 74 1.1 christos } 75 1.1 christos TEST_END 76 1.1 christos 77 1.1 christos int 78 1.1 christos main(void) { 79 1.1 christos return test( 80 1.1 christos test_thread_arena_resume_percpu); 81 1.1 christos } 82