Skip to content

Commit 07d5a22

Browse files
Run GC if no fiber stacks are available, before expanding pool.
1 parent 3b8317e commit 07d5a22

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

cont.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ fiber_pool_expand(struct fiber_pool * fiber_pool, size_t count)
554554

555555
if (!VirtualProtect(page, RB_PAGE_SIZE, PAGE_READWRITE | PAGE_GUARD, &old_protect)) {
556556
VirtualFree(allocation->base, 0, MEM_RELEASE);
557+
ruby_xfree(allocation);
557558
rb_raise(rb_eFiberError, "can't set a guard page: %s", ERRNOMSG);
558559
}
559560
#elif defined(__wasi__)
@@ -666,13 +667,23 @@ fiber_pool_allocation_free(struct fiber_pool_allocation * allocation)
666667
static struct fiber_pool_stack
667668
fiber_pool_stack_acquire(struct fiber_pool * fiber_pool)
668669
{
669-
struct fiber_pool_vacancy * vacancy ;
670+
struct fiber_pool_vacancy * vacancy;
671+
670672
RB_VM_LOCK_ENTER();
671673
{
672674
vacancy = fiber_pool_vacancy_pop(fiber_pool);
673675

674676
if (DEBUG) fprintf(stderr, "fiber_pool_stack_acquire: %p used=%"PRIuSIZE"\n", (void*)fiber_pool->vacancies, fiber_pool->used);
675677

678+
// During allocation, if we run out of stacks, we may need to collect garbage to free up some stacks before trying to allocate more.
679+
if (!vacancy) {
680+
if (DEBUG)fprintf(stderr, "fiber_pool_stack_acquire: no stacks available, collecting garbage\n");
681+
rb_gc();
682+
683+
// In the worst case, we garbage collect, but all fibers are reachable, so we don't free any stacks. We will try to expand the fiber pool:
684+
vacancy = fiber_pool_vacancy_pop(fiber_pool);
685+
}
686+
676687
if (!vacancy) {
677688
const size_t maximum = FIBER_POOL_ALLOCATION_MAXIMUM_SIZE;
678689
const size_t minimum = fiber_pool->initial_count;
@@ -681,6 +692,7 @@ fiber_pool_stack_acquire(struct fiber_pool * fiber_pool)
681692
if (count > maximum) count = maximum;
682693
if (count < minimum) count = minimum;
683694

695+
if (DEBUG)fprintf(stderr, "fiber_pool_stack_acquire: expanding fiber pool to %"PRIuSIZE" stacks\n", count);
684696
fiber_pool_expand(fiber_pool, count);
685697

686698
// The free list should now contain some stacks:

0 commit comments

Comments
 (0)