#ifdef ENABLE_SMP
#include "option.h"
+#include <errno.h>
+
+/* The chain of processors, starting with processor0 -- main()'s thread: */
+processor_t *processors;
+
+/* The mutex that serializes the thread system. */
+static pthread_mutex_t threads_mutex = MUTEX_INITIALIZER;
+
+/* The processor that owns the threads_mutex. */
+static processor_t *threads_processor = NULL;
+
+/* The current pthread's processor. */
+__thread processor_t *self;
#ifdef ENABLE_DEBUGGING_TOOLS
#endif
+static void
+pthread_error (int code)
+{
+ switch (code)
+ {
+ case EINVAL:
+ outf_error_line (";%d pthread error: invalid", self->id);
+ break;
+ case EDEADLK:
+ outf_error_line (";%d pthread error: deadlock", self->id);
+ break;
+ case EBUSY:
+ outf_error_line (";%d pthread error: busy", self->id);
+ break;
+ case EPERM:
+ outf_error_line (";%d pthread error: permission", self->id);
+ break;
+ default:
+ outf_error_line (";%d pthread error: unknown %d", self->id, code);
+ }
+}
+
+static void make_processors (int);
+
void
setup_processors (int count)
{
trace ("; processor count: %d", option_processor_count);
trace ("; local heap size: %d", option_processor_heap_size);
trace ("; stack size: %d", option_stack_size);
+
+ make_processors (0);
+
+ self = processors;
+ assert (self->id == 0);
+ self->pthread = pthread_self ();
+}
+
+static void
+make_processors (int id)
+{
+ processor_t *new;
+
+ trace (";%d Setup.", id);
+ new = malloc (sizeof (processor_t));
+ if (new == NULL)
+ {
+ outf_fatal ("\n;%d could not malloc processor_t", id);
+ outf_flush_fatal ();
+ Microcode_Termination (TERM_NO_SPACE);
+ }
+ new->next = processors;
+ new->id = id;
+ processors = new;
+
+ if (id > 0)
+ make_processors (id - 1);
}
#endif /* ENABLE_SMP */
+
+DEFINE_PRIMITIVE ("SMP-COUNT", Prim_smp_count, 0, 0, "(SMP-COUNT)\n\
+The number of concurrently running Symmetric Multi-Processors.")
+{
+ PRIMITIVE_HEADER (0);
+ PRIMITIVE_RETURN (SHARP_F);
+}
+
+DEFINE_PRIMITIVE ("SMP-ID", Prim_smp_id, 0, 0, "(SMP-ID)\n\
+A fixnum identifying the current processor.")
+{
+ PRIMITIVE_HEADER (0);
+#ifdef ENABLE_SMP
+ PRIMITIVE_RETURN (LONG_TO_FIXNUM (self->id));
+#else
+ PRIMITIVE_RETURN (FIXNUM_ZERO);
+#endif
+}
+
+DEFINE_PRIMITIVE ("SMP-LOCK-THREADS", Prim_smp_lock_threads, 1, 1,
+ "(SMP-LOCK-THREADS LOCK?)\n\
+When LOCK? is #F/non-#F, unlock/lock the pthread mutex serializing\n\
+access to the thread system.")
+{
+ PRIMITIVE_HEADER (1);
+#ifdef ENABLE_SMP
+ if ((ARG_REF (1)) == SHARP_F)
+ {
+ assert (self == threads_processor);
+ threads_processor = NULL;
+ mutex_unlock (&threads_mutex);
+ PRIMITIVE_RETURN (UNSPECIFIC);
+ }
+ else
+ {
+ mutex_lock (&threads_mutex);
+ threads_processor = self;
+ PRIMITIVE_RETURN (UNSPECIFIC);
+ }
+#else /* not ENABLE_SMP */
+ PRIMITIVE_RETURN (UNSPECIFIC);
+#endif
+}