Add SIGALRM distributor.
authorMatt Birkholz <puck@birchwood-abbey.net>
Sun, 19 Jul 2015 16:03:07 +0000 (09:03 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Thu, 26 Nov 2015 08:09:46 +0000 (01:09 -0700)
src/microcode/ossmp.h
src/microcode/uxsig.c

index c141102ddf7a246271e904373242c0c236a6b2d1..da4b85a02843cae1b9b5f85350fd5d70b2ce038d 100644 (file)
@@ -72,6 +72,7 @@ extern void smp_gc_finish (void);
 
 extern void smp_kill_gc (processor_t *);
 extern void smp_kill_timer (processor_t *);
+extern void smp_timer_interrupt (void);
 
 #ifdef ENABLE_DEBUGGING_TOOLS
 
index e00712e9bd8822352f3b5f99c755104f0921d680..1dc7fd303142439bf3ad43f8cfaba6281730bd81 100644 (file)
@@ -519,10 +519,62 @@ smp_kill_gc (processor_t *p)
   pthread_kill (p->pthread, SIGUSR2);
 }
 
+static volatile processor_t *next_timer = NULL;
+static pthread_mutex_t nt_mutex = 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 (processor_t *p)
 {
+  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 */
@@ -536,7 +588,11 @@ smp_kill_timer (processor_t *p)
 static
 DEFUN_STD_HANDLER (sighnd_timer,
 {
+#ifndef ENABLE_SMP
   request_timer_interrupt ();
+#else
+  smp_timer_interrupt ();
+#endif
 })
 
 #else /* not HAVE_SETITIMER */
@@ -547,7 +603,11 @@ static
 DEFUN_STD_HANDLER (sighnd_timer,
 {
   reschedule_alarm ();
+#ifndef ENABLE_SMP
   request_timer_interrupt ();
+#else
+  smp_timer_interrupt ();
+#endif
 })
 
 #endif /* not HAVE_SETITIMER */