+void
+sigaddset_blockable(sigset_t *s)
+{
+ sigaddset_deferrable(s);
+#ifdef LISP_FEATURE_SB_THREAD
+#ifdef SIG_RESUME_FROM_GC
+ sigaddset(s, SIG_RESUME_FROM_GC);
+#endif
+ sigaddset(s, SIG_STOP_FOR_GC);
+#endif
+}
+
+/* initialized in interrupt_init */
+static sigset_t deferrable_sigset;
+static sigset_t blockable_sigset;
+#endif
+
+void
+check_blockables_blocked_or_lose(void)
+{
+#if !defined(LISP_FEATURE_WIN32)
+ /* Get the current sigmask, by blocking the empty set. */
+ sigset_t empty,current;
+ int i;
+ sigemptyset(&empty);
+ thread_sigmask(SIG_BLOCK, &empty, ¤t);
+ for(i = 1; i < NSIG; i++) {
+ if (sigismember(&blockable_sigset, i) && !sigismember(¤t, i))
+ lose("blockable signal %d not blocked\n",i);
+ }
+#endif
+}
+
+void
+unblock_gc_signals(void)
+{
+#ifdef LISP_FEATURE_SB_THREAD
+ sigset_t new;
+ sigemptyset(&new);
+#if defined(SIG_RESUME_FROM_GC)
+ sigaddset(&new,SIG_RESUME_FROM_GC);
+#endif
+ sigaddset(&new,SIG_STOP_FOR_GC);
+ thread_sigmask(SIG_UNBLOCK,&new,0);
+#endif
+}
+
+inline static void
+check_interrupts_enabled_or_lose(os_context_t *context)
+{
+ struct thread *thread=arch_os_get_current_thread();
+ if (SymbolValue(INTERRUPTS_ENABLED,thread) == NIL)
+ lose("interrupts not enabled\n");
+ if (arch_pseudo_atomic_atomic(context))
+ lose ("in pseudo atomic section\n");
+}
+