9c767d44e1215d8a769e475676db0ca484004356
[ghc-hetmet.git] / ghc / rts / Signals.c
1 /* -----------------------------------------------------------------------------
2  * $Id: Signals.c,v 1.36 2003/03/29 00:00:41 sof Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Signal processing / handling.
7  *
8  * ---------------------------------------------------------------------------*/
9
10 /* This is non-Posix-compliant.
11    #include "PosixSource.h" 
12 */
13 #include "Rts.h"
14 #include "SchedAPI.h"
15 #include "Schedule.h"
16 #include "Signals.h"
17 #include "RtsUtils.h"
18 #include "RtsFlags.h"
19 #include "StablePriv.h"
20
21 #ifdef alpha_TARGET_ARCH
22 # include <machine/fpu.h>
23 #endif
24
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif
28
29 #ifdef HAVE_SIGNAL_H
30 # include <signal.h>
31 #endif
32
33 #include <stdlib.h>
34
35 #ifndef PAR
36
37 /* SUP: The type of handlers is a little bit, well, doubtful... */
38 static StgInt *handlers = NULL; /* Dynamically grown array of signal handlers */
39 static StgInt nHandlers = 0;    /* Size of handlers array */
40
41 static nat n_haskell_handlers = 0;
42
43 #define N_PENDING_HANDLERS 16
44
45 StgPtr pending_handler_buf[N_PENDING_HANDLERS];
46 StgPtr *next_pending_handler = pending_handler_buf;
47
48 StgInt nocldstop = 0;
49
50
51 #ifdef RTS_SUPPORTS_THREADS
52 pthread_t signalHandlingThread;
53 #endif
54
55         // Handle all signals in the current thread.
56         // Called from Capability.c whenever the main capability is granted to a thread
57         // and in installDefaultHandlers
58 void
59 handleSignalsInThisThread()
60 {
61 #ifdef RTS_SUPPORTS_THREADS
62     signalHandlingThread = pthread_self();
63 #endif
64 }
65
66
67 /* -----------------------------------------------------------------------------
68  * Allocate/resize the table of signal handlers.
69  * -------------------------------------------------------------------------- */
70
71 static void
72 more_handlers(I_ sig)
73 {
74     StgInt i;
75
76     if (sig < nHandlers)
77         return;
78
79     if (handlers == NULL)
80         handlers = (StgInt *)stgMallocBytes((sig + 1) * sizeof(StgInt), "more_handlers");
81     else
82         handlers = (StgInt *)stgReallocBytes(handlers, (sig + 1) * sizeof(StgInt), "more_handlers");
83
84     for(i = nHandlers; i <= sig; i++)
85         // Fill in the new slots with default actions
86         handlers[i] = STG_SIG_DFL;
87
88     nHandlers = sig + 1;
89 }
90
91 /* -----------------------------------------------------------------------------
92  * SIGCONT handler
93  *
94  * It seems that shells tend to put stdin back into blocking mode
95  * following a suspend/resume of the process.  Here we arrange to put
96  * it back into non-blocking mode.  We don't do anything to
97  * stdout/stderr because these handles don't get put into non-blocking
98  * mode at all - see the comments on stdout/stderr in PrelHandle.hsc.
99  * -------------------------------------------------------------------------- */
100
101 static void
102 cont_handler(int sig STG_UNUSED)
103 {
104     setNonBlockingFd(0);
105 }
106
107 /* -----------------------------------------------------------------------------
108  * Low-level signal handler
109  *
110  * Places the requested handler on a stack of pending handlers to be
111  * started up at the next context switch.
112  * -------------------------------------------------------------------------- */
113
114 static void
115 generic_handler(int sig)
116 {
117     sigset_t signals;
118
119 #if defined(THREADED_RTS)
120         // Make the thread that currently holds the main capability
121         // handle the signal.
122         // This makes sure that awaitEvent() is interrupted
123         // and it (hopefully) prevents race conditions
124         // (signal handlers are not atomic with respect to other threads)
125
126     if(pthread_self() != signalHandlingThread) {
127         pthread_kill(signalHandlingThread, sig);
128         return;
129     }
130 #endif
131
132     /* Can't call allocate from here.  Probably can't call malloc
133        either.  However, we have to schedule a new thread somehow.
134
135        It's probably ok to request a context switch and allow the
136        scheduler to  start the handler thread, but how do we
137        communicate this to the scheduler?
138
139        We need some kind of locking, but with low overhead (i.e. no
140        blocking signals every time around the scheduler).
141        
142        Signal Handlers are atomic (i.e. they can't be interrupted), and
143        we can make use of this.  We just need to make sure the
144        critical section of the scheduler can't be interrupted - the
145        only way to do this is to block signals.  However, we can lower
146        the overhead by only blocking signals when there are any
147        handlers to run, i.e. the set of pending handlers is
148        non-empty.
149     */
150        
151     /* We use a stack to store the pending signals.  We can't
152        dynamically grow this since we can't allocate any memory from
153        within a signal handler.
154
155        Hence unfortunately we have to bomb out if the buffer
156        overflows.  It might be acceptable to carry on in certain
157        circumstances, depending on the signal.  
158     */
159
160     *next_pending_handler++ = deRefStablePtr((StgStablePtr)handlers[sig]);
161
162     // stack full?
163     if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
164         prog_belch("too many pending signals");
165         stg_exit(EXIT_FAILURE);
166     }
167     
168     // re-establish the signal handler, and carry on
169     sigemptyset(&signals);
170     sigaddset(&signals, sig);
171     sigprocmask(SIG_UNBLOCK, &signals, NULL);
172
173     // *always* do the SIGCONT handler, even if the user overrides it.
174     if (sig == SIGCONT) {
175         cont_handler(sig);
176     }
177
178     context_switch = 1;
179 }
180
181 /* -----------------------------------------------------------------------------
182  * Blocking/Unblocking of the user signals
183  * -------------------------------------------------------------------------- */
184
185 static sigset_t userSignals;
186 static sigset_t savedSignals;
187
188 void
189 initUserSignals(void)
190 {
191     sigemptyset(&userSignals);
192 }
193
194 void
195 blockUserSignals(void)
196 {
197     sigprocmask(SIG_BLOCK, &userSignals, &savedSignals);
198 }
199
200 void
201 unblockUserSignals(void)
202 {
203     sigprocmask(SIG_SETMASK, &savedSignals, NULL);
204 }
205
206 rtsBool
207 anyUserHandlers(void)
208 {
209     return n_haskell_handlers != 0;
210 }
211
212 void
213 awaitUserSignals(void)
214 {
215     while (!signals_pending() && !interrupted) {
216         pause();
217     }
218 }
219
220 /* -----------------------------------------------------------------------------
221  * Install a Haskell signal handler.
222  * -------------------------------------------------------------------------- */
223
224 int
225 stg_sig_install(int sig, int spi, StgStablePtr *handler, void *mask)
226 {
227     sigset_t signals, osignals;
228     struct sigaction action;
229     StgInt previous_spi;
230
231     // Block the signal until we figure out what to do
232     // Count on this to fail if the signal number is invalid
233     if (sig < 0 || sigemptyset(&signals) ||
234         sigaddset(&signals, sig) || sigprocmask(SIG_BLOCK, &signals, &osignals)) {
235         return STG_SIG_ERR;
236     }
237     
238     more_handlers(sig);
239
240     previous_spi = handlers[sig];
241
242     action.sa_flags = 0;
243     
244     switch(spi) {
245     case STG_SIG_IGN:
246         handlers[sig] = STG_SIG_IGN;
247         sigdelset(&userSignals, sig);
248         action.sa_handler = SIG_IGN;
249         break;
250         
251     case STG_SIG_DFL:
252         handlers[sig] = STG_SIG_DFL;
253         sigdelset(&userSignals, sig);
254         action.sa_handler = SIG_DFL;
255         break;
256
257     case STG_SIG_HAN:
258     case STG_SIG_RST:
259         handlers[sig] = (StgInt)*handler;
260         sigaddset(&userSignals, sig);
261         action.sa_handler = generic_handler;
262         if (spi == STG_SIG_RST) {
263             action.sa_flags = SA_RESETHAND;
264         }
265         n_haskell_handlers++;
266         break;
267
268     default:
269         barf("stg_sig_install: bad spi");
270     }
271
272     if (mask != NULL)
273         action.sa_mask = *(sigset_t *)mask;
274     else
275         sigemptyset(&action.sa_mask);
276
277     action.sa_flags |= sig == SIGCHLD && nocldstop ? SA_NOCLDSTOP : 0;
278
279     if (sigaction(sig, &action, NULL) || 
280         sigprocmask(SIG_SETMASK, &osignals, NULL)) 
281     {
282         // need to return an error code, so avoid a stable pointer leak
283         // by freeing the previous handler if there was one.
284         if (previous_spi >= 0) {
285             freeStablePtr(stgCast(StgStablePtr,handlers[sig]));
286             n_haskell_handlers--;
287         }
288         return STG_SIG_ERR;
289     }
290     
291     if (previous_spi == STG_SIG_DFL || previous_spi == STG_SIG_IGN
292         || previous_spi == STG_SIG_ERR) {
293         return previous_spi;
294     } else {
295         *handler = (StgStablePtr)previous_spi;
296         return STG_SIG_HAN;
297     }
298 }
299
300 /* -----------------------------------------------------------------------------
301  * Creating new threads for the pending signal handlers.
302  * -------------------------------------------------------------------------- */
303 void
304 startSignalHandlers(void)
305 {
306   blockUserSignals();
307   
308   while (next_pending_handler != pending_handler_buf) {
309
310     next_pending_handler--;
311
312     scheduleThread(
313        createIOThread(RtsFlags.GcFlags.initialStkSize, 
314                       (StgClosure *) *next_pending_handler));
315   }
316
317   unblockUserSignals();
318 }
319
320 /* ----------------------------------------------------------------------------
321  * Mark signal handlers during GC.
322  *
323  * We do this rather than trying to start all the signal handlers
324  * prior to GC, because that requires extra heap for the new threads.
325  * Signals must be blocked (see blockUserSignals() above) during GC to
326  * avoid race conditions.
327  * -------------------------------------------------------------------------- */
328
329 void
330 markSignalHandlers (evac_fn evac)
331 {
332     StgPtr *p;
333
334     p = next_pending_handler;
335     while (p != pending_handler_buf) {
336         p--;
337         evac((StgClosure **)p);
338     }
339 }
340
341 #else // PAR
342 StgInt 
343 stg_sig_install(StgInt sig, StgInt spi, StgStablePtr handler, sigset_t *mask)
344 {
345     // don't fflush(stdout); WORKAROUND bug in Linux glibc
346     barf("no signal handling support in a parallel implementation");
347 }
348
349 void
350 startSignalHandlers(void)
351 {
352 }
353 #endif
354
355 /* -----------------------------------------------------------------------------
356  * SIGINT handler.
357  *
358  * We like to shutdown nicely after receiving a SIGINT, write out the
359  * stats, write profiling info, close open files and flush buffers etc.
360  * -------------------------------------------------------------------------- */
361 #ifdef SMP
362 pthread_t startup_guy;
363 #endif
364
365 static void
366 shutdown_handler(int sig STG_UNUSED)
367 {
368 #ifdef SMP
369     // if I'm a worker thread, send this signal to the guy who
370     // originally called startupHaskell().  Since we're handling
371     // the signal, it won't be a "send to all threads" type of signal
372     // (according to the POSIX threads spec).
373     if (pthread_self() != startup_guy) {
374         pthread_kill(startup_guy, sig);
375         return;
376     }
377     // ToDo: The code for the threaded RTS below does something very
378     // similar. Maybe the SMP special case is not needed
379     // -- Wolfgang Thaller
380 #elif defined(THREADED_RTS)
381         // Make the thread that currently holds the main capability
382         // handle the signal.
383         // This makes sure that awaitEvent() is interrupted
384     if(pthread_self() != signalHandlingThread) {
385         pthread_kill(signalHandlingThread, sig);
386         return;
387     }
388 #endif
389
390     // If we're already trying to interrupt the RTS, terminate with
391     // extreme prejudice.  So the first ^C tries to exit the program
392     // cleanly, and the second one just kills it.
393     if (interrupted) {
394         stg_exit(EXIT_INTERRUPTED);
395     } else {
396         interruptStgRts();
397     }
398 }
399
400 /* -----------------------------------------------------------------------------
401  * Install default signal handlers.
402  *
403  * The RTS installs a default signal handler for catching
404  * SIGINT, so that we can perform an orderly shutdown.
405  *
406  * Haskell code may install their own SIGINT handler, which is
407  * fine, provided they're so kind as to put back the old one
408  * when they de-install.
409  *
410  * In addition to handling SIGINT, the RTS also handles SIGFPE
411  * by ignoring it.  Apparently IEEE requires floating-point
412  * exceptions to be ignored by default, but alpha-dec-osf3
413  * doesn't seem to do so.
414  * -------------------------------------------------------------------------- */
415 void
416 initDefaultHandlers()
417 {
418     struct sigaction action,oact;
419
420 #ifdef SMP
421     startup_guy = pthread_self();
422 #endif
423 #ifdef RTS_SUPPORTS_THREADS
424         handleSignalsInThisThread();
425 #endif
426
427     // install the SIGINT handler
428     action.sa_handler = shutdown_handler;
429     sigemptyset(&action.sa_mask);
430     action.sa_flags = 0;
431     if (sigaction(SIGINT, &action, &oact) != 0) {
432         prog_belch("warning: failed to install SIGINT handler");
433     }
434
435 #ifndef cygwin32_TARGET_OS
436     siginterrupt(SIGINT, 1);    // isn't this the default? --SDM
437 #endif
438
439     // install the SIGCONT handler
440     action.sa_handler = cont_handler;
441     sigemptyset(&action.sa_mask);
442     action.sa_flags = 0;
443     if (sigaction(SIGCONT, &action, &oact) != 0) {
444         prog_belch("warning: failed to install SIGCONT handler");
445     }
446
447     // install the SIGFPE handler
448
449     // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
450     // Apparently IEEE requires floating-point exceptions to be ignored by
451     // default, but alpha-dec-osf3 doesn't seem to do so.
452
453     // Commented out by SDM 2/7/2002: this causes an infinite loop on
454     // some architectures when an integer division by zero occurs: we
455     // don't recover from the floating point exception, and the
456     // program just generates another one immediately.
457 #if 0
458     action.sa_handler = SIG_IGN;
459     sigemptyset(&action.sa_mask);
460     action.sa_flags = 0;
461     if (sigaction(SIGFPE, &action, &oact) != 0) {
462         prog_belch("warning: failed to install SIGFPE handler");
463     }
464 #endif
465
466 #ifdef alpha_TARGET_ARCH
467     ieee_set_fp_control(0);
468 #endif
469 }