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