1*8e33eff8Schristos #include "test/jemalloc_test.h" 2*8e33eff8Schristos 3*8e33eff8Schristos TEST_BEGIN(test_small_extent_size) { 4*8e33eff8Schristos unsigned nbins, i; 5*8e33eff8Schristos size_t sz, extent_size; 6*8e33eff8Schristos size_t mib[4]; 7*8e33eff8Schristos size_t miblen = sizeof(mib) / sizeof(size_t); 8*8e33eff8Schristos 9*8e33eff8Schristos /* 10*8e33eff8Schristos * Iterate over all small size classes, get their extent sizes, and 11*8e33eff8Schristos * verify that the quantized size is the same as the extent size. 12*8e33eff8Schristos */ 13*8e33eff8Schristos 14*8e33eff8Schristos sz = sizeof(unsigned); 15*8e33eff8Schristos assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0, 16*8e33eff8Schristos "Unexpected mallctl failure"); 17*8e33eff8Schristos 18*8e33eff8Schristos assert_d_eq(mallctlnametomib("arenas.bin.0.slab_size", mib, &miblen), 0, 19*8e33eff8Schristos "Unexpected mallctlnametomib failure"); 20*8e33eff8Schristos for (i = 0; i < nbins; i++) { 21*8e33eff8Schristos mib[2] = i; 22*8e33eff8Schristos sz = sizeof(size_t); 23*8e33eff8Schristos assert_d_eq(mallctlbymib(mib, miblen, (void *)&extent_size, &sz, 24*8e33eff8Schristos NULL, 0), 0, "Unexpected mallctlbymib failure"); 25*8e33eff8Schristos assert_zu_eq(extent_size, 26*8e33eff8Schristos extent_size_quantize_floor(extent_size), 27*8e33eff8Schristos "Small extent quantization should be a no-op " 28*8e33eff8Schristos "(extent_size=%zu)", extent_size); 29*8e33eff8Schristos assert_zu_eq(extent_size, 30*8e33eff8Schristos extent_size_quantize_ceil(extent_size), 31*8e33eff8Schristos "Small extent quantization should be a no-op " 32*8e33eff8Schristos "(extent_size=%zu)", extent_size); 33*8e33eff8Schristos } 34*8e33eff8Schristos } 35*8e33eff8Schristos TEST_END 36*8e33eff8Schristos 37*8e33eff8Schristos TEST_BEGIN(test_large_extent_size) { 38*8e33eff8Schristos bool cache_oblivious; 39*8e33eff8Schristos unsigned nlextents, i; 40*8e33eff8Schristos size_t sz, extent_size_prev, ceil_prev; 41*8e33eff8Schristos size_t mib[4]; 42*8e33eff8Schristos size_t miblen = sizeof(mib) / sizeof(size_t); 43*8e33eff8Schristos 44*8e33eff8Schristos /* 45*8e33eff8Schristos * Iterate over all large size classes, get their extent sizes, and 46*8e33eff8Schristos * verify that the quantized size is the same as the extent size. 47*8e33eff8Schristos */ 48*8e33eff8Schristos 49*8e33eff8Schristos sz = sizeof(bool); 50*8e33eff8Schristos assert_d_eq(mallctl("config.cache_oblivious", (void *)&cache_oblivious, 51*8e33eff8Schristos &sz, NULL, 0), 0, "Unexpected mallctl failure"); 52*8e33eff8Schristos 53*8e33eff8Schristos sz = sizeof(unsigned); 54*8e33eff8Schristos assert_d_eq(mallctl("arenas.nlextents", (void *)&nlextents, &sz, NULL, 55*8e33eff8Schristos 0), 0, "Unexpected mallctl failure"); 56*8e33eff8Schristos 57*8e33eff8Schristos assert_d_eq(mallctlnametomib("arenas.lextent.0.size", mib, &miblen), 0, 58*8e33eff8Schristos "Unexpected mallctlnametomib failure"); 59*8e33eff8Schristos for (i = 0; i < nlextents; i++) { 60*8e33eff8Schristos size_t lextent_size, extent_size, floor, ceil; 61*8e33eff8Schristos 62*8e33eff8Schristos mib[2] = i; 63*8e33eff8Schristos sz = sizeof(size_t); 64*8e33eff8Schristos assert_d_eq(mallctlbymib(mib, miblen, (void *)&lextent_size, 65*8e33eff8Schristos &sz, NULL, 0), 0, "Unexpected mallctlbymib failure"); 66*8e33eff8Schristos extent_size = cache_oblivious ? lextent_size + PAGE : 67*8e33eff8Schristos lextent_size; 68*8e33eff8Schristos floor = extent_size_quantize_floor(extent_size); 69*8e33eff8Schristos ceil = extent_size_quantize_ceil(extent_size); 70*8e33eff8Schristos 71*8e33eff8Schristos assert_zu_eq(extent_size, floor, 72*8e33eff8Schristos "Extent quantization should be a no-op for precise size " 73*8e33eff8Schristos "(lextent_size=%zu, extent_size=%zu)", lextent_size, 74*8e33eff8Schristos extent_size); 75*8e33eff8Schristos assert_zu_eq(extent_size, ceil, 76*8e33eff8Schristos "Extent quantization should be a no-op for precise size " 77*8e33eff8Schristos "(lextent_size=%zu, extent_size=%zu)", lextent_size, 78*8e33eff8Schristos extent_size); 79*8e33eff8Schristos 80*8e33eff8Schristos if (i > 0) { 81*8e33eff8Schristos assert_zu_eq(extent_size_prev, 82*8e33eff8Schristos extent_size_quantize_floor(extent_size - PAGE), 83*8e33eff8Schristos "Floor should be a precise size"); 84*8e33eff8Schristos if (extent_size_prev < ceil_prev) { 85*8e33eff8Schristos assert_zu_eq(ceil_prev, extent_size, 86*8e33eff8Schristos "Ceiling should be a precise size " 87*8e33eff8Schristos "(extent_size_prev=%zu, ceil_prev=%zu, " 88*8e33eff8Schristos "extent_size=%zu)", extent_size_prev, 89*8e33eff8Schristos ceil_prev, extent_size); 90*8e33eff8Schristos } 91*8e33eff8Schristos } 92*8e33eff8Schristos if (i + 1 < nlextents) { 93*8e33eff8Schristos extent_size_prev = floor; 94*8e33eff8Schristos ceil_prev = extent_size_quantize_ceil(extent_size + 95*8e33eff8Schristos PAGE); 96*8e33eff8Schristos } 97*8e33eff8Schristos } 98*8e33eff8Schristos } 99*8e33eff8Schristos TEST_END 100*8e33eff8Schristos 101*8e33eff8Schristos TEST_BEGIN(test_monotonic) { 102*8e33eff8Schristos #define SZ_MAX ZU(4 * 1024 * 1024) 103*8e33eff8Schristos unsigned i; 104*8e33eff8Schristos size_t floor_prev, ceil_prev; 105*8e33eff8Schristos 106*8e33eff8Schristos floor_prev = 0; 107*8e33eff8Schristos ceil_prev = 0; 108*8e33eff8Schristos for (i = 1; i <= SZ_MAX >> LG_PAGE; i++) { 109*8e33eff8Schristos size_t extent_size, floor, ceil; 110*8e33eff8Schristos 111*8e33eff8Schristos extent_size = i << LG_PAGE; 112*8e33eff8Schristos floor = extent_size_quantize_floor(extent_size); 113*8e33eff8Schristos ceil = extent_size_quantize_ceil(extent_size); 114*8e33eff8Schristos 115*8e33eff8Schristos assert_zu_le(floor, extent_size, 116*8e33eff8Schristos "Floor should be <= (floor=%zu, extent_size=%zu, ceil=%zu)", 117*8e33eff8Schristos floor, extent_size, ceil); 118*8e33eff8Schristos assert_zu_ge(ceil, extent_size, 119*8e33eff8Schristos "Ceiling should be >= (floor=%zu, extent_size=%zu, " 120*8e33eff8Schristos "ceil=%zu)", floor, extent_size, ceil); 121*8e33eff8Schristos 122*8e33eff8Schristos assert_zu_le(floor_prev, floor, "Floor should be monotonic " 123*8e33eff8Schristos "(floor_prev=%zu, floor=%zu, extent_size=%zu, ceil=%zu)", 124*8e33eff8Schristos floor_prev, floor, extent_size, ceil); 125*8e33eff8Schristos assert_zu_le(ceil_prev, ceil, "Ceiling should be monotonic " 126*8e33eff8Schristos "(floor=%zu, extent_size=%zu, ceil_prev=%zu, ceil=%zu)", 127*8e33eff8Schristos floor, extent_size, ceil_prev, ceil); 128*8e33eff8Schristos 129*8e33eff8Schristos floor_prev = floor; 130*8e33eff8Schristos ceil_prev = ceil; 131*8e33eff8Schristos } 132*8e33eff8Schristos } 133*8e33eff8Schristos TEST_END 134*8e33eff8Schristos 135*8e33eff8Schristos int 136*8e33eff8Schristos main(void) { 137*8e33eff8Schristos return test( 138*8e33eff8Schristos test_small_extent_size, 139*8e33eff8Schristos test_large_extent_size, 140*8e33eff8Schristos test_monotonic); 141*8e33eff8Schristos } 142