[MLton] cvs commit: critical sections during thread switch

Matthew Fluet fluet@cs.cornell.edu
Sun, 4 Apr 2004 11:46:21 -0400 (EDT)


A related question:  I was looking at GC_gc with an eye to fix the GC
and/or switch to handler problem.  The naive solution would be to do what
I said:

if (s->canHandle == 0 and s->signalIsPending) {
	startHandler (s);
	switchToThread (s, s->signalHandler);
}

However, I'd like to avoid too much duplicate work.  For example, if we
switch to the signal handler, then the GC we did for the current thread is
(in a sense) wasted, because we'll need to do an  ensureFree  (and
possibly doGC) when switching back to the current thread (if ever).
Likewise, even if we did to a GC for the current thread, there is the
possibility that the signal handler thread needs more bytes than the
current thread, so that while a minor GC serviced the current thread, upon
switching to the signal handler, we may need to do a major GC.

All of this suggested to me that we should switch to the signal handler
_first_.  Unfortunately, this plays havoc with the stackTopIsOk invariant
(and also the force GC argument, but that is really a side issue).

(Note: a similar argument applies to GC_switchToThread; if we need to
switch to the signal handler thread, we may waste work in switchToThread,
which will ensureFree for the thread we temporarily switch to before
switching to the signal handler.)

So, what is the rationale for maintaining the stackTopIsOk invariant; I
see that the comment on it says:
/* stackTopIsOk ensures that when this stack becomes current that
 * the stackTop is less than the stackLimit.
 */
but when switching to a thread, we may GC based on its bytesNeeded, so
why not GC based on its stackTopIsOk?


Now, of course, this may all be pretty moot.  I imagine that the
situtation I'm describing is pretty rare.  I guess I'll put in some DEBUG
fprintf's to see if it ever arises in practice.