Skip to content

Commit 179ff61

Browse files
committed
Trigger GC for actors when they tell the cycle detector they're blocked
Prior to this commit, if an actor blocked, it did not run GC to free any memory it no longer needed. This would result in blocked actors holding on to (potentially lots of) memory unnecessarily. This commit causes GC to be triggered when the cycle detector asks an actor if it is blocked and the actor responds telling the cycle detector that it is blocked. This should result in memory being held by blocked actors to be freed more quickly even if the cycle detector doesn't end up detecting a cycle and reaping the actors.
1 parent 6d66304 commit 179ff61

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

src/libponyrt/actor/actor.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ static bool handle_message(pony_ctx_t* ctx, pony_actor_t* actor,
154154
// We're blocked, send block message.
155155
set_flag(actor, FLAG_BLOCKED_SENT);
156156
ponyint_cycle_block(ctx, actor, &actor->gc);
157+
158+
// trigger a GC if we're blocked and have done work since the last GC
159+
if(actor->msgs_since_gc > 0)
160+
pony_triggergc(ctx);
157161
}
158162

159163
return false;
@@ -230,6 +234,8 @@ static void try_gc(pony_ctx_t* ctx, pony_actor_t* actor)
230234
ponyint_mark_done(ctx);
231235
ponyint_heap_endgc(&actor->heap);
232236

237+
actor->msgs_since_gc = 0;
238+
233239
DTRACE1(GC_END, (uintptr_t)ctx->scheduler);
234240
}
235241

@@ -299,6 +305,7 @@ bool ponyint_actor_run(pony_ctx_t* ctx, pony_actor_t* actor, bool polling)
299305
{
300306
// If we handle an application message, try to gc.
301307
app++;
308+
actor->msgs_since_gc++;
302309
try_gc(ctx, actor);
303310

304311
// maybe mute actor
@@ -326,6 +333,7 @@ bool ponyint_actor_run(pony_ctx_t* ctx, pony_actor_t* actor, bool polling)
326333
{
327334
// If we handle an application message, try to gc.
328335
app++;
336+
actor->msgs_since_gc++;
329337
try_gc(ctx, actor);
330338

331339
// maybe mute actor; returns true if mute occurs
@@ -752,7 +760,10 @@ void* pony_alloc_large_final(pony_ctx_t* ctx, size_t size)
752760
PONY_API void pony_triggergc(pony_ctx_t* ctx)
753761
{
754762
pony_assert(ctx->current != NULL);
755-
ctx->current->heap.next_gc = 0;
763+
764+
// only trigger gc if actor allocated something on the heap
765+
if(ctx->current->heap.used > 0)
766+
ctx->current->heap.next_gc = 0;
756767
}
757768

758769
PONY_API void pony_schedule(pony_ctx_t* ctx, pony_actor_t* actor)

src/libponyrt/actor/actor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ typedef struct pony_actor_t
3636
#ifdef USE_ACTOR_CONTINUATIONS
3737
pony_msg_t* continuation;
3838
#endif
39+
uint32_t msgs_since_gc;
3940
PONY_ATOMIC(uint8_t) flags;
4041
PONY_ATOMIC(uint8_t) is_muted;
4142
PONY_ATOMIC(size_t) muted;

0 commit comments

Comments
 (0)