#endif
void
-check_blockables_blocked_or_lose()
+check_blockables_blocked_or_lose(void)
{
-#ifndef LISP_FEATURE_WIN32
+#if !defined(LISP_FEATURE_WIN32)
/* Get the current sigmask, by blocking the empty set. */
sigset_t empty,current;
int i;
#endif
}
+void
+check_gc_signals_unblocked_or_lose(void)
+{
+#ifdef LISP_FEATURE_SB_THREAD
+# if !defined(LISP_FEATURE_WIN32)
+ /* Get the current sigmask, by blocking the empty set. */
+ sigset_t empty,current;
+ sigemptyset(&empty);
+ thread_sigmask(SIG_BLOCK, &empty, ¤t);
+ if (sigismember(¤t, SIG_STOP_FOR_GC))
+ lose("SIG_STOP_FOR_GC blocked in thread %p at a bad place\n",
+ arch_os_get_current_thread());
+# if defined(SIG_RESUME_FROM_GC)
+ if (sigismember(¤t, SIG_RESUME_FROM_GC))
+ lose("SIG_RESUME_FROM_GC blocked in thread %p at a bad place\n",
+ arch_os_get_current_thread());
+# endif
+# endif
+#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)
{
#endif
}
+void
+block_deferrable_signals(void)
+{
+#ifndef LISP_FEATURE_WIN32
+ thread_sigmask(SIG_BLOCK, &deferrable_sigset, 0);
+#endif
+}
+
\f
/*
* utility routines used by various signal handlers
* pending handler before calling it. Trust the handler to finish
* with the siginfo before enabling interrupts. */
void (*pending_handler) (int, siginfo_t*, void*)=data->pending_handler;
- os_context_t *context = arch_os_get_context(&v_context);
data->pending_handler=0;
(*pending_handler)(data->pending_signal,&(data->pending_info), v_context);
struct thread *thread=arch_os_get_current_thread();
sigset_t ss;
- if ((arch_pseudo_atomic_atomic(context) ||
+ if ((arch_pseudo_atomic_atomic(context) ||
SymbolValue(GC_INHIBIT,thread) != NIL)) {
SetSymbolValue(STOP_FOR_GC_PENDING,T,thread);
if (SymbolValue(GC_INHIBIT,thread) == NIL)
else{
void *badaddr=arch_get_bad_addr(signal,info,context);
return (badaddr >= (void *)current_auto_gc_trigger &&
- badaddr <((void *)current_dynamic_space + DYNAMIC_SPACE_SIZE));
+ badaddr <((void *)current_dynamic_space + dynamic_space_size));
}
}
#endif
#elif defined(LISP_FEATURE_X86_64)
u64 *sp=(u64 *)*os_context_register_addr(context,reg_RSP);
+
/* return address for call_into_lisp: */
*(sp-18) = (u64)post_signal_tramp;
* outer context.
*/
#ifndef LISP_FEATURE_WIN32
- if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL)
+ if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL) {
thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
-#ifdef LISP_FEATURE_SB_THREAD
- else {
- 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);
+ check_gc_signals_unblocked_or_lose();
}
-#endif
+ else
+ unblock_gc_signals();
#endif
funcall0(SymbolFunction(SUB_GC));
-
undo_fake_foreign_function_call(context);
return 1;
}
sigset_t empty, current;
int i;
sigemptyset(&empty);
- sigprocmask(SIG_BLOCK, &empty, ¤t);
+ thread_sigmask(SIG_BLOCK, &empty, ¤t);
/* There should be exactly two blocked signals: the two we added
* to sa_mask when setting up the handler. NetBSD doesn't block
* the signal we're handling when SA_NODEFER is set; Linux before
{
sigset_t empty;
sigemptyset(&empty);
- sigprocmask(SIG_SETMASK, &empty, 0);
+ thread_sigmask(SIG_SETMASK, &empty, 0);
}
kill(getpid(), SA_NODEFER_TEST_KILL_SIGNAL);
while (sigaction_nodefer_works == -1);
SHOW("returning from interrupt_init()");
#endif
}
+
+#ifndef LISP_FEATURE_WIN32
+int
+siginfo_code(siginfo_t *info)
+{
+ return info->si_code;
+}
+os_vm_address_t current_memory_fault_address;
+
+void
+lisp_memory_fault_error(os_context_t *context, os_vm_address_t addr)
+{
+ /* FIXME: This is lossy: if we get another memory fault (eg. from
+ * another thread) before lisp has read this, we the information.
+ * However, since this is mostly informative, we'll live with that for
+ * now -- some address is better then no address in this case.
+ */
+ current_memory_fault_address = addr;
+ arrange_return_to_lisp_function(context, SymbolFunction(MEMORY_FAULT_ERROR));
+}
+#endif