a5044cd6de08c34af2d904128e91b65a5e983d4f
[ghc-hetmet.git] / rts / posix / Signals.c
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2005
4  *
5  * Signal processing / handling.
6  *
7  * ---------------------------------------------------------------------------*/
8
9 /* This is non-Posix-compliant.
10    #include "PosixSource.h" 
11 */
12 #include "Rts.h"
13 #include "SchedAPI.h"
14 #include "Schedule.h"
15 #include "RtsSignals.h"
16 #include "posix/Signals.h"
17 #include "RtsUtils.h"
18 #include "RtsFlags.h"
19 #include "Prelude.h"
20
21 #ifdef alpha_HOST_ARCH
22 # if defined(linux_HOST_OS)
23 #  include <asm/fpu.h>
24 # else
25 #  include <machine/fpu.h>
26 # endif
27 #endif
28
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32
33 #ifdef HAVE_SIGNAL_H
34 # include <signal.h>
35 #endif
36
37 #include <stdlib.h>
38
39 /* This curious flag is provided for the benefit of the Haskell binding
40  * to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
41  * installing a SIGCHLD handler. 
42  */
43 StgInt nocldstop = 0;
44
45 /* -----------------------------------------------------------------------------
46  * The table of signal handlers
47  * -------------------------------------------------------------------------- */
48
49 #if defined(RTS_USER_SIGNALS)
50
51 /* SUP: The type of handlers is a little bit, well, doubtful... */
52 StgInt *signal_handlers = NULL; /* Dynamically grown array of signal handlers */
53 static StgInt nHandlers = 0;    /* Size of handlers array */
54
55 static nat n_haskell_handlers = 0;
56
57 /* -----------------------------------------------------------------------------
58  * Allocate/resize the table of signal handlers.
59  * -------------------------------------------------------------------------- */
60
61 static void
62 more_handlers(I_ sig)
63 {
64     StgInt i;
65
66     if (sig < nHandlers)
67         return;
68
69     if (signal_handlers == NULL)
70         signal_handlers = (StgInt *)stgMallocBytes((sig + 1) * sizeof(StgInt), "more_handlers");
71     else
72         signal_handlers = (StgInt *)stgReallocBytes(signal_handlers, (sig + 1) * sizeof(StgInt), "more_handlers");
73
74     for(i = nHandlers; i <= sig; i++)
75         // Fill in the new slots with default actions
76         signal_handlers[i] = STG_SIG_DFL;
77
78     nHandlers = sig + 1;
79 }
80
81 /* -----------------------------------------------------------------------------
82  * Pending Handlers
83  *
84  * The mechanism for starting handlers differs between the threaded
85  * (THREADED_RTS) and non-threaded versions of the RTS.
86  *
87  * When the RTS is single-threaded, we just write the pending signal
88  * handlers into a buffer, and start a thread for each one in the
89  * scheduler loop.
90  *
91  * When THREADED_RTS, the problem is that signals might be
92  * delivered to multiple threads, so we would need to synchronise
93  * access to pending_handler_buf somehow.  Using thread
94  * synchronisation from a signal handler isn't possible in general
95  * (some OSs support it, eg. MacOS X, but not all).  So instead:
96  *
97  *   - the signal handler writes the signal number into the pipe
98  *     managed by the IO manager thread (see GHC.Conc).
99  *   - the IO manager picks up the signal number and calls
100  *     startSignalHandler() to start the thread.
101  *
102  * This also has the nice property that we don't need to arrange to
103  * wake up a worker task to start the signal handler: the IO manager
104  * wakes up when we write into the pipe.
105  *
106  * -------------------------------------------------------------------------- */
107
108 // Here's the pipe into which we will send our signals
109 static int io_manager_pipe = -1;
110
111 #define IO_MANAGER_WAKEUP 0xff
112 #define IO_MANAGER_DIE    0xfe
113
114 void
115 setIOManagerPipe (int fd)
116 {
117     // only called when THREADED_RTS, but unconditionally
118     // compiled here because GHC.Conc depends on it.
119     io_manager_pipe = fd;
120 }
121
122 #if defined(THREADED_RTS)
123 void
124 ioManagerWakeup (void)
125 {
126     // Wake up the IO Manager thread by sending a byte down its pipe
127     if (io_manager_pipe >= 0) {
128         StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
129         write(io_manager_pipe, &byte, 1);
130     }
131 }
132
133 void
134 ioManagerDie (void)
135 {
136     // Ask the IO Manager thread to exit
137     if (io_manager_pipe >= 0) {
138         StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
139         write(io_manager_pipe, &byte, 1);
140     }
141 }
142
143 void
144 ioManagerStart (void)
145 {
146     // Make sure the IO manager thread is running
147     Capability *cap;
148     if (io_manager_pipe < 0) {
149         cap = rts_lock();
150         rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
151         rts_unlock(cap);
152     }
153 }
154 #endif
155
156 #if !defined(THREADED_RTS)
157
158 #define N_PENDING_HANDLERS 16
159
160 StgPtr pending_handler_buf[N_PENDING_HANDLERS];
161 StgPtr *next_pending_handler = pending_handler_buf;
162
163 #endif /* THREADED_RTS */
164
165 /* -----------------------------------------------------------------------------
166  * SIGCONT handler
167  *
168  * It seems that shells tend to put stdin back into blocking mode
169  * following a suspend/resume of the process.  Here we arrange to put
170  * it back into non-blocking mode.  We don't do anything to
171  * stdout/stderr because these handles don't get put into non-blocking
172  * mode at all - see the comments on stdout/stderr in PrelHandle.hsc.
173  * -------------------------------------------------------------------------- */
174
175 static void
176 cont_handler(int sig STG_UNUSED)
177 {
178     setNonBlockingFd(0);
179 }
180
181 /* -----------------------------------------------------------------------------
182  * Low-level signal handler
183  *
184  * Places the requested handler on a stack of pending handlers to be
185  * started up at the next context switch.
186  * -------------------------------------------------------------------------- */
187
188 static void
189 generic_handler(int sig)
190 {
191     sigset_t signals;
192
193 #if defined(THREADED_RTS)
194
195     if (io_manager_pipe != -1)
196     {
197         // Write the signal number into the pipe as a single byte.  We
198         // hope that signals fit into a byte...
199         StgWord8 csig = (StgWord8)sig;
200         write(io_manager_pipe, &csig, 1);
201     }
202     // If the IO manager hasn't told us what the FD of the write end
203     // of its pipe is, there's not much we can do here, so just ignore
204     // the signal..
205
206 #else /* not THREADED_RTS */
207
208     /* Can't call allocate from here.  Probably can't call malloc
209        either.  However, we have to schedule a new thread somehow.
210
211        It's probably ok to request a context switch and allow the
212        scheduler to  start the handler thread, but how do we
213        communicate this to the scheduler?
214
215        We need some kind of locking, but with low overhead (i.e. no
216        blocking signals every time around the scheduler).
217        
218        Signal Handlers are atomic (i.e. they can't be interrupted), and
219        we can make use of this.  We just need to make sure the
220        critical section of the scheduler can't be interrupted - the
221        only way to do this is to block signals.  However, we can lower
222        the overhead by only blocking signals when there are any
223        handlers to run, i.e. the set of pending handlers is
224        non-empty.
225     */
226        
227     /* We use a stack to store the pending signals.  We can't
228        dynamically grow this since we can't allocate any memory from
229        within a signal handler.
230
231        Hence unfortunately we have to bomb out if the buffer
232        overflows.  It might be acceptable to carry on in certain
233        circumstances, depending on the signal.  
234     */
235
236     *next_pending_handler++ = deRefStablePtr((StgStablePtr)signal_handlers[sig]);
237
238     // stack full?
239     if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
240         errorBelch("too many pending signals");
241         stg_exit(EXIT_FAILURE);
242     }
243     
244 #endif /* THREADED_RTS */
245
246     // re-establish the signal handler, and carry on
247     sigemptyset(&signals);
248     sigaddset(&signals, sig);
249     sigprocmask(SIG_UNBLOCK, &signals, NULL);
250
251     // *always* do the SIGCONT handler, even if the user overrides it.
252     if (sig == SIGCONT) {
253         cont_handler(sig);
254     }
255
256     context_switch = 1;
257 }
258
259 /* -----------------------------------------------------------------------------
260  * Blocking/Unblocking of the user signals
261  * -------------------------------------------------------------------------- */
262
263 static sigset_t userSignals;
264 static sigset_t savedSignals;
265
266 void
267 initUserSignals(void)
268 {
269     sigemptyset(&userSignals);
270 }
271
272 void
273 blockUserSignals(void)
274 {
275     sigprocmask(SIG_BLOCK, &userSignals, &savedSignals);
276 }
277
278 void
279 unblockUserSignals(void)
280 {
281     sigprocmask(SIG_SETMASK, &savedSignals, NULL);
282 }
283
284 rtsBool
285 anyUserHandlers(void)
286 {
287     return n_haskell_handlers != 0;
288 }
289
290 #if !defined(THREADED_RTS)
291 void
292 awaitUserSignals(void)
293 {
294     while (!signals_pending() && sched_state == SCHED_RUNNING) {
295         pause();
296     }
297 }
298 #endif
299
300 /* -----------------------------------------------------------------------------
301  * Install a Haskell signal handler.
302  * -------------------------------------------------------------------------- */
303
304 int
305 stg_sig_install(int sig, int spi, StgStablePtr *handler, void *mask)
306 {
307     sigset_t signals, osignals;
308     struct sigaction action;
309     StgInt previous_spi;
310
311     // Block the signal until we figure out what to do
312     // Count on this to fail if the signal number is invalid
313     if (sig < 0 || sigemptyset(&signals) ||
314         sigaddset(&signals, sig) || sigprocmask(SIG_BLOCK, &signals, &osignals)) {
315         return STG_SIG_ERR;
316     }
317     
318     more_handlers(sig);
319
320     previous_spi = signal_handlers[sig];
321
322     action.sa_flags = 0;
323     
324     switch(spi) {
325     case STG_SIG_IGN:
326         signal_handlers[sig] = STG_SIG_IGN;
327         sigdelset(&userSignals, sig);
328         action.sa_handler = SIG_IGN;
329         break;
330         
331     case STG_SIG_DFL:
332         signal_handlers[sig] = STG_SIG_DFL;
333         sigdelset(&userSignals, sig);
334         action.sa_handler = SIG_DFL;
335         break;
336
337     case STG_SIG_HAN:
338     case STG_SIG_RST:
339         signal_handlers[sig] = (StgInt)*handler;
340         sigaddset(&userSignals, sig);
341         action.sa_handler = generic_handler;
342         if (spi == STG_SIG_RST) {
343             action.sa_flags = SA_RESETHAND;
344         }
345         n_haskell_handlers++;
346         break;
347
348     default:
349         barf("stg_sig_install: bad spi");
350     }
351
352     if (mask != NULL)
353         action.sa_mask = *(sigset_t *)mask;
354     else
355         sigemptyset(&action.sa_mask);
356
357     action.sa_flags |= sig == SIGCHLD && nocldstop ? SA_NOCLDSTOP : 0;
358
359     if (sigaction(sig, &action, NULL) || 
360         sigprocmask(SIG_SETMASK, &osignals, NULL)) 
361     {
362         // need to return an error code, so avoid a stable pointer leak
363         // by freeing the previous handler if there was one.
364         if (previous_spi >= 0) {
365             freeStablePtr(stgCast(StgStablePtr,signal_handlers[sig]));
366             n_haskell_handlers--;
367         }
368         return STG_SIG_ERR;
369     }
370
371     if (previous_spi == STG_SIG_DFL || previous_spi == STG_SIG_IGN
372         || previous_spi == STG_SIG_ERR) {
373         return previous_spi;
374     } else {
375         *handler = (StgStablePtr)previous_spi;
376         return STG_SIG_HAN;
377     }
378 }
379
380 /* -----------------------------------------------------------------------------
381  * Creating new threads for signal handlers.
382  * -------------------------------------------------------------------------- */
383
384 #if !defined(THREADED_RTS)
385 void
386 startSignalHandlers(Capability *cap)
387 {
388   blockUserSignals();
389   
390   while (next_pending_handler != pending_handler_buf) {
391
392     next_pending_handler--;
393
394     scheduleThread (cap,
395         createIOThread(cap,
396                        RtsFlags.GcFlags.initialStkSize, 
397                        (StgClosure *) *next_pending_handler));
398   }
399
400   unblockUserSignals();
401 }
402 #endif
403
404 /* ----------------------------------------------------------------------------
405  * Mark signal handlers during GC.
406  *
407  * We do this rather than trying to start all the signal handlers
408  * prior to GC, because that requires extra heap for the new threads.
409  * Signals must be blocked (see blockUserSignals() above) during GC to
410  * avoid race conditions.
411  * -------------------------------------------------------------------------- */
412
413 #if !defined(THREADED_RTS)
414 void
415 markSignalHandlers (evac_fn evac)
416 {
417     StgPtr *p;
418
419     p = next_pending_handler;
420     while (p != pending_handler_buf) {
421         p--;
422         evac((StgClosure **)p);
423     }
424 }
425 #else
426 void
427 markSignalHandlers (evac_fn evac STG_UNUSED)
428 {
429 }
430 #endif
431
432 #else /* !RTS_USER_SIGNALS */
433 StgInt 
434 stg_sig_install(StgInt sig STG_UNUSED,
435                 StgInt spi STG_UNUSED,
436                 StgStablePtr* handler STG_UNUSED,
437                 void* mask STG_UNUSED)
438 {
439   //barf("User signals not supported");
440   return STG_SIG_DFL;
441 }
442
443 #endif
444
445 #if defined(RTS_USER_SIGNALS)
446 /* -----------------------------------------------------------------------------
447  * SIGINT handler.
448  *
449  * We like to shutdown nicely after receiving a SIGINT, write out the
450  * stats, write profiling info, close open files and flush buffers etc.
451  * -------------------------------------------------------------------------- */
452 #ifdef SMP
453 pthread_t startup_guy;
454 #endif
455
456 static void
457 shutdown_handler(int sig STG_UNUSED)
458 {
459 #ifdef SMP
460     // if I'm a worker thread, send this signal to the guy who
461     // originally called startupHaskell().  Since we're handling
462     // the signal, it won't be a "send to all threads" type of signal
463     // (according to the POSIX threads spec).
464     if (pthread_self() != startup_guy) {
465         pthread_kill(startup_guy, sig);
466         return;
467     }
468 #endif
469
470     // If we're already trying to interrupt the RTS, terminate with
471     // extreme prejudice.  So the first ^C tries to exit the program
472     // cleanly, and the second one just kills it.
473     if (sched_state >= SCHED_INTERRUPTING) {
474         stg_exit(EXIT_INTERRUPTED);
475     } else {
476         interruptStgRts();
477     }
478 }
479
480 /* -----------------------------------------------------------------------------
481  * Install default signal handlers.
482  *
483  * The RTS installs a default signal handler for catching
484  * SIGINT, so that we can perform an orderly shutdown.
485  *
486  * Haskell code may install their own SIGINT handler, which is
487  * fine, provided they're so kind as to put back the old one
488  * when they de-install.
489  *
490  * In addition to handling SIGINT, the RTS also handles SIGFPE
491  * by ignoring it.  Apparently IEEE requires floating-point
492  * exceptions to be ignored by default, but alpha-dec-osf3
493  * doesn't seem to do so.
494  * -------------------------------------------------------------------------- */
495 void
496 initDefaultHandlers()
497 {
498     struct sigaction action,oact;
499
500 #ifdef SMP
501     startup_guy = pthread_self();
502 #endif
503
504     // install the SIGINT handler
505     action.sa_handler = shutdown_handler;
506     sigemptyset(&action.sa_mask);
507     action.sa_flags = 0;
508     if (sigaction(SIGINT, &action, &oact) != 0) {
509         sysErrorBelch("warning: failed to install SIGINT handler");
510     }
511
512 #if defined(HAVE_SIGINTERRUPT)
513     siginterrupt(SIGINT, 1);    // isn't this the default? --SDM
514 #endif
515
516     // install the SIGCONT handler
517     action.sa_handler = cont_handler;
518     sigemptyset(&action.sa_mask);
519     action.sa_flags = 0;
520     if (sigaction(SIGCONT, &action, &oact) != 0) {
521         sysErrorBelch("warning: failed to install SIGCONT handler");
522     }
523
524     // install the SIGFPE handler
525
526     // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
527     // Apparently IEEE requires floating-point exceptions to be ignored by
528     // default, but alpha-dec-osf3 doesn't seem to do so.
529
530     // Commented out by SDM 2/7/2002: this causes an infinite loop on
531     // some architectures when an integer division by zero occurs: we
532     // don't recover from the floating point exception, and the
533     // program just generates another one immediately.
534 #if 0
535     action.sa_handler = SIG_IGN;
536     sigemptyset(&action.sa_mask);
537     action.sa_flags = 0;
538     if (sigaction(SIGFPE, &action, &oact) != 0) {
539         sysErrorBelch("warning: failed to install SIGFPE handler");
540     }
541 #endif
542
543 #ifdef alpha_HOST_ARCH
544     ieee_set_fp_control(0);
545 #endif
546 }
547
548 #endif /* RTS_USER_SIGNALS */