Pull tcache GC events into thread event handler

This commit is contained in:
Yinan Zhang 2019-10-24 16:41:45 -07:00
parent 198f02e797
commit 97f93fa0f2
8 changed files with 34 additions and 12 deletions

View File

@ -93,7 +93,6 @@ tcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
if (config_stats) { if (config_stats) {
bin->tstats.nrequests++; bin->tstats.nrequests++;
} }
tcache_event(tsd, tcache);
return ret; return ret;
} }
@ -150,7 +149,6 @@ tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size,
} }
} }
tcache_event(tsd, tcache);
return ret; return ret;
} }

View File

@ -43,10 +43,13 @@ typedef struct tcaches_s tcaches_t;
*/ */
#define TCACHE_GC_SWEEP 8192 #define TCACHE_GC_SWEEP 8192
/* Number of tcache allocation/deallocation events between incremental GCs. */ /* Number of tcache deallocation events between incremental GCs. */
#define TCACHE_GC_INCR \ #define TCACHE_GC_INCR \
((TCACHE_GC_SWEEP / SC_NBINS) + ((TCACHE_GC_SWEEP / SC_NBINS == 0) ? 0 : 1)) ((TCACHE_GC_SWEEP / SC_NBINS) + ((TCACHE_GC_SWEEP / SC_NBINS == 0) ? 0 : 1))
/* Number of allocation bytes between tcache incremental GCs. */
#define TCACHE_GC_INCR_BYTES 65536U
/* Used in TSD static initializer only. Real init in tsd_tcache_data_init(). */ /* Used in TSD static initializer only. Real init in tsd_tcache_data_init(). */
#define TCACHE_ZERO_INITIALIZER {{0}} #define TCACHE_ZERO_INITIALIZER {{0}}

View File

@ -33,6 +33,7 @@ void thread_event_boot();
* E(event, (condition)) * E(event, (condition))
*/ */
#define ITERATE_OVER_ALL_EVENTS \ #define ITERATE_OVER_ALL_EVENTS \
E(tcache_gc, (TCACHE_GC_INCR_BYTES > 0)) \
E(prof_sample, (config_prof && opt_prof)) E(prof_sample, (config_prof && opt_prof))
#define E(event, condition) \ #define E(event, condition) \

View File

@ -29,6 +29,7 @@
* x: narenas_tdata * x: narenas_tdata
* l: thread_allocated_last_event * l: thread_allocated_last_event
* j: thread_allocated_next_event * j: thread_allocated_next_event
* g: tcache_gc_event_wait
* w: prof_sample_event_wait (config_prof) * w: prof_sample_event_wait (config_prof)
* x: prof_sample_last_event (config_prof) * x: prof_sample_last_event (config_prof)
* p: prof_tdata (config_prof) * p: prof_tdata (config_prof)
@ -46,11 +47,11 @@
* |---------------------------- 2nd cacheline ----------------------------| * |---------------------------- 2nd cacheline ----------------------------|
* | [c * 64 ........ ........ ........ ........ ........ ........ .......] | * | [c * 64 ........ ........ ........ ........ ........ ........ .......] |
* |---------------------------- 3nd cacheline ----------------------------| * |---------------------------- 3nd cacheline ----------------------------|
* | [c * 32 ........ ........ .......] llllllll jjjjjjjj wwwwwwww xxxxxxxx | * | [c * 32 ........ ........ .......] llllllll jjjjjjjj gggggggg wwwwwwww |
* +---------------------------- 4th cacheline ----------------------------+ * +---------------------------- 4th cacheline ----------------------------+
* | pppppppp vvvvvvvv iiiiiiii aaaaaaaa oooooooo [b...... ........ ........ | * | xxxxxxxx pppppppp vvvvvvvv iiiiiiii aaaaaaaa oooooooo [b...... ........ |
* +---------------------------- 5th cacheline ----------------------------+ * +---------------------------- 5th cacheline ----------------------------+
* | ........ ..b][t.. ........ ........ ........ ........ ........ ........ | * | ........ ........ ..b][t.. ........ ........ ........ ........ ........ |
* +-------------------------------------------------------------------------+ * +-------------------------------------------------------------------------+
* Note: the entire tcache is embedded into TSD and spans multiple cachelines. * Note: the entire tcache is embedded into TSD and spans multiple cachelines.
* *
@ -83,6 +84,7 @@ typedef void (*test_callback_t)(int *);
O(rtree_ctx, rtree_ctx_t, rtree_ctx_t) \ O(rtree_ctx, rtree_ctx_t, rtree_ctx_t) \
O(thread_allocated_last_event, uint64_t, uint64_t) \ O(thread_allocated_last_event, uint64_t, uint64_t) \
O(thread_allocated_next_event, uint64_t, uint64_t) \ O(thread_allocated_next_event, uint64_t, uint64_t) \
O(tcache_gc_event_wait, uint64_t, uint64_t) \
O(prof_sample_event_wait, uint64_t, uint64_t) \ O(prof_sample_event_wait, uint64_t, uint64_t) \
O(prof_sample_last_event, uint64_t, uint64_t) \ O(prof_sample_last_event, uint64_t, uint64_t) \
O(prof_tdata, prof_tdata_t *, prof_tdata_t *) \ O(prof_tdata, prof_tdata_t *, prof_tdata_t *) \
@ -113,6 +115,7 @@ typedef void (*test_callback_t)(int *);
/* rtree_ctx */ RTREE_CTX_ZERO_INITIALIZER, \ /* rtree_ctx */ RTREE_CTX_ZERO_INITIALIZER, \
/* thread_allocated_last_event */ 0, \ /* thread_allocated_last_event */ 0, \
/* thread_allocated_next_event */ THREAD_EVENT_MIN_START_WAIT, \ /* thread_allocated_next_event */ THREAD_EVENT_MIN_START_WAIT, \
/* tcache_gc_event_wait */ THREAD_EVENT_MIN_START_WAIT, \
/* prof_sample_event_wait */ THREAD_EVENT_MIN_START_WAIT, \ /* prof_sample_event_wait */ THREAD_EVENT_MIN_START_WAIT, \
/* prof_sample_last_event */ 0, \ /* prof_sample_last_event */ 0, \
/* prof_tdata */ NULL, \ /* prof_tdata */ NULL, \

View File

@ -2350,10 +2350,6 @@ je_malloc(size_t size) {
tcache_t *tcache = tsd_tcachep_get(tsd); tcache_t *tcache = tsd_tcachep_get(tsd);
if (unlikely(ticker_trytick(&tcache->gc_ticker))) {
return malloc_default(size);
}
szind_t ind = sz_size2index_lookup(size); szind_t ind = sz_size2index_lookup(size);
/* /*
* The thread_allocated counter in tsd serves as a general purpose * The thread_allocated counter in tsd serves as a general purpose

View File

@ -18,6 +18,17 @@ static void thread_##event##_event_handler(tsd_t *tsd);
ITERATE_OVER_ALL_EVENTS ITERATE_OVER_ALL_EVENTS
#undef E #undef E
static void
thread_tcache_gc_event_handler(tsd_t *tsd) {
assert(TCACHE_GC_INCR_BYTES > 0);
assert(tcache_gc_event_wait_get(tsd) == 0U);
thread_tcache_gc_event_update(tsd, TCACHE_GC_INCR_BYTES);
tcache_t *tcache = tcache_get(tsd);
if (tcache != NULL) {
tcache_event_hard(tsd, tcache);
}
}
static void static void
thread_prof_sample_event_handler(tsd_t *tsd) { thread_prof_sample_event_handler(tsd_t *tsd) {
assert(config_prof && opt_prof); assert(config_prof && opt_prof);

View File

@ -233,6 +233,10 @@ tsd_data_init(tsd_t *tsd) {
*tsd_offset_statep_get(tsd) = config_debug ? 0 : *tsd_offset_statep_get(tsd) = config_debug ? 0 :
(uint64_t)(uintptr_t)tsd; (uint64_t)(uintptr_t)tsd;
if (TCACHE_GC_INCR_BYTES > 0) {
thread_tcache_gc_event_update(tsd, TCACHE_GC_INCR_BYTES);
}
return tsd_tcache_enabled_data_init(tsd); return tsd_tcache_enabled_data_init(tsd);
} }

View File

@ -9,8 +9,11 @@ TEST_BEGIN(test_next_event_fast_roll_back) {
THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX); THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX);
thread_allocated_next_event_fast_set(tsd, thread_allocated_next_event_fast_set(tsd,
THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX); THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX);
prof_sample_event_wait_set(tsd, #define E(event, condition) \
event##_event_wait_set(tsd, \
THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX); THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX);
ITERATE_OVER_ALL_EVENTS
#undef E
void *p = malloc(16U); void *p = malloc(16U);
assert_ptr_not_null(p, "malloc() failed"); assert_ptr_not_null(p, "malloc() failed");
free(p); free(p);
@ -25,8 +28,11 @@ TEST_BEGIN(test_next_event_fast_resume) {
thread_allocated_next_event_set(tsd, thread_allocated_next_event_set(tsd,
THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX + 16U); THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX + 16U);
thread_allocated_next_event_fast_set(tsd, 0); thread_allocated_next_event_fast_set(tsd, 0);
prof_sample_event_wait_set(tsd, #define E(event, condition) \
event##_event_wait_set(tsd, \
THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX + 16U); THREAD_ALLOCATED_NEXT_EVENT_FAST_MAX + 16U);
ITERATE_OVER_ALL_EVENTS
#undef E
void *p = malloc(SC_LOOKUP_MAXCLASS); void *p = malloc(SC_LOOKUP_MAXCLASS);
assert_ptr_not_null(p, "malloc() failed"); assert_ptr_not_null(p, "malloc() failed");
free(p); free(p);