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