diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in index 8e9a5d8f..e5f2aa67 100644 --- a/doc/jemalloc.xml.in +++ b/doc/jemalloc.xml.in @@ -1301,21 +1301,23 @@ malloc_conf = "xmalloc:true";]]> a certain size. Thread-specific caching allows many allocations to be satisfied without performing any thread synchronization, at the cost of increased memory use. See the opt.lg_tcache_max + linkend="opt.tcache_max">opt.tcache_max option for related tuning information. This option is enabled by default. - + - opt.lg_tcache_max + opt.tcache_max (size_t) r- - Maximum size class (log base 2) to cache in the - thread-specific cache (tcache). At a minimum, all small size classes - are cached; and at a maximum, size classes up to 8 MiB can be cached. - The default maximum is 32 KiB (2^15). + Maximum size class to cache in the thread-specific cache + (tcache). At a minimum, all small size classes are cached; and at a + maximum, size classes up to 8 MiB can be cached. The default maximum is + 32 KiB (2^15). As a convenience, this may also be set by specifying + lg_tcache_max, which will be taken to be the base-2 logarithm of the + setting of tcache_max diff --git a/include/jemalloc/internal/tcache_externs.h b/include/jemalloc/internal/tcache_externs.h index f044d322..95f3a682 100644 --- a/include/jemalloc/internal/tcache_externs.h +++ b/include/jemalloc/internal/tcache_externs.h @@ -2,7 +2,7 @@ #define JEMALLOC_INTERNAL_TCACHE_EXTERNS_H extern bool opt_tcache; -extern ssize_t opt_lg_tcache_max; +extern size_t opt_tcache_max; extern ssize_t opt_lg_tcache_nslots_mul; extern unsigned opt_tcache_nslots_small_min; extern unsigned opt_tcache_nslots_small_max; diff --git a/src/ctl.c b/src/ctl.c index aec3473e..db0e05f0 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -109,7 +109,7 @@ CTL_PROTO(opt_zero) CTL_PROTO(opt_utrace) CTL_PROTO(opt_xmalloc) CTL_PROTO(opt_tcache) -CTL_PROTO(opt_lg_tcache_max) +CTL_PROTO(opt_tcache_max) CTL_PROTO(opt_tcache_nslots_small_min) CTL_PROTO(opt_tcache_nslots_small_max) CTL_PROTO(opt_tcache_nslots_large) @@ -362,7 +362,7 @@ static const ctl_named_node_t opt_node[] = { {NAME("utrace"), CTL(opt_utrace)}, {NAME("xmalloc"), CTL(opt_xmalloc)}, {NAME("tcache"), CTL(opt_tcache)}, - {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, + {NAME("tcache_max"), CTL(opt_tcache_max)}, {NAME("tcache_nslots_small_min"), CTL(opt_tcache_nslots_small_min)}, {NAME("tcache_nslots_small_max"), @@ -1837,7 +1837,7 @@ CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool) CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) CTL_RO_NL_GEN(opt_tcache, opt_tcache, bool) -CTL_RO_NL_GEN(opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) +CTL_RO_NL_GEN(opt_tcache_max, opt_tcache_max, size_t) CTL_RO_NL_GEN(opt_tcache_nslots_small_min, opt_tcache_nslots_small_min, unsigned) CTL_RO_NL_GEN(opt_tcache_nslots_small_max, opt_tcache_nslots_small_max, diff --git a/src/jemalloc.c b/src/jemalloc.c index 1d6191ae..170b1723 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -1170,15 +1170,18 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS], #define CONF_DONT_CHECK_MAX(um, max) false #define CONF_CHECK_MAX(um, max) ((um) > (max)) +#define CONF_VALUE_READ(max_t, result) \ + char *end; \ + set_errno(0); \ + result = (max_t)malloc_strtoumax(v, &end, 0); +#define CONF_VALUE_READ_FAIL() \ + (get_errno() != 0 || (uintptr_t)end - (uintptr_t)v != vlen) + #define CONF_HANDLE_T(t, max_t, o, n, min, max, check_min, check_max, clip) \ if (CONF_MATCH(n)) { \ max_t mv; \ - char *end; \ - \ - set_errno(0); \ - mv = (max_t)malloc_strtoumax(v, &end, 0); \ - if (get_errno() != 0 || (uintptr_t)end -\ - (uintptr_t)v != vlen) { \ + CONF_VALUE_READ(max_t, mv) \ + if (CONF_VALUE_READ_FAIL()) { \ CONF_ERROR("Invalid conf value",\ k, klen, v, vlen); \ } else if (clip) { \ @@ -1379,8 +1382,24 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS], CONF_HANDLE_BOOL(opt_xmalloc, "xmalloc") } CONF_HANDLE_BOOL(opt_tcache, "tcache") - CONF_HANDLE_SSIZE_T(opt_lg_tcache_max, "lg_tcache_max", - -1, (sizeof(size_t) << 3) - 1) + CONF_HANDLE_SIZE_T(opt_tcache_max, "tcache_max", + 0, TCACHE_MAXCLASS_LIMIT, CONF_DONT_CHECK_MIN, + CONF_CHECK_MAX, /* clip */ true) + if (CONF_MATCH("lg_tcache_max")) { + size_t m; + CONF_VALUE_READ(size_t, m) + if (CONF_VALUE_READ_FAIL()) { + CONF_ERROR("Invalid conf value", + k, klen, v, vlen); + } else { + /* clip if necessary */ + if (m > TCACHE_LG_MAXCLASS_LIMIT) { + m = TCACHE_LG_MAXCLASS_LIMIT; + } + opt_tcache_max = (size_t)1 << m; + } + CONF_CONTINUE; + } /* * Anyone trying to set a value outside -16 to 16 is * deeply confused. diff --git a/src/tcache.c b/src/tcache.c index 63eddc2d..6bf1d309 100644 --- a/src/tcache.c +++ b/src/tcache.c @@ -11,11 +11,8 @@ bool opt_tcache = true; -/* - * (1U << opt_lg_tcache_max) is used to compute tcache_maxclass. This choice - * (32kb by default) works well as a default in practice. - */ -ssize_t opt_lg_tcache_max = 15; +/* tcache_maxclass is set to 32KB by default. */ +size_t opt_tcache_max = ((size_t)1) << 15; /* Reasonable defaults for min and max values. */ unsigned opt_tcache_nslots_small_min = 20; @@ -935,14 +932,11 @@ tcache_ncached_max_compute(szind_t szind) { bool tcache_boot(tsdn_t *tsdn, base_t *base) { - /* If necessary, clamp opt_lg_tcache_max. */ - tcache_maxclass = opt_lg_tcache_max < 0 ? 0 : - ZU(1) << opt_lg_tcache_max; + tcache_maxclass = sz_s2u(opt_tcache_max); if (tcache_maxclass < SC_SMALL_MAXCLASS) { tcache_maxclass = SC_SMALL_MAXCLASS; - } else if (tcache_maxclass > TCACHE_MAXCLASS_LIMIT) { - tcache_maxclass = TCACHE_MAXCLASS_LIMIT; } + assert(tcache_maxclass <= TCACHE_MAXCLASS_LIMIT); nhbins = sz_size2index(tcache_maxclass) + 1; if (malloc_mutex_init(&tcaches_mtx, "tcaches", WITNESS_RANK_TCACHES, diff --git a/test/unit/mallctl.c b/test/unit/mallctl.c index 3de56947..cf5c88e0 100644 --- a/test/unit/mallctl.c +++ b/test/unit/mallctl.c @@ -179,7 +179,7 @@ TEST_BEGIN(test_mallctl_opt) { TEST_MALLCTL_OPT(bool, xmalloc, xmalloc); TEST_MALLCTL_OPT(bool, tcache, always); TEST_MALLCTL_OPT(size_t, lg_extent_max_active_fit, always); - TEST_MALLCTL_OPT(size_t, lg_tcache_max, always); + TEST_MALLCTL_OPT(size_t, tcache_max, always); TEST_MALLCTL_OPT(const char *, thp, always); TEST_MALLCTL_OPT(const char *, zero_realloc, always); TEST_MALLCTL_OPT(bool, prof, prof); diff --git a/test/unit/stats.c b/test/unit/stats.c index 20a32ddf..21a29a6f 100644 --- a/test/unit/stats.c +++ b/test/unit/stats.c @@ -393,7 +393,7 @@ test_tcache_bytes_for_usize(size_t usize) { TEST_BEGIN(test_stats_tcache_bytes_small) { test_skip_if(!config_stats); test_skip_if(!opt_tcache); - test_skip_if((ZU(1) << opt_lg_tcache_max) < SC_SMALL_MAXCLASS); + test_skip_if(opt_tcache_max < SC_SMALL_MAXCLASS); test_tcache_bytes_for_usize(SC_SMALL_MAXCLASS); } @@ -402,7 +402,7 @@ TEST_END TEST_BEGIN(test_stats_tcache_bytes_large) { test_skip_if(!config_stats); test_skip_if(!opt_tcache); - test_skip_if((ZU(1) << opt_lg_tcache_max) < SC_LARGE_MINCLASS); + test_skip_if(opt_tcache_max < SC_LARGE_MINCLASS); test_tcache_bytes_for_usize(SC_LARGE_MINCLASS); }