1 /* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
9 /* GC_startSignalHandler does not do an enter()/leave(), even though
10 * it is exported. The basis library uses it via _import, not _prim,
11 * and so does not treat it as a runtime call -- so the invariant in
12 * enter would fail miserably. It is OK because GC_startHandler must
13 * be called from within a critical section.
15 * Don't make it inline, because it is also called in basis/Thread.c,
16 * and when compiling with COMPILE_FAST, they may appear out of order.
18 void GC_startSignalHandler (GC_state s
) {
19 /* Switch to the signal handler thread. */
21 fprintf (stderr
, "GC_startSignalHandler\n");
23 assert (s
->atomicState
== 1);
24 assert (s
->signalsInfo
.signalIsPending
);
25 s
->signalsInfo
.signalIsPending
= FALSE
;
26 s
->signalsInfo
.amInSignalHandler
= TRUE
;
27 assert (s
->savedThread
== BOGUS_OBJPTR
);
28 s
->savedThread
= s
->currentThread
;
29 /* Set s->atomicState to 2 when switching to the signal handler
30 * thread; leaving the runtime will decrement s->atomicState to 1,
31 * the signal handler will then run atomically and will finish by
32 * switching to the thread to continue with, which will decrement
33 * s->atomicState to 0.
38 void GC_finishSignalHandler (GC_state s
) {
40 fprintf (stderr
, "GC_finishSignalHandler ()\n");
41 assert (s
->atomicState
== 1);
42 s
->signalsInfo
.amInSignalHandler
= FALSE
;
45 void switchToSignalHandlerThreadIfNonAtomicAndSignalPending (GC_state s
) {
46 if (s
->atomicState
== 1
47 and s
->signalsInfo
.signalIsPending
) {
48 GC_startSignalHandler (s
);
49 switchToThread (s
, s
->signalHandlerThread
);
53 /* GC_handler sets s->limit = 0 so that the next limit check will
54 * fail. Signals need to be blocked during the handler (i.e. it
55 * should run atomically) because sigaddset does both a read and a
56 * write of s->signalsInfo.signalsPending. The signals are blocked
57 * by Posix_Signal_handle (see Posix/Signal/Signal.c).
59 void GC_handler (GC_state s
, int signum
) {
61 fprintf (stderr
, "GC_handler signum = %d\n", signum
);
62 assert (sigismember (&s
->signalsInfo
.signalsHandled
, signum
));
63 if (s
->atomicState
== 0)
65 s
->signalsInfo
.signalIsPending
= TRUE
;
66 sigaddset (&s
->signalsInfo
.signalsPending
, signum
);
68 fprintf (stderr
, "GC_handler done\n");