Experimental calloc implementation with using memset on larger sizes

This commit is contained in:
Shirui Cheng 2024-04-03 13:27:11 -07:00 committed by Qi Wang
parent 38056fea64
commit 5081c16bb4
3 changed files with 34 additions and 7 deletions

View file

@ -37,6 +37,7 @@ extern const char *const zero_realloc_mode_names[];
extern atomic_zu_t zero_realloc_count;
extern bool opt_cache_oblivious;
extern unsigned opt_debug_double_free_max_scan;
extern size_t opt_calloc_madvise_threshold;
extern const char *opt_malloc_conf_symlink;
extern const char *opt_malloc_conf_env_var;

View file

@ -359,18 +359,39 @@ arena_extent_alloc_large(tsdn_t *tsdn, arena_t *arena, size_t usize,
bool guarded = san_large_extent_decide_guard(tsdn,
arena_get_ehooks(arena), esize, alignment);
edata_t *edata = pa_alloc(tsdn, &arena->pa_shard, esize, alignment,
/* slab */ false, szind, zero, guarded, &deferred_work_generated);
if (edata != NULL) {
if (config_stats) {
arena_large_malloc_stats_update(tsdn, arena, usize);
}
/*
* - if usize >= opt_calloc_madvise_threshold,
* - pa_alloc(..., zero_override = zero, ...)
* - otherwise,
* - pa_alloc(..., zero_override = false, ...)
* - use memset() to zero out memory if zero == true.
*/
bool zero_override = zero && (usize >= opt_calloc_madvise_threshold);
edata_t *edata = pa_alloc(tsdn, &arena->pa_shard, esize, alignment,
/* slab */ false, szind, zero_override, guarded,
&deferred_work_generated);
if (edata == NULL) {
return NULL;
}
if (edata != NULL && sz_large_pad != 0) {
if (config_stats) {
arena_large_malloc_stats_update(tsdn, arena, usize);
}
if (sz_large_pad != 0) {
arena_cache_oblivious_randomize(tsdn, arena, edata, alignment);
}
/*
* This branch should be put after the randomization so that the addr
* returned by edata_addr_get() has already be randomized,
* if cache_oblivious is enabled.
*/
if (zero && !zero_override && !edata_zeroed_get(edata)) {
void *addr = edata_addr_get(edata);
size_t usize = edata_usize_get(edata);
memset(addr, 0, usize);
}
return edata;
}

View file

@ -160,6 +160,8 @@ unsigned ncpus;
unsigned opt_debug_double_free_max_scan =
SAFETY_CHECK_DOUBLE_FREE_MAX_SCAN_DEFAULT;
size_t opt_calloc_madvise_threshold = 0;
/* Protects arenas initialization. */
static malloc_mutex_t arenas_lock;
@ -1453,6 +1455,9 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
"debug_double_free_max_scan", 0, UINT_MAX,
CONF_DONT_CHECK_MIN, CONF_DONT_CHECK_MAX,
/* clip */ false)
CONF_HANDLE_SIZE_T(opt_calloc_madvise_threshold,
"calloc_madvise_threshold", 0, SC_LARGE_MAXCLASS,
CONF_DONT_CHECK_MIN, CONF_CHECK_MAX, /* clip */ false)
/*
* The runtime option of oversize_threshold remains