3 ms·
Have you got any links to how they continue the threads after the gc has run? I was looking for something similar but couldn't find much.
by tubs 3y ago
Have you got any links to how they continue the threads after the gc has run? I was looking for something similar but couldn't find much.
- themoonisachees 3y agoNaïve approach is to have each segv handler poll something to tell when GC is done, and simply return when it can. State is then restored by the kernel.
- jlokier 3y agoYou could have each thread select(), poll(), or read() a byte, from the same pipe in their SIGSEGV handler. (Those syscalls are async-signal-safe in POSIX.) When it's time to resume, the GC unprotects the page then writes a byte (or enough bytes if read() is used), which wakes all the blocked mutator threads. Those threads also need to synchronise acks with the GC. After the GC protects the guard page, the mutators don't stop mutating immediately, so they must send an ack to the GC thread from their SIGSEGV handler to say when they have stopped. A pipe can be used for this too. Use of a non-mutex-using atomic counter, if available, can speed this by ensuring the GC only wakes once. Similarly the mutator threads must send an ack after they resume before returning from their SIGSEGV handler, to ensure the next GC run does not race with a mutator thread still slowly handling the current GC run On Linux, futex or eventfd are async-signal-safe but non-portable alternatives to pipes. Futex has the advantage of not using a file descriptor and may be faster.