Re: Remaining guardian issues
Marc Feeley 20 Dec 2023 04:21 UTC
> On Dec 19, 2023, at 3:02 PM, John Cowan <xxxxxx@ccil.org> wrote:
>
> There are two remaining guardian issues:
>
> 1) We have two proposals for async operations, Marc F.'s guardian-wait <https://srfi-email.schemers.org/srfi-246/msg/23507606/> and Daphne's guardian-try-collect <https://srfi-email.schemers.org/srfi-246/msg/23847614/>. It's unclear if these are completely distinct. Here are the apparent differences:
>
> a) -wait suspends the calling thread until there is an object in the inaccessible objects group; -try-collect triggers a GC to start with. The latter is useful if the GC is not running in its own thread (e.g. there are no threads).
>
> b) If the accessible objects group is empty, guardian-wait apparently waits for an object to be registered (adding it to the accessible objects group) and then waits again for it to move to the inaccessible objects group; guardian-try-collect returns at once.
>
> 2) The other issue is less significant and is orthogonal to 1. In the Chez and Guile implementations, a guardian is a procedure called with one or two arguments to add an object to the accessible objects group or with zero arguments to remove an object from the inaccessible objects group and return its representative. In Feeley's proposal, these operations are procedures applied to opaque guardian objects. In either case, -unregister and -wait/-try-collect are procedures applied to guardian objects. It is easy to convert either style to the other. The Chez/Guile style is backward compatible; the Feeley style is uniform.
>
> Daphne is off-line until next year. Marc, I haven't heard back from you on Daphne's proposal. Can you weigh in? Thanks.
I think it is a bad idea to introduce a procedure (i.e. guardian-try-collect) that triggers a garbage-collection, even if conditional. In typical language implementations with a garbage collector, it is often a design goal to make the operation of the garbage collector as transparent as possible. You shouldn’t have to know when the garbafe collector is run, and the algorithm used (stop the world, incremental, parallel, concurrent, etc). A garbage-collection is, relatively speaking, an extremely expensive operation because it operates globally on all objects in the heap. It can take anywhere from a millisecond (a long time on a modern CPU) to several seconds on large heaps. Imagine a concurrent program with N threads calling guardian-try-collect on various guardians for which no object gets enqueued. This will cause N GCs in rapid succession, with no computational progress happening. In the case where at least one object gets enqueued there is a possible improvement in performance by stopping the GC as soon as the first object gets enqueued, but this requires non-trivial changes to the garbage collector (how would you modify a parallel garbage collector) and there is no guarantee that the object gets enqueued early in the GC cycle.
Marc