1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
/* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
* Jagannathan, and Stephen Weeks.
* Copyright (C) 1997-2000 NEC Research Institute.
*
* MLton is released under a BSD-style license.
* See the file MLton-LICENSE for details.
*/
void switchToThread (GC_state s, objptr op) {
if (DEBUG_THREADS) {
GC_thread thread;
GC_stack stack;
thread = (GC_thread)(objptrToPointer (op, s->heap.start)
+ offsetofThread (s));
stack = (GC_stack)(objptrToPointer (thread->stack, s->heap.start));
fprintf (stderr, "switchToThread ("FMTOBJPTR") used = %"PRIuMAX
" reserved = %"PRIuMAX"\n",
op, (uintmax_t)stack->used, (uintmax_t)stack->reserved);
}
s->currentThread = op;
setGCStateCurrentThreadAndStack (s);
}
void GC_switchToThread (GC_state s, pointer p, size_t ensureBytesFree) {
if (DEBUG_THREADS)
fprintf (stderr, "GC_switchToThread ("FMTPTR", %"PRIuMAX")\n",
(uintptr_t)p, (uintmax_t)ensureBytesFree);
if (FALSE) {
/* This branch is slower than the else branch, especially
* when debugging is turned on, because it does an invariant
* check on every thread switch.
* So, we'll stick with the else branch for now.
*/
enter (s);
getThreadCurrent(s)->bytesNeeded = ensureBytesFree;
switchToThread (s, pointerToObjptr(p, s->heap.start));
s->atomicState--;
switchToSignalHandlerThreadIfNonAtomicAndSignalPending (s);
ensureInvariantForMutator (s, FALSE);
assert (invariantForMutatorFrontier(s));
assert (invariantForMutatorStack(s));
leave (s);
} else {
/* BEGIN: enter(s); */
getStackCurrent(s)->used = sizeofGCStateCurrentStackUsed (s);
getThreadCurrent(s)->exnStack = s->exnStack;
beginAtomic (s);
/* END: enter(s); */
getThreadCurrent(s)->bytesNeeded = ensureBytesFree;
switchToThread (s, pointerToObjptr(p, s->heap.start));
s->atomicState--;
switchToSignalHandlerThreadIfNonAtomicAndSignalPending (s);
/* BEGIN: ensureInvariantForMutator */
if (not (invariantForMutatorFrontier(s))
or not (invariantForMutatorStack(s))) {
/* This GC will grow the stack, if necessary. */
performGC (s, 0, getThreadCurrent(s)->bytesNeeded, FALSE, TRUE);
}
/* END: ensureInvariantForMutator */
/* BEGIN: leave(s); */
endAtomic (s);
/* END: leave(s); */
}
assert (invariantForMutatorFrontier(s));
assert (invariantForMutatorStack(s));
}
|