Commit | Line | Data |
---|---|---|
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 | ||
9 | void 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 | ||
26 | void 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 | } |