Add clipping support to lg_chunk option processing.

Modify processing of the lg_chunk option so that it clips an
out-of-range input to the edge of the valid range.  This makes it
possible to request the minimum possible chunk size without intimate
knowledge of allocator internals.

Submitted by Ian Lepore (see FreeBSD PR bin/174641).
This commit is contained in:
Jason Evans 2012-12-23 08:51:48 -08:00
parent 1271185b87
commit 1bf2743e08
2 changed files with 28 additions and 21 deletions

View File

@ -790,8 +790,11 @@ for (i = 0; i < nbins; i++) {
(<type>size_t</type>) (<type>size_t</type>)
<literal>r-</literal> <literal>r-</literal>
</term> </term>
<listitem><para>Virtual memory chunk size (log base 2). The default <listitem><para>Virtual memory chunk size (log base 2). If a chunk
chunk size is 4 MiB (2^22).</para></listitem> size outside the supported size range is specified, the size is
silently clipped to the minimum/maximum supported size. The default
chunk size is 4 MiB (2^22).
</para></listitem>
</varlistentry> </varlistentry>
<varlistentry id="opt.dss"> <varlistentry id="opt.dss">

View File

@ -469,7 +469,7 @@ malloc_conf_init(void)
while (*opts != '\0' && malloc_conf_next(&opts, &k, &klen, &v, while (*opts != '\0' && malloc_conf_next(&opts, &k, &klen, &v,
&vlen) == false) { &vlen) == false) {
#define CONF_HANDLE_BOOL_HIT(o, n, hit) \ #define CONF_HANDLE_BOOL(o, n) \
if (sizeof(n)-1 == klen && strncmp(n, k, \ if (sizeof(n)-1 == klen && strncmp(n, k, \
klen) == 0) { \ klen) == 0) { \
if (strncmp("true", v, vlen) == 0 && \ if (strncmp("true", v, vlen) == 0 && \
@ -483,16 +483,9 @@ malloc_conf_init(void)
"Invalid conf value", \ "Invalid conf value", \
k, klen, v, vlen); \ k, klen, v, vlen); \
} \ } \
hit = true; \
} else \
hit = false;
#define CONF_HANDLE_BOOL(o, n) { \
bool hit; \
CONF_HANDLE_BOOL_HIT(o, n, hit); \
if (hit) \
continue; \ continue; \
} }
#define CONF_HANDLE_SIZE_T(o, n, min, max) \ #define CONF_HANDLE_SIZE_T(o, n, min, max, clip) \
if (sizeof(n)-1 == klen && strncmp(n, k, \ if (sizeof(n)-1 == klen && strncmp(n, k, \
klen) == 0) { \ klen) == 0) { \
uintmax_t um; \ uintmax_t um; \
@ -505,12 +498,22 @@ malloc_conf_init(void)
malloc_conf_error( \ malloc_conf_error( \
"Invalid conf value", \ "Invalid conf value", \
k, klen, v, vlen); \ k, klen, v, vlen); \
} else if (um < min || um > max) { \ } else if (clip) { \
malloc_conf_error( \ if (um < min) \
"Out-of-range conf value", \ o = min; \
k, klen, v, vlen); \ else if (um > max) \
} else \ o = max; \
o = um; \ else \
o = um; \
} else { \
if (um < min || um > max) { \
malloc_conf_error( \
"Out-of-range " \
"conf value", \
k, klen, v, vlen); \
} else \
o = um; \
} \
continue; \ continue; \
} }
#define CONF_HANDLE_SSIZE_T(o, n, min, max) \ #define CONF_HANDLE_SSIZE_T(o, n, min, max) \
@ -555,7 +558,8 @@ malloc_conf_init(void)
* config_fill. * config_fill.
*/ */
CONF_HANDLE_SIZE_T(opt_lg_chunk, "lg_chunk", LG_PAGE + CONF_HANDLE_SIZE_T(opt_lg_chunk, "lg_chunk", LG_PAGE +
(config_fill ? 2 : 1), (sizeof(size_t) << 3) - 1) (config_fill ? 2 : 1), (sizeof(size_t) << 3) - 1,
true)
if (strncmp("dss", k, klen) == 0) { if (strncmp("dss", k, klen) == 0) {
int i; int i;
bool match = false; bool match = false;
@ -581,14 +585,14 @@ malloc_conf_init(void)
continue; continue;
} }
CONF_HANDLE_SIZE_T(opt_narenas, "narenas", 1, CONF_HANDLE_SIZE_T(opt_narenas, "narenas", 1,
SIZE_T_MAX) SIZE_T_MAX, false)
CONF_HANDLE_SSIZE_T(opt_lg_dirty_mult, "lg_dirty_mult", CONF_HANDLE_SSIZE_T(opt_lg_dirty_mult, "lg_dirty_mult",
-1, (sizeof(size_t) << 3) - 1) -1, (sizeof(size_t) << 3) - 1)
CONF_HANDLE_BOOL(opt_stats_print, "stats_print") CONF_HANDLE_BOOL(opt_stats_print, "stats_print")
if (config_fill) { if (config_fill) {
CONF_HANDLE_BOOL(opt_junk, "junk") CONF_HANDLE_BOOL(opt_junk, "junk")
CONF_HANDLE_SIZE_T(opt_quarantine, "quarantine", CONF_HANDLE_SIZE_T(opt_quarantine, "quarantine",
0, SIZE_T_MAX) 0, SIZE_T_MAX, false)
CONF_HANDLE_BOOL(opt_redzone, "redzone") CONF_HANDLE_BOOL(opt_redzone, "redzone")
CONF_HANDLE_BOOL(opt_zero, "zero") CONF_HANDLE_BOOL(opt_zero, "zero")
} }