-
-#ifndef LISP_FEATURE_GENCGC
-/* This function gets called from the SIGSEGV (for e.g. Linux, NetBSD, &
- * OpenBSD) or SIGBUS (for e.g. FreeBSD) handler. Here we check
- * whether the signal was due to treading on the mprotect()ed zone -
- * and if so, arrange for a GC to happen. */
-extern unsigned long bytes_consed_between_gcs; /* gc-common.c */
-
-boolean
-interrupt_maybe_gc(int signal, siginfo_t *info, void *void_context)
-{
- os_context_t *context=(os_context_t *) void_context;
-
- if(!foreign_function_call_active && gc_trigger_hit(signal, info, context)){
- struct thread *thread=arch_os_get_current_thread();
- clear_auto_gc_trigger();
- /* Don't flood the system with interrupts if the need to gc is
- * already noted. This can happen for example when SUB-GC
- * allocates or after a gc triggered in a WITHOUT-GCING. */
- if (SymbolValue(GC_PENDING,thread) == NIL) {
- if (SymbolValue(GC_INHIBIT,thread) == NIL) {
- if (arch_pseudo_atomic_atomic(context)) {
- /* set things up so that GC happens when we finish
- * the PA section */
- SetSymbolValue(GC_PENDING,T,thread);
- arch_set_pseudo_atomic_interrupted(context);
- } else {
- interrupt_maybe_gc_int(signal,info,void_context);
- }
- } else {
- SetSymbolValue(GC_PENDING,T,thread);
- }
- }
- return 1;
- }
- return 0;
-}
-
-#endif
-
-/* this is also used by gencgc, in alloc() */
-boolean
-interrupt_maybe_gc_int(int signal, siginfo_t *info, void *void_context)
-{
- os_context_t *context=(os_context_t *) void_context;
-#ifndef LISP_FEATURE_WIN32
- struct thread *thread=arch_os_get_current_thread();
-#endif
-
- fake_foreign_function_call(context);
-
- /* SUB-GC may return without GCing if *GC-INHIBIT* is set, in
- * which case we will be running with no gc trigger barrier
- * thing for a while. But it shouldn't be long until the end
- * of WITHOUT-GCING.
- *
- * FIXME: It would be good to protect the end of dynamic space
- * and signal a storage condition from there.
- */
-
- /* Restore the signal mask from the interrupted context before
- * calling into Lisp if interrupts are enabled. Why not always?
- *
- * Suppose there is a WITHOUT-INTERRUPTS block far, far out. If an
- * interrupt hits while in SUB-GC, it is deferred and the
- * os_context_sigmask of that interrupt is set to block further
- * deferrable interrupts (until the first one is
- * handled). Unfortunately, that context refers to this place and
- * when we return from here the signals will not be blocked.
- *
- * A kludgy alternative is to propagate the sigmask change to the
- * outer context.
- */
-#ifndef LISP_FEATURE_WIN32
- 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);
- }
-#endif
-#endif
- funcall0(SymbolFunction(SUB_GC));
-
- undo_fake_foreign_function_call(context);
- return 1;
-}
-