1.0.26.15: interrupt.c refactoring
[sbcl.git] / src / runtime / interrupt.h
index 09a63f2..4f2b097 100644 (file)
 /* FIXME: do not rely on NSIG being a multiple of 8 */
 #define REAL_SIGSET_SIZE_BYTES ((NSIG/8))
 
-extern sigset_t deferrable_sigset;
-extern sigset_t blockable_sigset;
-
-extern void check_blockables_blocked_or_lose(void);
-extern void check_gc_signals_unblocked_or_lose(void);
-extern void unblock_gc_signals(void);
-
 static inline void
 sigcopyset(sigset_t *new, sigset_t *old)
 {
     memcpy(new, old, REAL_SIGSET_SIZE_BYTES);
 }
 
+extern void get_current_sigmask(sigset_t *sigset);
+
+/* Set all deferrable signals into *s. */
+extern void sigaddset_deferrable(sigset_t *s);
+/* Set all blockable signals into *s. */
+extern void sigaddset_blockable(sigset_t *s);
+/* Set all gc signals into *s. */
+extern void sigaddset_gc(sigset_t *s);
+
+extern sigset_t deferrable_sigset;
+extern sigset_t blockable_sigset;
+extern sigset_t gc_sigset;
+
+extern boolean deferrables_blocked_p(sigset_t *sigset);
+extern boolean blockables_blocked_p(sigset_t *sigset);
+extern boolean gc_signals_blocked_p(sigset_t *sigset);
+
+extern void check_deferrables_blocked_or_lose(sigset_t *sigset);
+extern void check_blockables_blocked_or_lose(sigset_t *sigset);
+extern void check_gc_signals_blocked_or_lose(sigset_t *sigset);
+
+extern void check_deferrables_unblocked_or_lose(sigset_t *sigset);
+extern void check_blockables_unblocked_or_lose(sigset_t *sigset);
+extern void check_gc_signals_unblocked_or_lose(sigset_t *sigset);
+
+extern void block_deferrable_signals(sigset_t *where, sigset_t *old);
+extern void block_blockable_signals(sigset_t *where, sigset_t *old);
+extern void block_gc_signals(sigset_t *where, sigset_t *old);
+
+extern void unblock_deferrable_signals(sigset_t *where, sigset_t *old);
+extern void unblock_blockable_signals(sigset_t *where, sigset_t *old);
+extern void unblock_gc_signals(sigset_t *where, sigset_t *old);
+
+extern void maybe_save_gc_mask_and_block_deferrables(sigset_t *sigset);
+
 /* maximum signal nesting depth
  *
  * FIXME: In CMUCL this was 4096, and it was first scaled down to 256
@@ -68,7 +96,7 @@ sigcopyset(sigset_t *new, sigset_t *old)
 
 union interrupt_handler {
     lispobj lisp;
-    void (*c)(int, siginfo_t*, void*);
+    void (*c)(int, siginfo_t*, os_context_t*);
 };
 
 extern union interrupt_handler interrupt_handlers[NSIG];
@@ -76,13 +104,18 @@ extern union interrupt_handler interrupt_handlers[NSIG];
 struct interrupt_data {
     /* signal information for pending signal.  pending_signal=0 when there
      * is no pending signal. */
-    void (*pending_handler) (int, siginfo_t*, void*) ;
+    void (*pending_handler) (int, siginfo_t*, os_context_t*) ;
     int pending_signal;
     siginfo_t pending_info;
     sigset_t pending_mask;
+    /* Was pending mask saved for gc request? True if GC_PENDING or
+     * SIG_STOP_FOR_GC happened in a pseudo atomic with no GC_INHIBIT
+     * NIL. Both deferrable interrupt handlers and gc are careful not
+     * to clobber each other's pending_mask. */
+    boolean gc_blocked_deferrables;
 };
 
-
+extern boolean interrupt_handler_pending_p(void);
 extern void interrupt_init(void);
 extern void fake_foreign_function_call(os_context_t* context);
 extern void undo_fake_foreign_function_call(os_context_t* context);
@@ -100,10 +133,9 @@ extern void do_pending_interrupt(void);
 #endif
 
 #ifdef LISP_FEATURE_SB_THREAD
-extern void interrupt_thread_handler(int, siginfo_t*, void*);
-extern void sig_stop_for_gc_handler(int, siginfo_t*, void*);
+extern void sig_stop_for_gc_handler(int, siginfo_t*, os_context_t*);
 #endif
-typedef void (*interrupt_handler_t)(int, siginfo_t *, void *);
+typedef void (*interrupt_handler_t)(int, siginfo_t *, os_context_t *);
 extern void undoably_install_low_level_interrupt_handler (
                         int signal,
                         interrupt_handler_t handler);
@@ -112,13 +144,6 @@ extern unsigned long install_handler(int signal,
 
 extern union interrupt_handler interrupt_handlers[NSIG];
 
-/* Set all deferrable signals into *s. */
-extern void sigaddset_deferrable(sigset_t *s);
-/* Set all blockable signals into *s. */
-extern void sigaddset_blockable(sigset_t *s);
-
-extern void block_blockable_signals(void);
-
 /* The void* casting here avoids having to mess with the various types
  * of function argument lists possible for signal handlers:
  * SA_SIGACTION handlers have one signature, and the default old-style