smp: Serialize the outf functions.
authorMatt Birkholz <puck@birchwood-abbey.net>
Sat, 20 Dec 2014 15:44:05 +0000 (08:44 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Sun, 21 Dec 2014 19:19:09 +0000 (12:19 -0700)
src/microcode/outf.c

index 1a5cc5a9e5e3d48d96f7be633fd1e5cd2dcab340..a5849f9f59bf9d0261f7e5fe198b22b44de7ac1f 100644 (file)
@@ -40,8 +40,12 @@ USA.
    Use outf where you would normally think of using fprintf and
    outf_flush where you would normally use fflush.  */
 
-#include "config.h"
+#include "scheme.h"
+#include "ossmp.h"
 #include "outf.h"
+#ifdef ENABLE_SMP
+#include <pthread.h>
+#endif
 
 #ifdef __WIN32__
 #  include <windows.h>
@@ -245,48 +249,89 @@ outf_flush_fatal (void)
 \f
 #ifndef OUTF_VARIANTS_DEFINED
 
+#ifdef ENABLE_SMP
+static pthread_mutex_t stderr_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t stdout_mutex = PTHREAD_MUTEX_INITIALIZER;
+#define LOCK(which) mutex_lock (which)
+#define UNLOCK(which) mutex_unlock (which)
+
+static void
+mutex_lock (pthread_mutex_t *m)
+{
+  int err = pthread_mutex_lock (m);
+  if (err)
+    outf_error_line (";%d outf mutex lock failed: %d", self->id, err);
+}
+
+static void
+mutex_unlock (pthread_mutex_t *m)
+{
+  int err = pthread_mutex_unlock (m);
+  if (err)
+    outf_error_line (";%d outf mutex unlock failed: %d", self->id, err);
+}
+
+#else
+#define LOCK(which)
+#define UNLOCK(which)
+#endif
+
 void
 voutf_console (const char * format, va_list args)
 {
+  LOCK (&stdout_mutex);
   vfprintf (stdout, format, args);
+  UNLOCK (&stdout_mutex);
 }
 
 void
 outf_flush_console (void)
 {
+  LOCK(&stdout_mutex);
   fflush (stdout);
+  UNLOCK(&stdout_mutex);
 }
 
 void
 voutf_error (const char * format, va_list args)
 {
+  LOCK(&stderr_mutex);
   vfprintf (stderr, format, args);
+  UNLOCK(&stderr_mutex);
 }
 
 void
 outf_flush_error (void)
 {
+  LOCK(&stderr_mutex);
   fflush (stderr);
+  UNLOCK(&stderr_mutex);
 }
 
 void
 voutf_error_line (const char * format, va_list args)
 {
+  LOCK(&stderr_mutex);
   vfprintf (stderr, format, args);
   fputc ('\n', stderr);
   fflush (stderr);
+  UNLOCK(&stderr_mutex);
 }
 
 void
 voutf_fatal (const char * format, va_list args)
 {
+  LOCK(&stderr_mutex);
   vfprintf (stderr, format, args);
+  UNLOCK(&stderr_mutex);
 }
 
 void
 outf_flush_fatal (void)
 {
+  LOCK(&stderr_mutex);
   fflush (stderr);
+  UNLOCK(&stderr_mutex);
 }
 
 #endif /* not OUTF_VARIANTS_DEFINED */