1.0.25.28: always use SIG_RESUME_FROM_GC
authorGabor Melis <mega@hotpop.com>
Mon, 16 Feb 2009 21:42:05 +0000 (21:42 +0000)
committerGabor Melis <mega@hotpop.com>
Mon, 16 Feb 2009 21:42:05 +0000 (21:42 +0000)
The other mechanism relied on real time signals which made it freeze
when the sysystem wide real time signal queue got full on Linux. A
full queue spells trouble for other processes using rt signals.

All platforms are changed to use SIGUSR1 and SIGUSR2 for
SIG_STOP_FOR_GC and SIG_RESUME_FROM_GC.

Check that SIG_RESUME_FROM_GC is never signalled without a
corresponding sigwait.

src/runtime/bsd-os.c
src/runtime/interrupt.c
src/runtime/interrupt.h
src/runtime/linux-os.c
src/runtime/linux-os.h
src/runtime/sunos-os.c
src/runtime/sunos-os.h
src/runtime/thread.c
src/runtime/win32-os.h
version.lisp-expr

index e31048a..c5e3e4e 100644 (file)
@@ -257,10 +257,8 @@ os_install_interrupt_handlers(void)
                                                  interrupt_thread_handler);
     undoably_install_low_level_interrupt_handler(SIG_STOP_FOR_GC,
                                                  sig_stop_for_gc_handler);
-#ifdef SIG_RESUME_FROM_GC
     undoably_install_low_level_interrupt_handler(SIG_RESUME_FROM_GC,
-                                                 sig_stop_for_gc_handler);
-#endif
+                                                 sig_resume_from_gc_handler);
 #endif
     SHOW("leaving os_install_interrupt_handlers()");
 }
index 9e4bfff..cdd7b24 100644 (file)
@@ -105,25 +105,18 @@ sigaddset_deferrable(sigset_t *s)
     sigaddset(s, SIGPROF);
     sigaddset(s, SIGWINCH);
 
-#if !((defined(LISP_FEATURE_DARWIN) || defined(LISP_FEATURE_FREEBSD)) && defined(LISP_FEATURE_SB_THREAD))
-    sigaddset(s, SIGUSR1);
-    sigaddset(s, SIGUSR2);
-#endif
-
 #ifdef LISP_FEATURE_SB_THREAD
     sigaddset(s, SIG_INTERRUPT_THREAD);
 #endif
 }
 
 void
-sigaddset_blockable(sigset_t *s)
+sigaddset_blockable(sigset_t *sigset)
 {
-    sigaddset_deferrable(s);
+    sigaddset_deferrable(sigset);
 #ifdef LISP_FEATURE_SB_THREAD
-#ifdef SIG_RESUME_FROM_GC
-    sigaddset(s, SIG_RESUME_FROM_GC);
-#endif
-    sigaddset(s, SIG_STOP_FOR_GC);
+    sigaddset(sigset,SIG_RESUME_FROM_GC);
+    sigaddset(sigset,SIG_STOP_FOR_GC);
 #endif
 }
 
@@ -876,23 +869,15 @@ sig_stop_for_gc_handler(int signal, siginfo_t *info, void *void_context)
     FSHOW_SIGNAL((stderr,"suspended\n"));
 
     sigemptyset(&ss);
-#if defined(SIG_RESUME_FROM_GC)
     sigaddset(&ss,SIG_RESUME_FROM_GC);
-#else
-    sigaddset(&ss,SIG_STOP_FOR_GC);
-#endif
 
     /* It is possible to get SIGCONT (and probably other non-blockable
      * signals) here. */
-#ifdef SIG_RESUME_FROM_GC
     {
         int sigret;
         do { sigwait(&ss, &sigret); }
         while (sigret != SIG_RESUME_FROM_GC);
     }
-#else
-    while (sigwaitinfo(&ss,0) != SIG_STOP_FOR_GC);
-#endif
 
     FSHOW_SIGNAL((stderr,"resumed\n"));
     if(thread->state!=STATE_RUNNING) {
@@ -902,6 +887,13 @@ sig_stop_for_gc_handler(int signal, siginfo_t *info, void *void_context)
 
     undo_fake_foreign_function_call(context);
 }
+
+void
+sig_resume_from_gc_handler(int signal, siginfo_t *info, void *void_context)
+{
+    lose("SIG_RESUME_FROM_GC handler called.");
+}
+
 #endif
 
 void
index 210579b..36b9720 100644 (file)
@@ -103,6 +103,7 @@ extern void do_pending_interrupt(void);
 #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_resume_from_gc_handler(int, siginfo_t*, void*);
 #endif
 typedef void (*interrupt_handler_t)(int, siginfo_t *, void *);
 extern void undoably_install_low_level_interrupt_handler (
index 4a3f994..8bd86f1 100644 (file)
@@ -422,6 +422,8 @@ os_install_interrupt_handlers(void)
                                                  interrupt_thread_handler);
     undoably_install_low_level_interrupt_handler(SIG_STOP_FOR_GC,
                                                  sig_stop_for_gc_handler);
+    undoably_install_low_level_interrupt_handler(SIG_RESUME_FROM_GC,
+                                                 sig_resume_from_gc_handler);
 #endif
 }
 
index cfeaed4..8b74848 100644 (file)
@@ -40,5 +40,5 @@ typedef int os_vm_prot_t;
 #define SIG_MEMORY_FAULT SIGSEGV
 
 #define SIG_INTERRUPT_THREAD (SIGRTMIN)
-#define SIG_STOP_FOR_GC (SIGRTMIN+1)
-
+#define SIG_STOP_FOR_GC (SIGUSR1)
+#define SIG_RESUME_FROM_GC (SIGUSR2)
index 8d8bb28..bf8e4ec 100644 (file)
@@ -238,6 +238,8 @@ os_install_interrupt_handlers()
                                                  interrupt_thread_handler);
     undoably_install_low_level_interrupt_handler(SIG_STOP_FOR_GC,
                                                  sig_stop_for_gc_handler);
+    undoably_install_low_level_interrupt_handler(SIG_RESUME_FROM_GC,
+                                                 sig_resume_from_gc_handler);
 #endif
 }
 
index 95212e2..6720c31 100644 (file)
@@ -33,8 +33,8 @@ typedef int os_vm_prot_t;
 #define SIG_MEMORY_FAULT SIGSEGV
 
 #define SIG_INTERRUPT_THREAD (SIGRTMIN)
-#define SIG_STOP_FOR_GC (SIGRTMIN+1)
-#define SIG_RESUME_FROM_GC (SIGRTMIN+2)
+#define SIG_STOP_FOR_GC (SIGUSR1)
+#define SIG_RESUME_FROM_GC (SIGUSR2)
 
 /* Yaargh?! */
 typedef int os_context_register_t ;
index 69a32b3..ae2f990 100644 (file)
@@ -668,21 +668,13 @@ void gc_start_the_world()
                           p->os_thread));
             p->state=STATE_RUNNING;
 
-#if defined(SIG_RESUME_FROM_GC)
             status=kill_thread_safely(p->os_thread,SIG_RESUME_FROM_GC);
-#else
-            status=kill_thread_safely(p->os_thread,SIG_STOP_FOR_GC);
-#endif
             if (status) {
                 lose("cannot resume thread=%lu: %d, %s\n",
                      p->os_thread,status,strerror(status));
             }
         }
     }
-    /* If we waited here until all threads leave STATE_SUSPENDED, then
-     * SIG_STOP_FOR_GC wouldn't need to be a rt signal. That has some
-     * performance implications, but does away with the 'rt signal
-     * queue full' problem. */
 
     lock_ret = pthread_mutex_unlock(&all_threads_lock);
     gc_assert(lock_ret == 0);
index 1526e8d..f08a784 100644 (file)
@@ -37,6 +37,7 @@ typedef void *siginfo_t;
 
 #define SIG_INTERRUPT_THREAD (SIGRTMIN)
 #define SIG_STOP_FOR_GC (SIGRTMIN+1)
+#define SIG_RESUME_FROM_GC (SIGRTMIN+4)
 #define SIG_DEQUEUE (SIGRTMIN+2)
 #define SIG_THREAD_EXIT (SIGRTMIN+3)
 
index 8c4d00c..575dff3 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.25.27"
+"1.0.25.28"