Always initialize tcache data structures.

Always initialize tcache data structures if the tcache configuration
option is enabled, regardless of opt_tcache.  This fixes
"thread.tcache.enabled" mallctl manipulation in the case when opt_tcache
is false.
This commit is contained in:
Jason Evans 2012-04-06 12:41:55 -07:00
parent fad100bc35
commit 3701367e4c

View File

@ -334,17 +334,17 @@ tcache_thread_cleanup(void *arg)
} else if (tcache == TCACHE_STATE_REINCARNATED) { } else if (tcache == TCACHE_STATE_REINCARNATED) {
/* /*
* Another destructor called an allocator function after this * Another destructor called an allocator function after this
* destructor was called. Reset tcache to 1 in order to * destructor was called. Reset tcache to
* receive another callback. * TCACHE_STATE_PURGATORY in order to receive another callback.
*/ */
tcache = TCACHE_STATE_PURGATORY; tcache = TCACHE_STATE_PURGATORY;
tcache_tsd_set(&tcache); tcache_tsd_set(&tcache);
} else if (tcache == TCACHE_STATE_PURGATORY) { } else if (tcache == TCACHE_STATE_PURGATORY) {
/* /*
* The previous time this destructor was called, we set the key * The previous time this destructor was called, we set the key
* to 1 so that other destructors wouldn't cause re-creation of * to TCACHE_STATE_PURGATORY so that other destructors wouldn't
* the tcache. This time, do nothing, so that the destructor * cause re-creation of the tcache. This time, do nothing, so
* will not be called again. * that the destructor will not be called again.
*/ */
} else if (tcache != NULL) { } else if (tcache != NULL) {
assert(tcache != TCACHE_STATE_PURGATORY); assert(tcache != TCACHE_STATE_PURGATORY);
@ -381,46 +381,40 @@ tcache_stats_merge(tcache_t *tcache, arena_t *arena)
bool bool
tcache_boot0(void) tcache_boot0(void)
{ {
unsigned i;
if (opt_tcache) { /*
unsigned i; * If necessary, clamp opt_lg_tcache_max, now that arena_maxclass is
* known.
*/
if (opt_lg_tcache_max < 0 || (1U << opt_lg_tcache_max) < SMALL_MAXCLASS)
tcache_maxclass = SMALL_MAXCLASS;
else if ((1U << opt_lg_tcache_max) > arena_maxclass)
tcache_maxclass = arena_maxclass;
else
tcache_maxclass = (1U << opt_lg_tcache_max);
/* nhbins = NBINS + (tcache_maxclass >> LG_PAGE);
* If necessary, clamp opt_lg_tcache_max, now that
* SMALL_MAXCLASS and arena_maxclass are known.
* XXX Can this be done earlier?
*/
if (opt_lg_tcache_max < 0 || (1U << opt_lg_tcache_max) <
SMALL_MAXCLASS)
tcache_maxclass = SMALL_MAXCLASS;
else if ((1U << opt_lg_tcache_max) > arena_maxclass)
tcache_maxclass = arena_maxclass;
else
tcache_maxclass = (1U << opt_lg_tcache_max);
nhbins = NBINS + (tcache_maxclass >> LG_PAGE); /* Initialize tcache_bin_info. */
tcache_bin_info = (tcache_bin_info_t *)base_alloc(nhbins *
/* Initialize tcache_bin_info. */ sizeof(tcache_bin_info_t));
tcache_bin_info = (tcache_bin_info_t *)base_alloc(nhbins * if (tcache_bin_info == NULL)
sizeof(tcache_bin_info_t)); return (true);
if (tcache_bin_info == NULL) stack_nelms = 0;
return (true); for (i = 0; i < NBINS; i++) {
stack_nelms = 0; if ((arena_bin_info[i].nregs << 1) <= TCACHE_NSLOTS_SMALL_MAX) {
for (i = 0; i < NBINS; i++) { tcache_bin_info[i].ncached_max =
if ((arena_bin_info[i].nregs << 1) <= (arena_bin_info[i].nregs << 1);
TCACHE_NSLOTS_SMALL_MAX) { } else {
tcache_bin_info[i].ncached_max = tcache_bin_info[i].ncached_max =
(arena_bin_info[i].nregs << 1); TCACHE_NSLOTS_SMALL_MAX;
} else {
tcache_bin_info[i].ncached_max =
TCACHE_NSLOTS_SMALL_MAX;
}
stack_nelms += tcache_bin_info[i].ncached_max;
}
for (; i < nhbins; i++) {
tcache_bin_info[i].ncached_max = TCACHE_NSLOTS_LARGE;
stack_nelms += tcache_bin_info[i].ncached_max;
} }
stack_nelms += tcache_bin_info[i].ncached_max;
}
for (; i < nhbins; i++) {
tcache_bin_info[i].ncached_max = TCACHE_NSLOTS_LARGE;
stack_nelms += tcache_bin_info[i].ncached_max;
} }
return (false); return (false);
@ -430,10 +424,8 @@ bool
tcache_boot1(void) tcache_boot1(void)
{ {
if (opt_tcache) { if (tcache_tsd_boot() || tcache_enabled_tsd_boot())
if (tcache_tsd_boot() || tcache_enabled_tsd_boot()) return (true);
return (true);
}
return (false); return (false);
} }