+/* Check our baroque invariants. */
+void
+check_interrupt_context_or_lose(os_context_t *context)
+{
+ struct thread *thread = arch_os_get_current_thread();
+ struct interrupt_data *data = thread->interrupt_data;
+ int interrupt_deferred_p = (data->pending_handler != 0);
+ int interrupt_pending = (SymbolValue(INTERRUPT_PENDING,thread) != NIL);
+ /* On PPC pseudo_atomic_interrupted is cleared when coming out of
+ * handle_allocation_trap. */
+#if defined(LISP_FEATURE_GENCGC) && !defined(LISP_FEATURE_PPC)
+#if 0
+ int interrupts_enabled = (SymbolValue(INTERRUPTS_ENABLED,thread) != NIL);
+ int gc_inhibit = (SymbolValue(GC_INHIBIT,thread) != NIL);
+ int gc_pending = (SymbolValue(GC_PENDING,thread) == T);
+ int pseudo_atomic_interrupted = get_pseudo_atomic_interrupted(thread);
+#endif
+ /* In the time window between leaving the *INTERRUPTS-ENABLED* NIL
+ * section and trapping, a SIG_STOP_FOR_GC would see the next
+ * check fail, for this reason sig_stop_for_gc handler does not
+ * call this function. Plus, there may be interrupt lossage when a
+ * pseudo atomic is interrupted by a deferrable signal and gc is
+ * triggered, too. */
+#if 0
+ if (interrupt_deferred_p)
+ if (interrupts_enabled && !pseudo_atomic_interrupted)
+ lose("Stray deferred interrupt.");
+#endif
+ /* Broken momentarily at the end of WITHOUT-GCING. */
+#if 0
+ if (gc_pending)
+ if (!(pseudo_atomic_interrupted || gc_inhibit))
+ lose("GC_PENDING, but why?.");
+#if defined(LISP_FEATURE_SB_THREAD)
+ {
+ int stop_for_gc_pending =
+ (SymbolValue(STOP_FOR_GC_PENDING,thread) != NIL);
+ if (stop_for_gc_pending)
+ if (!(pseudo_atomic_interrupted || gc_inhibit))
+ lose("STOP_FOR_GC_PENDING, but why?.");
+ }
+#endif
+#endif
+#endif
+ if (interrupt_pending && !interrupt_deferred_p)
+ lose("INTERRUPT_PENDING but not pending handler.");
+ if (interrupt_deferred_p)
+ check_deferrables_blocked_in_sigset_or_lose
+ (os_context_sigmask_addr(context));
+ else
+ check_deferrables_unblocked_in_sigset_or_lose
+ (os_context_sigmask_addr(context));
+}
+