Remove ratio-based purging.

Make decay-based purging the default (and only) mode.

Remove associated mallctls:
- opt.purge
- opt.lg_dirty_mult
- arena.<i>.lg_dirty_mult
- arenas.lg_dirty_mult
- stats.arenas.<i>.lg_dirty_mult

This resolves #385.
This commit is contained in:
Jason Evans 2016-10-12 10:40:27 -07:00
parent b4b4a77848
commit 63b5657aa5
11 changed files with 38 additions and 485 deletions

View File

@ -374,17 +374,15 @@ stress_dir:
check_dir: check_unit_dir check_integration_dir check_dir: check_unit_dir check_integration_dir
check_unit: tests_unit check_unit_dir check_unit: tests_unit check_unit_dir
$(MALLOC_CONF)="purge:ratio" $(SHELL) $(objroot)test/test.sh $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%) $(SHELL) $(objroot)test/test.sh $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%)
$(MALLOC_CONF)="purge:decay" $(SHELL) $(objroot)test/test.sh $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%)
check_integration_prof: tests_integration check_integration_dir check_integration_prof: tests_integration check_integration_dir
ifeq ($(enable_prof), 1) ifeq ($(enable_prof), 1)
$(MALLOC_CONF)="prof:true" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(MALLOC_CONF)="prof:true" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)
$(MALLOC_CONF)="prof:true,prof_active:false" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(MALLOC_CONF)="prof:true,prof_active:false" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)
endif endif
check_integration_decay: tests_integration check_integration_dir check_integration_decay: tests_integration check_integration_dir
$(MALLOC_CONF)="purge:decay,decay_time:-1" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(MALLOC_CONF)="decay_time:-1" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)
$(MALLOC_CONF)="purge:decay,decay_time:0" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(MALLOC_CONF)="decay_time:0" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)
$(MALLOC_CONF)="purge:decay" $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)
check_integration: tests_integration check_integration_dir check_integration: tests_integration check_integration_dir
$(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%) $(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)
stress: tests_stress stress_dir stress: tests_stress stress_dir

View File

@ -924,42 +924,6 @@ for (i = 0; i < nbins; i++) {
number of CPUs, or one if there is a single CPU.</para></listitem> number of CPUs, or one if there is a single CPU.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry id="opt.purge">
<term>
<mallctl>opt.purge</mallctl>
(<type>const char *</type>)
<literal>r-</literal>
</term>
<listitem><para>Purge mode is &ldquo;ratio&rdquo; (default) or
&ldquo;decay&rdquo;. See <link
linkend="opt.lg_dirty_mult"><mallctl>opt.lg_dirty_mult</mallctl></link>
for details of the ratio mode. See <link
linkend="opt.decay_time"><mallctl>opt.decay_time</mallctl></link> for
details of the decay mode.</para></listitem>
</varlistentry>
<varlistentry id="opt.lg_dirty_mult">
<term>
<mallctl>opt.lg_dirty_mult</mallctl>
(<type>ssize_t</type>)
<literal>r-</literal>
</term>
<listitem><para>Per-arena minimum ratio (log base 2) of active to dirty
pages. Some dirty unused pages may be allowed to accumulate, within
the limit set by the ratio (or one chunk worth of dirty pages,
whichever is greater), before informing the kernel about some of those
pages via <citerefentry><refentrytitle>madvise</refentrytitle>
<manvolnum>2</manvolnum></citerefentry> or a similar system call. This
provides the kernel with sufficient information to recycle dirty pages
if physical memory becomes scarce and the pages remain unused. The
default minimum ratio is 8:1 (2^3:1); an option value of -1 will
disable dirty page purging. See <link
linkend="arenas.lg_dirty_mult"><mallctl>arenas.lg_dirty_mult</mallctl></link>
and <link
linkend="arena.i.lg_dirty_mult"><mallctl>arena.&lt;i&gt;.lg_dirty_mult</mallctl></link>
for related dynamic control options.</para></listitem>
</varlistentry>
<varlistentry id="opt.decay_time"> <varlistentry id="opt.decay_time">
<term> <term>
<mallctl>opt.decay_time</mallctl> <mallctl>opt.decay_time</mallctl>
@ -1518,20 +1482,6 @@ malloc_conf = "xmalloc:true";]]></programlisting>
settings.</para></listitem> settings.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry id="arena.i.lg_dirty_mult">
<term>
<mallctl>arena.&lt;i&gt;.lg_dirty_mult</mallctl>
(<type>ssize_t</type>)
<literal>rw</literal>
</term>
<listitem><para>Current per-arena minimum ratio (log base 2) of active
to dirty pages for arena &lt;i&gt;. Each time this interface is set and
the ratio is increased, pages are synchronously purged as necessary to
impose the new ratio. See <link
linkend="opt.lg_dirty_mult"><mallctl>opt.lg_dirty_mult</mallctl></link>
for additional information.</para></listitem>
</varlistentry>
<varlistentry id="arena.i.decay_time"> <varlistentry id="arena.i.decay_time">
<term> <term>
<mallctl>arena.&lt;i&gt;.decay_time</mallctl> <mallctl>arena.&lt;i&gt;.decay_time</mallctl>
@ -1778,20 +1728,6 @@ struct extent_hooks_s {
initialized.</para></listitem> initialized.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry id="arenas.lg_dirty_mult">
<term>
<mallctl>arenas.lg_dirty_mult</mallctl>
(<type>ssize_t</type>)
<literal>rw</literal>
</term>
<listitem><para>Current default per-arena minimum ratio (log base 2) of
active to dirty pages, used to initialize <link
linkend="arena.i.lg_dirty_mult"><mallctl>arena.&lt;i&gt;.lg_dirty_mult</mallctl></link>
during arena creation. See <link
linkend="opt.lg_dirty_mult"><mallctl>opt.lg_dirty_mult</mallctl></link>
for additional information.</para></listitem>
</varlistentry>
<varlistentry id="arenas.decay_time"> <varlistentry id="arenas.decay_time">
<term> <term>
<mallctl>arenas.decay_time</mallctl> <mallctl>arenas.decay_time</mallctl>
@ -2137,18 +2073,6 @@ struct extent_hooks_s {
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry id="stats.arenas.i.lg_dirty_mult">
<term>
<mallctl>stats.arenas.&lt;i&gt;.lg_dirty_mult</mallctl>
(<type>ssize_t</type>)
<literal>r-</literal>
</term>
<listitem><para>Minimum ratio (log base 2) of active to dirty pages.
See <link
linkend="opt.lg_dirty_mult"><mallctl>opt.lg_dirty_mult</mallctl></link>
for details.</para></listitem>
</varlistentry>
<varlistentry id="stats.arenas.i.decay_time"> <varlistentry id="stats.arenas.i.decay_time">
<term> <term>
<mallctl>stats.arenas.&lt;i&gt;.decay_time</mallctl> <mallctl>stats.arenas.&lt;i&gt;.decay_time</mallctl>

View File

@ -7,23 +7,6 @@
#define LG_SLAB_MAXREGS (LG_PAGE - LG_TINY_MIN) #define LG_SLAB_MAXREGS (LG_PAGE - LG_TINY_MIN)
#define SLAB_MAXREGS (1U << LG_SLAB_MAXREGS) #define SLAB_MAXREGS (1U << LG_SLAB_MAXREGS)
/*
* The minimum ratio of active:dirty pages per arena is computed as:
*
* (nactive >> lg_dirty_mult) >= ndirty
*
* So, supposing that lg_dirty_mult is 3, there can be no less than 8 times as
* many active pages as dirty pages.
*/
#define LG_DIRTY_MULT_DEFAULT 3
typedef enum {
purge_mode_ratio = 0,
purge_mode_decay = 1,
purge_mode_limit = 2
} purge_mode_t;
#define PURGE_DEFAULT purge_mode_ratio
/* Default decay time in seconds. */ /* Default decay time in seconds. */
#define DECAY_TIME_DEFAULT 10 #define DECAY_TIME_DEFAULT 10
/* Number of event ticks between time checks. */ /* Number of event ticks between time checks. */
@ -203,9 +186,6 @@ struct arena_s {
dss_prec_t dss_prec; dss_prec_t dss_prec;
/* Minimum ratio (log base 2) of nactive:ndirty. */
ssize_t lg_dirty_mult;
/* True if a thread is currently executing arena_purge_to_limit(). */ /* True if a thread is currently executing arena_purge_to_limit(). */
bool purging; bool purging;
@ -274,9 +254,6 @@ static const size_t large_pad =
#endif #endif
; ;
extern purge_mode_t opt_purge;
extern const char *purge_mode_names[];
extern ssize_t opt_lg_dirty_mult;
extern ssize_t opt_decay_time; extern ssize_t opt_decay_time;
extern const arena_bin_info_t arena_bin_info[NBINS]; extern const arena_bin_info_t arena_bin_info[NBINS];
@ -298,9 +275,6 @@ void arena_extent_ralloc_large_shrink(tsdn_t *tsdn, arena_t *arena,
extent_t *extent, size_t oldsize); extent_t *extent, size_t oldsize);
void arena_extent_ralloc_large_expand(tsdn_t *tsdn, arena_t *arena, void arena_extent_ralloc_large_expand(tsdn_t *tsdn, arena_t *arena,
extent_t *extent, size_t oldsize); extent_t *extent, size_t oldsize);
ssize_t arena_lg_dirty_mult_get(tsdn_t *tsdn, arena_t *arena);
bool arena_lg_dirty_mult_set(tsdn_t *tsdn, arena_t *arena,
ssize_t lg_dirty_mult);
ssize_t arena_decay_time_get(tsdn_t *tsdn, arena_t *arena); ssize_t arena_decay_time_get(tsdn_t *tsdn, arena_t *arena);
bool arena_decay_time_set(tsdn_t *tsdn, arena_t *arena, ssize_t decay_time); bool arena_decay_time_set(tsdn_t *tsdn, arena_t *arena, ssize_t decay_time);
void arena_purge(tsdn_t *tsdn, arena_t *arena, bool all); void arena_purge(tsdn_t *tsdn, arena_t *arena, bool all);
@ -334,17 +308,15 @@ void *arena_ralloc(tsdn_t *tsdn, arena_t *arena, extent_t *extent, void *ptr,
size_t oldsize, size_t size, size_t alignment, bool zero, tcache_t *tcache); size_t oldsize, size_t size, size_t alignment, bool zero, tcache_t *tcache);
dss_prec_t arena_dss_prec_get(tsdn_t *tsdn, arena_t *arena); dss_prec_t arena_dss_prec_get(tsdn_t *tsdn, arena_t *arena);
bool arena_dss_prec_set(tsdn_t *tsdn, arena_t *arena, dss_prec_t dss_prec); bool arena_dss_prec_set(tsdn_t *tsdn, arena_t *arena, dss_prec_t dss_prec);
ssize_t arena_lg_dirty_mult_default_get(void);
bool arena_lg_dirty_mult_default_set(ssize_t lg_dirty_mult);
ssize_t arena_decay_time_default_get(void); ssize_t arena_decay_time_default_get(void);
bool arena_decay_time_default_set(ssize_t decay_time); bool arena_decay_time_default_set(ssize_t decay_time);
void arena_basic_stats_merge(tsdn_t *tsdn, arena_t *arena, void arena_basic_stats_merge(tsdn_t *tsdn, arena_t *arena,
unsigned *nthreads, const char **dss, ssize_t *lg_dirty_mult, unsigned *nthreads, const char **dss, ssize_t *decay_time, size_t *nactive,
ssize_t *decay_time, size_t *nactive, size_t *ndirty); size_t *ndirty);
void arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads, void arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time, const char **dss, ssize_t *decay_time, size_t *nactive, size_t *ndirty,
size_t *nactive, size_t *ndirty, arena_stats_t *astats, arena_stats_t *astats, malloc_bin_stats_t *bstats,
malloc_bin_stats_t *bstats, malloc_large_stats_t *lstats); malloc_large_stats_t *lstats);
unsigned arena_nthreads_get(arena_t *arena, bool internal); unsigned arena_nthreads_get(arena_t *arena, bool internal);
void arena_nthreads_inc(arena_t *arena, bool internal); void arena_nthreads_inc(arena_t *arena, bool internal);
void arena_nthreads_dec(arena_t *arena, bool internal); void arena_nthreads_dec(arena_t *arena, bool internal);

View File

@ -35,7 +35,6 @@ struct ctl_arena_stats_s {
bool initialized; bool initialized;
unsigned nthreads; unsigned nthreads;
const char *dss; const char *dss;
ssize_t lg_dirty_mult;
ssize_t decay_time; ssize_t decay_time;
size_t pactive; size_t pactive;
size_t pdirty; size_t pdirty;

View File

@ -34,10 +34,6 @@ arena_extent_ralloc_large_shrink
arena_get arena_get
arena_ichoose arena_ichoose
arena_init arena_init
arena_lg_dirty_mult_default_get
arena_lg_dirty_mult_default_set
arena_lg_dirty_mult_get
arena_lg_dirty_mult_set
arena_malloc arena_malloc
arena_malloc_hard arena_malloc_hard
arena_maybe_purge arena_maybe_purge
@ -311,7 +307,6 @@ opt_junk
opt_junk_alloc opt_junk_alloc
opt_junk_free opt_junk_free
opt_lg_chunk opt_lg_chunk
opt_lg_dirty_mult
opt_lg_prof_interval opt_lg_prof_interval
opt_lg_prof_sample opt_lg_prof_sample
opt_lg_tcache_max opt_lg_tcache_max
@ -324,7 +319,6 @@ opt_prof_gdump
opt_prof_leak opt_prof_leak
opt_prof_prefix opt_prof_prefix
opt_prof_thread_active_init opt_prof_thread_active_init
opt_purge
opt_stats_print opt_stats_print
opt_tcache opt_tcache
opt_utrace opt_utrace
@ -399,7 +393,6 @@ psz2ind
psz2ind_clamp psz2ind_clamp
psz2ind_impl psz2ind_impl
psz2u psz2u
purge_mode_names
register_zone register_zone
rtree_child_read rtree_child_read
rtree_child_read_hard rtree_child_read_hard

View File

@ -4,14 +4,6 @@
/******************************************************************************/ /******************************************************************************/
/* Data. */ /* Data. */
purge_mode_t opt_purge = PURGE_DEFAULT;
const char *purge_mode_names[] = {
"ratio",
"decay",
"N/A"
};
ssize_t opt_lg_dirty_mult = LG_DIRTY_MULT_DEFAULT;
static ssize_t lg_dirty_mult_default;
ssize_t opt_decay_time = DECAY_TIME_DEFAULT; ssize_t opt_decay_time = DECAY_TIME_DEFAULT;
static ssize_t decay_time_default; static ssize_t decay_time_default;
@ -429,47 +421,10 @@ arena_extent_ralloc_large_expand(tsdn_t *tsdn, arena_t *arena, extent_t *extent,
malloc_mutex_unlock(tsdn, &arena->lock); malloc_mutex_unlock(tsdn, &arena->lock);
} }
static bool
arena_lg_dirty_mult_valid(ssize_t lg_dirty_mult)
{
return (lg_dirty_mult >= -1 && lg_dirty_mult < (ssize_t)(sizeof(size_t)
<< 3));
}
ssize_t
arena_lg_dirty_mult_get(tsdn_t *tsdn, arena_t *arena)
{
ssize_t lg_dirty_mult;
malloc_mutex_lock(tsdn, &arena->lock);
lg_dirty_mult = arena->lg_dirty_mult;
malloc_mutex_unlock(tsdn, &arena->lock);
return (lg_dirty_mult);
}
bool
arena_lg_dirty_mult_set(tsdn_t *tsdn, arena_t *arena, ssize_t lg_dirty_mult)
{
if (!arena_lg_dirty_mult_valid(lg_dirty_mult))
return (true);
malloc_mutex_lock(tsdn, &arena->lock);
arena->lg_dirty_mult = lg_dirty_mult;
arena_maybe_purge(tsdn, arena);
malloc_mutex_unlock(tsdn, &arena->lock);
return (false);
}
static void static void
arena_decay_deadline_init(arena_t *arena) arena_decay_deadline_init(arena_t *arena)
{ {
assert(opt_purge == purge_mode_decay);
/* /*
* Generate a new deadline that is uniformly random within the next * Generate a new deadline that is uniformly random within the next
* epoch after the current one. * epoch after the current one.
@ -489,8 +444,6 @@ static bool
arena_decay_deadline_reached(const arena_t *arena, const nstime_t *time) arena_decay_deadline_reached(const arena_t *arena, const nstime_t *time)
{ {
assert(opt_purge == purge_mode_decay);
return (nstime_compare(&arena->decay.deadline, time) <= 0); return (nstime_compare(&arena->decay.deadline, time) <= 0);
} }
@ -507,8 +460,6 @@ arena_decay_backlog_npages_limit(const arena_t *arena)
size_t npages_limit_backlog; size_t npages_limit_backlog;
unsigned i; unsigned i;
assert(opt_purge == purge_mode_decay);
/* /*
* For each element of decay_backlog, multiply by the corresponding * For each element of decay_backlog, multiply by the corresponding
* fixed-point smoothstep decay factor. Sum the products, then divide * fixed-point smoothstep decay factor. Sum the products, then divide
@ -559,7 +510,6 @@ arena_decay_epoch_advance_helper(arena_t *arena, const nstime_t *time)
uint64_t nadvance_u64; uint64_t nadvance_u64;
nstime_t delta; nstime_t delta;
assert(opt_purge == purge_mode_decay);
assert(arena_decay_deadline_reached(arena, time)); assert(arena_decay_deadline_reached(arena, time));
nstime_copy(&delta, time); nstime_copy(&delta, time);
@ -662,40 +612,10 @@ arena_decay_time_set(tsdn_t *tsdn, arena_t *arena, ssize_t decay_time)
} }
static void static void
arena_maybe_purge_ratio(tsdn_t *tsdn, arena_t *arena) arena_maybe_purge_helper(tsdn_t *tsdn, arena_t *arena)
{
assert(opt_purge == purge_mode_ratio);
/* Don't purge if the option is disabled. */
if (arena->lg_dirty_mult < 0)
return;
/*
* Iterate, since preventing recursive purging could otherwise leave too
* many dirty pages.
*/
while (true) {
size_t threshold = (arena->nactive >> arena->lg_dirty_mult);
if (threshold < chunk_npages)
threshold = chunk_npages;
/*
* Don't purge unless the number of purgeable pages exceeds the
* threshold.
*/
if (arena->ndirty <= threshold)
return;
arena_purge_to_limit(tsdn, arena, threshold);
}
}
static void
arena_maybe_purge_decay(tsdn_t *tsdn, arena_t *arena)
{ {
nstime_t time; nstime_t time;
assert(opt_purge == purge_mode_decay);
/* Purge all or nothing if the option is disabled. */ /* Purge all or nothing if the option is disabled. */
if (arena->decay.time <= 0) { if (arena->decay.time <= 0) {
if (arena->decay.time == 0) if (arena->decay.time == 0)
@ -743,10 +663,7 @@ arena_maybe_purge(tsdn_t *tsdn, arena_t *arena)
if (arena->purging) if (arena->purging)
return; return;
if (opt_purge == purge_mode_ratio) arena_maybe_purge_helper(tsdn, arena);
arena_maybe_purge_ratio(tsdn, arena);
else
arena_maybe_purge_decay(tsdn, arena);
} }
static size_t static size_t
@ -781,8 +698,7 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
UNUSED extent_t *textent; UNUSED extent_t *textent;
npages = extent_size_get(extent) >> LG_PAGE; npages = extent_size_get(extent) >> LG_PAGE;
if (opt_purge == purge_mode_decay && arena->ndirty - (nstashed + if (arena->ndirty - (nstashed + npages) < ndirty_limit)
npages) < ndirty_limit)
break; break;
next = qr_next(extent, qr_link); next = qr_next(extent, qr_link);
@ -797,9 +713,6 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
extent_ring_insert(purge_extents_sentinel, extent); extent_ring_insert(purge_extents_sentinel, extent);
nstashed += npages; nstashed += npages;
if (opt_purge == purge_mode_ratio && arena->ndirty - nstashed <=
ndirty_limit)
break;
} }
malloc_mutex_unlock(tsdn, &arena->extents_mtx); malloc_mutex_unlock(tsdn, &arena->extents_mtx);
@ -838,13 +751,8 @@ arena_purge_stashed(tsdn_t *tsdn, arena_t *arena,
} }
/* /*
* NB: ndirty_limit is interpreted differently depending on opt_purge: * ndirty_limit: Purge as many dirty extents as possible without violating the
* - purge_mode_ratio: Purge as few dirty extents as possible to reach the * invariant: (arena->ndirty >= ndirty_limit)
* desired state:
* (arena->ndirty <= ndirty_limit)
* - purge_mode_decay: Purge as many dirty extents as possible without
* violating the invariant:
* (arena->ndirty >= ndirty_limit)
*/ */
static void static void
arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena, size_t ndirty_limit) arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena, size_t ndirty_limit)
@ -863,9 +771,6 @@ arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena, size_t ndirty_limit)
size_t ndirty = arena_dirty_count(tsdn, arena); size_t ndirty = arena_dirty_count(tsdn, arena);
assert(ndirty == arena->ndirty); assert(ndirty == arena->ndirty);
} }
assert(opt_purge != purge_mode_ratio || (arena->nactive >>
arena->lg_dirty_mult) < arena->ndirty || ndirty_limit == 0);
extent_init(&purge_extents_sentinel, arena, NULL, 0, 0, false, false, extent_init(&purge_extents_sentinel, arena, NULL, 0, 0, false, false,
false, false); false, false);
@ -1644,25 +1549,6 @@ arena_dss_prec_set(tsdn_t *tsdn, arena_t *arena, dss_prec_t dss_prec)
return (false); return (false);
} }
ssize_t
arena_lg_dirty_mult_default_get(void)
{
return ((ssize_t)atomic_read_z((size_t *)&lg_dirty_mult_default));
}
bool
arena_lg_dirty_mult_default_set(ssize_t lg_dirty_mult)
{
if (opt_purge != purge_mode_ratio)
return (true);
if (!arena_lg_dirty_mult_valid(lg_dirty_mult))
return (true);
atomic_write_z((size_t *)&lg_dirty_mult_default, (size_t)lg_dirty_mult);
return (false);
}
ssize_t ssize_t
arena_decay_time_default_get(void) arena_decay_time_default_get(void)
{ {
@ -1674,8 +1560,6 @@ bool
arena_decay_time_default_set(ssize_t decay_time) arena_decay_time_default_set(ssize_t decay_time)
{ {
if (opt_purge != purge_mode_decay)
return (true);
if (!arena_decay_time_valid(decay_time)) if (!arena_decay_time_valid(decay_time))
return (true); return (true);
atomic_write_z((size_t *)&decay_time_default, (size_t)decay_time); atomic_write_z((size_t *)&decay_time_default, (size_t)decay_time);
@ -1684,13 +1568,11 @@ arena_decay_time_default_set(ssize_t decay_time)
static void static void
arena_basic_stats_merge_locked(arena_t *arena, unsigned *nthreads, arena_basic_stats_merge_locked(arena_t *arena, unsigned *nthreads,
const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time, const char **dss, ssize_t *decay_time, size_t *nactive, size_t *ndirty)
size_t *nactive, size_t *ndirty)
{ {
*nthreads += arena_nthreads_get(arena, false); *nthreads += arena_nthreads_get(arena, false);
*dss = dss_prec_names[arena->dss_prec]; *dss = dss_prec_names[arena->dss_prec];
*lg_dirty_mult = arena->lg_dirty_mult;
*decay_time = arena->decay.time; *decay_time = arena->decay.time;
*nactive += arena->nactive; *nactive += arena->nactive;
*ndirty += arena->ndirty; *ndirty += arena->ndirty;
@ -1698,29 +1580,28 @@ arena_basic_stats_merge_locked(arena_t *arena, unsigned *nthreads,
void void
arena_basic_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads, arena_basic_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time, const char **dss, ssize_t *decay_time, size_t *nactive, size_t *ndirty)
size_t *nactive, size_t *ndirty)
{ {
malloc_mutex_lock(tsdn, &arena->lock); malloc_mutex_lock(tsdn, &arena->lock);
arena_basic_stats_merge_locked(arena, nthreads, dss, lg_dirty_mult, arena_basic_stats_merge_locked(arena, nthreads, dss, decay_time,
decay_time, nactive, ndirty); nactive, ndirty);
malloc_mutex_unlock(tsdn, &arena->lock); malloc_mutex_unlock(tsdn, &arena->lock);
} }
void void
arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads, arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time, const char **dss, ssize_t *decay_time, size_t *nactive, size_t *ndirty,
size_t *nactive, size_t *ndirty, arena_stats_t *astats, arena_stats_t *astats, malloc_bin_stats_t *bstats,
malloc_bin_stats_t *bstats, malloc_large_stats_t *lstats) malloc_large_stats_t *lstats)
{ {
unsigned i; unsigned i;
cassert(config_stats); cassert(config_stats);
malloc_mutex_lock(tsdn, &arena->lock); malloc_mutex_lock(tsdn, &arena->lock);
arena_basic_stats_merge_locked(arena, nthreads, dss, lg_dirty_mult, arena_basic_stats_merge_locked(arena, nthreads, dss, decay_time,
decay_time, nactive, ndirty); nactive, ndirty);
astats->mapped += arena->stats.mapped; astats->mapped += arena->stats.mapped;
astats->retained += arena->stats.retained; astats->retained += arena->stats.retained;
@ -1816,12 +1697,10 @@ arena_new(tsdn_t *tsdn, unsigned ind)
arena->dss_prec = extent_dss_prec_get(tsdn); arena->dss_prec = extent_dss_prec_get(tsdn);
arena->lg_dirty_mult = arena_lg_dirty_mult_default_get();
arena->purging = false; arena->purging = false;
arena->nactive = 0; arena->nactive = 0;
arena->ndirty = 0; arena->ndirty = 0;
if (opt_purge == purge_mode_decay)
arena_decay_init(arena, arena_decay_time_default_get()); arena_decay_init(arena, arena_decay_time_default_get());
ql_new(&arena->large); ql_new(&arena->large);
@ -1869,7 +1748,6 @@ void
arena_boot(void) arena_boot(void)
{ {
arena_lg_dirty_mult_default_set(opt_lg_dirty_mult);
arena_decay_time_default_set(opt_decay_time); arena_decay_time_default_set(opt_decay_time);
} }

View File

@ -90,8 +90,6 @@ CTL_PROTO(opt_abort)
CTL_PROTO(opt_dss) CTL_PROTO(opt_dss)
CTL_PROTO(opt_lg_chunk) CTL_PROTO(opt_lg_chunk)
CTL_PROTO(opt_narenas) CTL_PROTO(opt_narenas)
CTL_PROTO(opt_purge)
CTL_PROTO(opt_lg_dirty_mult)
CTL_PROTO(opt_decay_time) CTL_PROTO(opt_decay_time)
CTL_PROTO(opt_stats_print) CTL_PROTO(opt_stats_print)
CTL_PROTO(opt_junk) CTL_PROTO(opt_junk)
@ -118,7 +116,6 @@ CTL_PROTO(arena_i_purge)
CTL_PROTO(arena_i_decay) CTL_PROTO(arena_i_decay)
CTL_PROTO(arena_i_reset) CTL_PROTO(arena_i_reset)
CTL_PROTO(arena_i_dss) CTL_PROTO(arena_i_dss)
CTL_PROTO(arena_i_lg_dirty_mult)
CTL_PROTO(arena_i_decay_time) CTL_PROTO(arena_i_decay_time)
CTL_PROTO(arena_i_extent_hooks) CTL_PROTO(arena_i_extent_hooks)
INDEX_PROTO(arena_i) INDEX_PROTO(arena_i)
@ -130,7 +127,6 @@ CTL_PROTO(arenas_lextent_i_size)
INDEX_PROTO(arenas_lextent_i) INDEX_PROTO(arenas_lextent_i)
CTL_PROTO(arenas_narenas) CTL_PROTO(arenas_narenas)
CTL_PROTO(arenas_initialized) CTL_PROTO(arenas_initialized)
CTL_PROTO(arenas_lg_dirty_mult)
CTL_PROTO(arenas_decay_time) CTL_PROTO(arenas_decay_time)
CTL_PROTO(arenas_quantum) CTL_PROTO(arenas_quantum)
CTL_PROTO(arenas_page) CTL_PROTO(arenas_page)
@ -171,7 +167,6 @@ CTL_PROTO(stats_arenas_i_lextents_j_curlextents)
INDEX_PROTO(stats_arenas_i_lextents_j) INDEX_PROTO(stats_arenas_i_lextents_j)
CTL_PROTO(stats_arenas_i_nthreads) CTL_PROTO(stats_arenas_i_nthreads)
CTL_PROTO(stats_arenas_i_dss) CTL_PROTO(stats_arenas_i_dss)
CTL_PROTO(stats_arenas_i_lg_dirty_mult)
CTL_PROTO(stats_arenas_i_decay_time) CTL_PROTO(stats_arenas_i_decay_time)
CTL_PROTO(stats_arenas_i_pactive) CTL_PROTO(stats_arenas_i_pactive)
CTL_PROTO(stats_arenas_i_pdirty) CTL_PROTO(stats_arenas_i_pdirty)
@ -251,8 +246,6 @@ static const ctl_named_node_t opt_node[] = {
{NAME("dss"), CTL(opt_dss)}, {NAME("dss"), CTL(opt_dss)},
{NAME("lg_chunk"), CTL(opt_lg_chunk)}, {NAME("lg_chunk"), CTL(opt_lg_chunk)},
{NAME("narenas"), CTL(opt_narenas)}, {NAME("narenas"), CTL(opt_narenas)},
{NAME("purge"), CTL(opt_purge)},
{NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)},
{NAME("decay_time"), CTL(opt_decay_time)}, {NAME("decay_time"), CTL(opt_decay_time)},
{NAME("stats_print"), CTL(opt_stats_print)}, {NAME("stats_print"), CTL(opt_stats_print)},
{NAME("junk"), CTL(opt_junk)}, {NAME("junk"), CTL(opt_junk)},
@ -284,7 +277,6 @@ static const ctl_named_node_t arena_i_node[] = {
{NAME("decay"), CTL(arena_i_decay)}, {NAME("decay"), CTL(arena_i_decay)},
{NAME("reset"), CTL(arena_i_reset)}, {NAME("reset"), CTL(arena_i_reset)},
{NAME("dss"), CTL(arena_i_dss)}, {NAME("dss"), CTL(arena_i_dss)},
{NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)},
{NAME("decay_time"), CTL(arena_i_decay_time)}, {NAME("decay_time"), CTL(arena_i_decay_time)},
{NAME("extent_hooks"), CTL(arena_i_extent_hooks)} {NAME("extent_hooks"), CTL(arena_i_extent_hooks)}
}; };
@ -323,7 +315,6 @@ static const ctl_indexed_node_t arenas_lextent_node[] = {
static const ctl_named_node_t arenas_node[] = { static const ctl_named_node_t arenas_node[] = {
{NAME("narenas"), CTL(arenas_narenas)}, {NAME("narenas"), CTL(arenas_narenas)},
{NAME("initialized"), CTL(arenas_initialized)}, {NAME("initialized"), CTL(arenas_initialized)},
{NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)},
{NAME("decay_time"), CTL(arenas_decay_time)}, {NAME("decay_time"), CTL(arenas_decay_time)},
{NAME("quantum"), CTL(arenas_quantum)}, {NAME("quantum"), CTL(arenas_quantum)},
{NAME("page"), CTL(arenas_page)}, {NAME("page"), CTL(arenas_page)},
@ -396,7 +387,6 @@ static const ctl_indexed_node_t stats_arenas_i_lextents_node[] = {
static const ctl_named_node_t stats_arenas_i_node[] = { static const ctl_named_node_t stats_arenas_i_node[] = {
{NAME("nthreads"), CTL(stats_arenas_i_nthreads)}, {NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
{NAME("dss"), CTL(stats_arenas_i_dss)}, {NAME("dss"), CTL(stats_arenas_i_dss)},
{NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)},
{NAME("decay_time"), CTL(stats_arenas_i_decay_time)}, {NAME("decay_time"), CTL(stats_arenas_i_decay_time)},
{NAME("pactive"), CTL(stats_arenas_i_pactive)}, {NAME("pactive"), CTL(stats_arenas_i_pactive)},
{NAME("pdirty"), CTL(stats_arenas_i_pdirty)}, {NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
@ -459,7 +449,6 @@ ctl_arena_clear(ctl_arena_stats_t *astats)
astats->nthreads = 0; astats->nthreads = 0;
astats->dss = dss_prec_names[dss_prec_limit]; astats->dss = dss_prec_names[dss_prec_limit];
astats->lg_dirty_mult = -1;
astats->decay_time = -1; astats->decay_time = -1;
astats->pactive = 0; astats->pactive = 0;
astats->pdirty = 0; astats->pdirty = 0;
@ -482,9 +471,8 @@ ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena)
if (config_stats) { if (config_stats) {
arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss, arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss,
&cstats->lg_dirty_mult, &cstats->decay_time, &cstats->decay_time, &cstats->pactive, &cstats->pdirty,
&cstats->pactive, &cstats->pdirty, &cstats->astats, &cstats->astats, cstats->bstats, cstats->lstats);
cstats->bstats, cstats->lstats);
for (i = 0; i < NBINS; i++) { for (i = 0; i < NBINS; i++) {
cstats->allocated_small += cstats->bstats[i].curregs * cstats->allocated_small += cstats->bstats[i].curregs *
@ -495,8 +483,8 @@ ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena)
} }
} else { } else {
arena_basic_stats_merge(tsdn, arena, &cstats->nthreads, arena_basic_stats_merge(tsdn, arena, &cstats->nthreads,
&cstats->dss, &cstats->lg_dirty_mult, &cstats->decay_time, &cstats->dss, &cstats->decay_time, &cstats->pactive,
&cstats->pactive, &cstats->pdirty); &cstats->pdirty);
} }
} }
@ -1150,8 +1138,6 @@ CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
CTL_RO_NL_GEN(opt_dss, opt_dss, const char *) CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t)
CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned) CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned)
CTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *)
CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t) CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t)
CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *) CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
@ -1562,41 +1548,6 @@ label_return:
return (ret); return (ret);
} }
static int
arena_i_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen)
{
int ret;
unsigned arena_ind = (unsigned)mib[1];
arena_t *arena;
arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
if (arena == NULL) {
ret = EFAULT;
goto label_return;
}
if (oldp != NULL && oldlenp != NULL) {
size_t oldval = arena_lg_dirty_mult_get(tsd_tsdn(tsd), arena);
READ(oldval, ssize_t);
}
if (newp != NULL) {
if (newlen != sizeof(ssize_t)) {
ret = EINVAL;
goto label_return;
}
if (arena_lg_dirty_mult_set(tsd_tsdn(tsd), arena,
*(ssize_t *)newp)) {
ret = EFAULT;
goto label_return;
}
}
ret = 0;
label_return:
return (ret);
}
static int static int
arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
size_t *oldlenp, void *newp, size_t newlen) size_t *oldlenp, void *newp, size_t newlen)
@ -1733,32 +1684,6 @@ label_return:
return (ret); return (ret);
} }
static int
arenas_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen)
{
int ret;
if (oldp != NULL && oldlenp != NULL) {
size_t oldval = arena_lg_dirty_mult_default_get();
READ(oldval, ssize_t);
}
if (newp != NULL) {
if (newlen != sizeof(ssize_t)) {
ret = EINVAL;
goto label_return;
}
if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) {
ret = EFAULT;
goto label_return;
}
}
ret = 0;
label_return:
return (ret);
}
static int static int
arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
size_t *oldlenp, void *newp, size_t newlen) size_t *oldlenp, void *newp, size_t newlen)
@ -1972,8 +1897,6 @@ CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t)
CTL_RO_CGEN(config_stats, stats_retained, ctl_stats.retained, size_t) CTL_RO_CGEN(config_stats, stats_retained, ctl_stats.retained, size_t)
CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *) CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *)
CTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult,
ssize_t)
CTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time, CTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time,
ssize_t) ssize_t)
CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned) CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned)

View File

@ -1053,25 +1053,6 @@ malloc_conf_init(void)
} }
CONF_HANDLE_UNSIGNED(opt_narenas, "narenas", 1, CONF_HANDLE_UNSIGNED(opt_narenas, "narenas", 1,
UINT_MAX, false) UINT_MAX, false)
if (strncmp("purge", k, klen) == 0) {
int i;
bool match = false;
for (i = 0; i < purge_mode_limit; i++) {
if (strncmp(purge_mode_names[i], v,
vlen) == 0) {
opt_purge = (purge_mode_t)i;
match = true;
break;
}
}
if (!match) {
malloc_conf_error("Invalid conf value",
k, klen, v, vlen);
}
continue;
}
CONF_HANDLE_SSIZE_T(opt_lg_dirty_mult, "lg_dirty_mult",
-1, (sizeof(size_t) << 3) - 1)
CONF_HANDLE_SSIZE_T(opt_decay_time, "decay_time", -1, CONF_HANDLE_SSIZE_T(opt_decay_time, "decay_time", -1,
NSTIME_SEC_MAX); NSTIME_SEC_MAX);
CONF_HANDLE_BOOL(opt_stats_print, "stats_print", true) CONF_HANDLE_BOOL(opt_stats_print, "stats_print", true)

View File

@ -210,7 +210,7 @@ stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,
{ {
unsigned nthreads; unsigned nthreads;
const char *dss; const char *dss;
ssize_t lg_dirty_mult, decay_time; ssize_t decay_time;
size_t page, pactive, pdirty, mapped, retained, metadata; size_t page, pactive, pdirty, mapped, retained, metadata;
uint64_t npurge, nmadvise, purged; uint64_t npurge, nmadvise, purged;
size_t small_allocated; size_t small_allocated;
@ -226,25 +226,12 @@ stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,
CTL_M2_GET("stats.arenas.0.dss", i, &dss, const char *); CTL_M2_GET("stats.arenas.0.dss", i, &dss, const char *);
malloc_cprintf(write_cb, cbopaque, "dss allocation precedence: %s\n", malloc_cprintf(write_cb, cbopaque, "dss allocation precedence: %s\n",
dss); dss);
CTL_M2_GET("stats.arenas.0.lg_dirty_mult", i, &lg_dirty_mult, ssize_t);
if (opt_purge == purge_mode_ratio) {
if (lg_dirty_mult >= 0) {
malloc_cprintf(write_cb, cbopaque,
"min active:dirty page ratio: %u:1\n",
(1U << lg_dirty_mult));
} else {
malloc_cprintf(write_cb, cbopaque,
"min active:dirty page ratio: N/A\n");
}
}
CTL_M2_GET("stats.arenas.0.decay_time", i, &decay_time, ssize_t); CTL_M2_GET("stats.arenas.0.decay_time", i, &decay_time, ssize_t);
if (opt_purge == purge_mode_decay) {
if (decay_time >= 0) { if (decay_time >= 0) {
malloc_cprintf(write_cb, cbopaque, "decay time: %zd\n", malloc_cprintf(write_cb, cbopaque, "decay time: %zd\n",
decay_time); decay_time);
} else } else
malloc_cprintf(write_cb, cbopaque, "decay time: N/A\n"); malloc_cprintf(write_cb, cbopaque, "decay time: N/A\n");
}
CTL_M2_GET("stats.arenas.0.pactive", i, &pactive, size_t); CTL_M2_GET("stats.arenas.0.pactive", i, &pactive, size_t);
CTL_M2_GET("stats.arenas.0.pdirty", i, &pdirty, size_t); CTL_M2_GET("stats.arenas.0.pdirty", i, &pdirty, size_t);
CTL_M2_GET("stats.arenas.0.npurge", i, &npurge, uint64_t); CTL_M2_GET("stats.arenas.0.npurge", i, &npurge, uint64_t);
@ -433,11 +420,6 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
OPT_WRITE_CHAR_P(dss) OPT_WRITE_CHAR_P(dss)
OPT_WRITE_UNSIGNED(narenas) OPT_WRITE_UNSIGNED(narenas)
OPT_WRITE_CHAR_P(purge) OPT_WRITE_CHAR_P(purge)
if (opt_purge == purge_mode_ratio) {
OPT_WRITE_SSIZE_T_MUTABLE(lg_dirty_mult,
arenas.lg_dirty_mult)
}
if (opt_purge == purge_mode_decay)
OPT_WRITE_SSIZE_T_MUTABLE(decay_time, arenas.decay_time) OPT_WRITE_SSIZE_T_MUTABLE(decay_time, arenas.decay_time)
OPT_WRITE_BOOL(stats_print) OPT_WRITE_BOOL(stats_print)
OPT_WRITE_CHAR_P(junk) OPT_WRITE_CHAR_P(junk)
@ -479,24 +461,10 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
CTL_GET("arenas.page", &sv, size_t); CTL_GET("arenas.page", &sv, size_t);
malloc_cprintf(write_cb, cbopaque, "Page size: %zu\n", sv); malloc_cprintf(write_cb, cbopaque, "Page size: %zu\n", sv);
CTL_GET("arenas.lg_dirty_mult", &ssv, ssize_t);
if (opt_purge == purge_mode_ratio) {
if (ssv >= 0) {
malloc_cprintf(write_cb, cbopaque,
"Min active:dirty page ratio per arena: "
"%u:1\n", (1U << ssv));
} else {
malloc_cprintf(write_cb, cbopaque,
"Min active:dirty page ratio per arena: "
"N/A\n");
}
}
CTL_GET("arenas.decay_time", &ssv, ssize_t); CTL_GET("arenas.decay_time", &ssv, ssize_t);
if (opt_purge == purge_mode_decay) {
malloc_cprintf(write_cb, cbopaque, malloc_cprintf(write_cb, cbopaque,
"Unused dirty page decay time: %zd%s\n", "Unused dirty page decay time: %zd%s\n", ssv, (ssv < 0) ?
ssv, (ssv < 0) ? " (no decay)" : ""); " (no decay)" : "");
}
if (je_mallctl("arenas.tcache_max", &sv, &ssz, NULL, 0) == 0) { if (je_mallctl("arenas.tcache_max", &sv, &ssz, NULL, 0) == 0) {
malloc_cprintf(write_cb, cbopaque, malloc_cprintf(write_cb, cbopaque,
"Maximum thread-cached size class: %zu\n", sv); "Maximum thread-cached size class: %zu\n", sv);

View File

@ -1,6 +1,6 @@
#include "test/jemalloc_test.h" #include "test/jemalloc_test.h"
const char *malloc_conf = "purge:decay,decay_time:1,lg_tcache_max:0"; const char *malloc_conf = "decay_time:1,lg_tcache_max:0";
static nstime_monotonic_t *nstime_monotonic_orig; static nstime_monotonic_t *nstime_monotonic_orig;
static nstime_update_t *nstime_update_orig; static nstime_update_t *nstime_update_orig;
@ -33,8 +33,6 @@ TEST_BEGIN(test_decay_ticks)
size_t sz, large0; size_t sz, large0;
void *p; void *p;
test_skip_if(opt_purge != purge_mode_decay);
decay_ticker = decay_ticker_get(tsd_fetch(), 0); decay_ticker = decay_ticker_get(tsd_fetch(), 0);
assert_ptr_not_null(decay_ticker, assert_ptr_not_null(decay_ticker,
"Unexpected failure getting decay ticker"); "Unexpected failure getting decay ticker");
@ -213,8 +211,6 @@ TEST_BEGIN(test_decay_ticker)
unsigned i, nupdates0; unsigned i, nupdates0;
nstime_t time, decay_time, deadline; nstime_t time, decay_time, deadline;
test_skip_if(opt_purge != purge_mode_decay);
/* /*
* Allocate a bunch of large objects, pause the clock, deallocate the * Allocate a bunch of large objects, pause the clock, deallocate the
* objects, restore the clock, then [md]allocx() in a tight loop to * objects, restore the clock, then [md]allocx() in a tight loop to
@ -307,8 +303,6 @@ TEST_BEGIN(test_decay_nonmonotonic)
size_t sz, large0; size_t sz, large0;
unsigned i, nupdates0; unsigned i, nupdates0;
test_skip_if(opt_purge != purge_mode_decay);
sz = sizeof(size_t); sz = sizeof(size_t);
assert_d_eq(mallctl("arenas.lextent.0.size", &large0, &sz, NULL, 0), 0, assert_d_eq(mallctl("arenas.lextent.0.size", &large0, &sz, NULL, 0), 0,
"Unexpected mallctl failure"); "Unexpected mallctl failure");

View File

@ -163,8 +163,6 @@ TEST_BEGIN(test_mallctl_opt)
TEST_MALLCTL_OPT(size_t, lg_chunk, always); TEST_MALLCTL_OPT(size_t, lg_chunk, always);
TEST_MALLCTL_OPT(const char *, dss, always); TEST_MALLCTL_OPT(const char *, dss, always);
TEST_MALLCTL_OPT(unsigned, narenas, always); TEST_MALLCTL_OPT(unsigned, narenas, always);
TEST_MALLCTL_OPT(const char *, purge, always);
TEST_MALLCTL_OPT(ssize_t, lg_dirty_mult, always);
TEST_MALLCTL_OPT(ssize_t, decay_time, always); TEST_MALLCTL_OPT(ssize_t, decay_time, always);
TEST_MALLCTL_OPT(bool, stats_print, always); TEST_MALLCTL_OPT(bool, stats_print, always);
TEST_MALLCTL_OPT(const char *, junk, fill); TEST_MALLCTL_OPT(const char *, junk, fill);
@ -349,47 +347,11 @@ TEST_BEGIN(test_thread_arena)
} }
TEST_END TEST_END
TEST_BEGIN(test_arena_i_lg_dirty_mult)
{
ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;
size_t sz = sizeof(ssize_t);
test_skip_if(opt_purge != purge_mode_ratio);
assert_d_eq(mallctl("arena.0.lg_dirty_mult", &orig_lg_dirty_mult, &sz,
NULL, 0), 0, "Unexpected mallctl() failure");
lg_dirty_mult = -2;
assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL,
&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success");
lg_dirty_mult = (sizeof(size_t) << 3);
assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL,
&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success");
for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;
lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult
= lg_dirty_mult, lg_dirty_mult++) {
ssize_t old_lg_dirty_mult;
assert_d_eq(mallctl("arena.0.lg_dirty_mult", &old_lg_dirty_mult,
&sz, &lg_dirty_mult, sizeof(ssize_t)), 0,
"Unexpected mallctl() failure");
assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,
"Unexpected old arena.0.lg_dirty_mult");
}
}
TEST_END
TEST_BEGIN(test_arena_i_decay_time) TEST_BEGIN(test_arena_i_decay_time)
{ {
ssize_t decay_time, orig_decay_time, prev_decay_time; ssize_t decay_time, orig_decay_time, prev_decay_time;
size_t sz = sizeof(ssize_t); size_t sz = sizeof(ssize_t);
test_skip_if(opt_purge != purge_mode_decay);
assert_d_eq(mallctl("arena.0.decay_time", &orig_decay_time, &sz, assert_d_eq(mallctl("arena.0.decay_time", &orig_decay_time, &sz,
NULL, 0), 0, "Unexpected mallctl() failure"); NULL, 0), 0, "Unexpected mallctl() failure");
@ -515,47 +477,11 @@ TEST_BEGIN(test_arenas_initialized)
} }
TEST_END TEST_END
TEST_BEGIN(test_arenas_lg_dirty_mult)
{
ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;
size_t sz = sizeof(ssize_t);
test_skip_if(opt_purge != purge_mode_ratio);
assert_d_eq(mallctl("arenas.lg_dirty_mult", &orig_lg_dirty_mult, &sz,
NULL, 0), 0, "Unexpected mallctl() failure");
lg_dirty_mult = -2;
assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL,
&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success");
lg_dirty_mult = (sizeof(size_t) << 3);
assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL,
&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
"Unexpected mallctl() success");
for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;
lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult =
lg_dirty_mult, lg_dirty_mult++) {
ssize_t old_lg_dirty_mult;
assert_d_eq(mallctl("arenas.lg_dirty_mult", &old_lg_dirty_mult,
&sz, &lg_dirty_mult, sizeof(ssize_t)), 0,
"Unexpected mallctl() failure");
assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,
"Unexpected old arenas.lg_dirty_mult");
}
}
TEST_END
TEST_BEGIN(test_arenas_decay_time) TEST_BEGIN(test_arenas_decay_time)
{ {
ssize_t decay_time, orig_decay_time, prev_decay_time; ssize_t decay_time, orig_decay_time, prev_decay_time;
size_t sz = sizeof(ssize_t); size_t sz = sizeof(ssize_t);
test_skip_if(opt_purge != purge_mode_decay);
assert_d_eq(mallctl("arenas.decay_time", &orig_decay_time, &sz, assert_d_eq(mallctl("arenas.decay_time", &orig_decay_time, &sz,
NULL, 0), 0, "Unexpected mallctl() failure"); NULL, 0), 0, "Unexpected mallctl() failure");
@ -669,7 +595,6 @@ TEST_BEGIN(test_stats_arenas)
TEST_STATS_ARENAS(unsigned, nthreads); TEST_STATS_ARENAS(unsigned, nthreads);
TEST_STATS_ARENAS(const char *, dss); TEST_STATS_ARENAS(const char *, dss);
TEST_STATS_ARENAS(ssize_t, lg_dirty_mult);
TEST_STATS_ARENAS(ssize_t, decay_time); TEST_STATS_ARENAS(ssize_t, decay_time);
TEST_STATS_ARENAS(size_t, pactive); TEST_STATS_ARENAS(size_t, pactive);
TEST_STATS_ARENAS(size_t, pdirty); TEST_STATS_ARENAS(size_t, pdirty);
@ -694,13 +619,11 @@ main(void)
test_tcache_none, test_tcache_none,
test_tcache, test_tcache,
test_thread_arena, test_thread_arena,
test_arena_i_lg_dirty_mult,
test_arena_i_decay_time, test_arena_i_decay_time,
test_arena_i_purge, test_arena_i_purge,
test_arena_i_decay, test_arena_i_decay,
test_arena_i_dss, test_arena_i_dss,
test_arenas_initialized, test_arenas_initialized,
test_arenas_lg_dirty_mult,
test_arenas_decay_time, test_arenas_decay_time,
test_arenas_constants, test_arenas_constants,
test_arenas_bin_constants, test_arenas_bin_constants,