* Taking the read half of a reader-writer lock for all pointer mutations
The point here is to block all mutators from mutating the object graph
while the collector is traversing it. I can't imagine this being good
for performance. This is in addition to the mutex on the PMC. Other
threads might be scheduled before GC completes, but don't have to be for
GC to proceed.
* OS "pause thread" support
Lots of operating systems (including at least several versions of Mac OS
X) don't support this. Maybe parrot can use it when it is available.
It's always a dangerous proposition, though; the paused thread might be
holding the system's malloc() mutex or something similarly evil. (This
evil is why platforms don't always support the construct.) I don't think
this is feasible for portability reasons. In this case, other threads
would not be scheduled before GC completes.
* Use events
This is my proposition: Have the garbage collector broadcast a "STOP!"
event to every other parrot thread, and then wait for them all to
rendezvous that they've stopped before GC proceeds. Hold a lock on the
thread mutex while doing this, so threads won't start or finish. This
has the worst latency characteristics of the three: All other threads
would need to be scheduled before GC can begin. Corner cases exist: NCI
calls could be long-running and shouldn't block parrot until completion;
another thread might try to allocate memory before checking events.
Neither is insurmountable.
—
Gordon Henriksen
mali...@mac.com
> So, I haven't heard any convincing evidence that execution in other
> threads can continue while garbage collection is executing, copying
> collector or not.
So it is. The coyping GC is indeed a different issue and not related to
DOD (our term - that is freeing PObjs)
> * Use events
> This is my proposition: Have the garbage collector broadcast a "STOP!"
> event to every other parrot thread, and then wait for them all to
> rendezvous
That was and is my opinion towards that. Every other is precisely every
thread that might have shared resources common to that thread.
We could use *one* DOD thread (incremental and in the background as is)
but that implies all data are shared, which isn't true for RL. All
intermediate expression results are local temporary PMCs. Sharing all
would impose a huge impact on DOD - it has to deliver newly fresh PMCs
for all threads - and of course it has the additional locking costs.
As soon as we have a mixture of shared and non-shared PMCs incremental
or background DOD doesn't work (IMHO): Threads have to DOD their temps
alone and they can do that in parallel. *If* the owner of the shared
PMCs starts DOD then a sequence of stop the world will run, likely one
that is already *in the source as comments* (s. dod.c and bottom of
thread.c: pt_DOD*)
> ... Corner cases exist: NCI
> calls could be long-running and shouldn't block parrot until completion;
> another thread might try to allocate memory before checking events.
If a NCI function runs for hours or not has not immediately something
todo with threads. It blocks Parrot. It might block other threads, that
want to run DOD, but can't because one (NCI running) thread didn't get
it to the rendezvous. If a DOD or GC run is disabled the mem subsystem
just tries to allocate new resources from the OS. This works as long as
there are some resources left.
> Neither is insurmountable.
Kill 'em softly?
> Gordon Henriksen
leo