Skip to content

Commit e5fc5dd

Browse files
authored
Avoid calling mmtk_gc_poll frequently (#20)
1 parent bf1c43e commit e5fc5dd

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

src/julia_threads.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ typedef struct _jl_tls_states_t {
283283

284284
#ifdef MMTK_GC
285285
MMTkMutatorContext mmtk_mutator;
286+
size_t malloc_sz_since_last_poll;
286287
#endif
287288

288289
// some hidden state (usually just because we don't have the type's size declaration)

src/mmtk-gc.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,24 @@ JL_DLLEXPORT void jl_gc_set_cb_notify_external_free(jl_gc_cb_notify_external_fre
3333

3434
inline void maybe_collect(jl_ptls_t ptls)
3535
{
36-
mmtk_gc_poll(ptls);
36+
// Just do a safe point for general maybe_collect
37+
jl_gc_safepoint_(ptls);
38+
}
39+
40+
// This is only used for malloc. We need to know if we need to do GC. However, keeping checking with MMTk (mmtk_gc_poll),
41+
// is expensive. So we only check for every few allocations.
42+
static inline void malloc_maybe_collect(jl_ptls_t ptls, size_t sz)
43+
{
44+
// We do not need to carefully maintain malloc_sz_since_last_poll. We just need to
45+
// avoid using mmtk_gc_poll too frequently, and try to be precise on our heap usage
46+
// as much as we can.
47+
if (ptls->malloc_sz_since_last_poll > 4096) {
48+
jl_atomic_store_relaxed(&ptls->malloc_sz_since_last_poll, 0);
49+
mmtk_gc_poll(ptls);
50+
} else {
51+
jl_atomic_fetch_add_relaxed(&ptls->malloc_sz_since_last_poll, sz);
52+
jl_gc_safepoint_(ptls);
53+
}
3754
}
3855

3956

@@ -266,6 +283,9 @@ void jl_init_thread_heap(jl_ptls_t ptls)
266283
memset(&ptls->gc_num, 0, sizeof(ptls->gc_num));
267284
jl_atomic_store_relaxed(&ptls->gc_num.allocd, -(int64_t)gc_num.interval);
268285

286+
// Clear the malloc sz count
287+
jl_atomic_store_relaxed(&ptls->malloc_sz_since_last_poll, 0);
288+
269289
// Create mutator
270290
MMTk_Mutator mmtk_mutator = mmtk_bind_mutator((void *)ptls, ptls->tid);
271291
// Copy the mutator to the thread local storage
@@ -363,7 +383,7 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz)
363383
jl_task_t *ct = jl_current_task;
364384
if (pgcstack && ct->world_age) {
365385
jl_ptls_t ptls = ct->ptls;
366-
maybe_collect(ptls);
386+
malloc_maybe_collect(ptls, sz);
367387
jl_atomic_store_relaxed(&ptls->gc_num.allocd,
368388
jl_atomic_load_relaxed(&ptls->gc_num.allocd) + sz);
369389
jl_atomic_store_relaxed(&ptls->gc_num.malloc,
@@ -379,7 +399,7 @@ JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz)
379399
jl_task_t *ct = jl_current_task;
380400
if (pgcstack && ct->world_age) {
381401
jl_ptls_t ptls = ct->ptls;
382-
maybe_collect(ptls);
402+
malloc_maybe_collect(ptls, sz);
383403
jl_atomic_store_relaxed(&ptls->gc_num.allocd,
384404
jl_atomic_load_relaxed(&ptls->gc_num.allocd) + nm*sz);
385405
jl_atomic_store_relaxed(&ptls->gc_num.malloc,
@@ -411,7 +431,7 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size
411431
jl_task_t *ct = jl_current_task;
412432
if (pgcstack && ct->world_age) {
413433
jl_ptls_t ptls = ct->ptls;
414-
maybe_collect(ptls);
434+
malloc_maybe_collect(ptls, sz);
415435
if (sz < old)
416436
jl_atomic_store_relaxed(&ptls->gc_num.freed,
417437
jl_atomic_load_relaxed(&ptls->gc_num.freed) + (old - sz));

0 commit comments

Comments
 (0)