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