smp: Add SIGALRM distributor.
authorMatt Birkholz <puck@birchwood-abbey.net>
Sat, 20 Dec 2014 18:13:30 +0000 (11:13 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Sun, 21 Dec 2014 19:19:09 +0000 (12:19 -0700)
src/microcode/ossmp.h
src/microcode/prossmp.c
src/microcode/uxsig.c

index a51d0004dc2b28411364d98867f8619277c1f74e..47185bbef5ed0b606a05483895b422872b59e3d2 100644 (file)
@@ -70,8 +70,9 @@ extern void smp_gc_start (void);
 extern bool smp_gc_started (void);
 extern void smp_gc_finished (void);
 
-extern void smp_kill_gc (pthread_t);
-extern void smp_kill_timer (pthread_t);
+extern void smp_kill_gc (processor_t *);
+extern void smp_kill_timer (processor_t *);
+extern void smp_timer_interrupt (void);
 
 #endif
 
index 707229d465ec58a630ff55d3e5aaefeba1b16aaa..52be57ccc59595049cf2d1b403960b0e1b3c5276 100644 (file)
@@ -368,7 +368,7 @@ interrupt_others (void)
     if (p != self && p->state != PROCESSOR_GC_WAIT)
       {
        trace (";%d sending SIGUSR2 to pthread %#x", self->id, p->pthread);
-       smp_kill_gc (p->pthread);
+       smp_kill_gc (p);
       }
 }
 
@@ -550,7 +550,7 @@ Send a timer interrupt to processor ID.")
     for (p = processors; p != NULL; p = p->next)
       if (p->id == id)
        {
-         smp_kill_timer (p->pthread);
+         smp_kill_timer (p);
          PRIMITIVE_RETURN (UNSPECIFIC);
        }
     outf_error_line (";%d smp-wake: bogus processor id %d", self->id, id);
index 0d839f953a7efd2d1038b8ef970c3a7c7cde4df1..8f061cbf89a683e62126f6add7b76a61399943eb 100644 (file)
@@ -507,6 +507,7 @@ DEFUN_STD_HANDLER (sighnd_console_resize,
 })
 
 #ifdef ENABLE_SMP
+#include <pthread.h>
 
 static
 DEFUN_STD_HANDLER (sighnd_global_gc,
@@ -515,15 +516,67 @@ DEFUN_STD_HANDLER (sighnd_global_gc,
 })
 
 void
-smp_kill_gc (pthread_t thread)
+smp_kill_gc (processor_t *p)
 {
-  pthread_kill (thread, SIGUSR2);
+  pthread_kill (p->pthread, SIGUSR2);
 }
 
+static volatile processor_t *next_timer = NULL;
+static pthread_mutex_t nt_mutex = PTHREAD_MUTEX_INITIALIZER;
+#ifdef ENABLE_DEBUGGING_TOOLS
+#  define LOCK_NT() do                                                 \
+{                                                                      \
+  int err = pthread_mutex_lock (&nt_mutex);                            \
+  assert (err == 0);                                                   \
+} while (false)
+#  define UNLOCK_NT() do                                               \
+{                                                                      \
+  int err = pthread_mutex_unlock (&nt_mutex);                          \
+  assert (err == 0);                                                   \
+} while (false)
+#else
+#  define LOCK_NT() do                                                 \
+{                                                                      \
+  int err = pthread_mutex_lock (&nt_mutex);                            \
+  if (err)                                                             \
+    error_with_argument (err);                                         \
+} while (false)
+#  define UNLOCK_NT() do                                               \
+{                                                                      \
+  int err = pthread_mutex_unlock (&nt_mutex);                          \
+  if (err)                                                             \
+    error_with_argument (err);                                         \
+} while (false)
+#endif
+
 void
-smp_kill_timer (pthread_t thread)
+smp_kill_timer (processor_t *p)
 {
-  pthread_kill (thread, SIGALRM);
+  block_signals ();
+  LOCK_NT();
+  next_timer = p;
+  pthread_kill (p->pthread, SIGALRM);
+  UNLOCK_NT();
+  unblock_signals ();
+}
+
+void
+smp_timer_interrupt (void)
+{
+  volatile processor_t *p;
+
+  LOCK_NT();
+  p = next_timer;
+  if (p == NULL)
+    p = processors;
+  if (p == self)
+    {
+      request_timer_interrupt ();
+      next_timer = p->next;
+    }
+  else
+    pthread_kill (p->pthread, SIGALRM);
+  UNLOCK_NT();
 }
 
 #endif /* ENABLE_SMP */
@@ -537,7 +590,11 @@ smp_kill_timer (pthread_t thread)
 static
 DEFUN_STD_HANDLER (sighnd_timer,
 {
+#ifndef ENABLE_SMP
   request_timer_interrupt ();
+#else
+  smp_timer_interrupt ();
+#endif
 })
 
 #else /* not HAVE_SETITIMER */
@@ -548,7 +605,11 @@ static
 DEFUN_STD_HANDLER (sighnd_timer,
 {
   reschedule_alarm ();
+#ifndef ENABLE_SMP
   request_timer_interrupt ();
+#else
+  smp_timer_interrupt ();
+#endif
 })
 
 #endif /* not HAVE_SETITIMER */