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
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);
}
}
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);
})
#ifdef ENABLE_SMP
+#include <pthread.h>
static
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 */
static
DEFUN_STD_HANDLER (sighnd_timer,
{
+#ifndef ENABLE_SMP
request_timer_interrupt ();
+#else
+ smp_timer_interrupt ();
+#endif
})
#else /* not HAVE_SETITIMER */
DEFUN_STD_HANDLER (sighnd_timer,
{
reschedule_alarm ();
+#ifndef ENABLE_SMP
request_timer_interrupt ();
+#else
+ smp_timer_interrupt ();
+#endif
})
#endif /* not HAVE_SETITIMER */