rts/Schedule: Allow synchronization without holding a capability wip/gc/sync-without-capability
authorBen Gamari <ben@well-typed.com>
Fri, 20 Jul 2018 01:57:14 +0000 (21:57 -0400)
committerBen Gamari <ben@smart-cactus.org>
Tue, 18 Jun 2019 22:07:56 +0000 (18:07 -0400)
commitf17c9fcf97efd3f4f3b954cc1a7a4f2a12e1e95b
treeba50872aa034829f4690a550d1107aa4732f49df
parentbb141114ad4e4eb6db66e212fa08d93257b99bbc
rts/Schedule: Allow synchronization without holding a capability

The concurrent mark-and-sweep will be performed by a GHC task which will
not hold a capability. This is necessary to avoid a concurrent mark from
interfering with minor generation collections.

However, the major collector must synchronize with the mutators at the
end of marking to flush their update remembered sets. This patch extends
the `requestSync` mechanism used to synchronize garbage collectors to
allow synchronization without holding a capability.

This change is fairly straightforward as the capability was previously
only required for two reasons:

 1. to ensure that we don't try to re-acquire a capability that we
    the sync requestor already holds.

 2. to provide a way to suspend and later resume the sync request if
    there is already a sync pending.

When synchronizing without holding a capability we needn't worry about
consideration (1) at all.

(2) is slightly trickier and may happen, for instance, when a capability
requests a minor collection and shortly thereafter the non-moving mark
thread requests a post-mark synchronization. In this case we need to
ensure that the non-moving mark thread suspends his request until after
the minor GC has concluded to avoid dead-locking. For this we introduce
a condition variable, `sync_finished_cond`, which a
non-capability-bearing requestor will wait on and which is signalled
after a synchronization or GC has finished.
rts/Schedule.c
rts/Schedule.h