Serialize the outf functions.
authorMatt Birkholz <puck@birchwood-abbey.net>
Thu, 23 Jul 2015 23:25:01 +0000 (16:25 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Thu, 26 Nov 2015 08:09:45 +0000 (01:09 -0700)
src/microcode/outf.c

index 7ba8563706952713f6f7ac50d75b69013c24db75..211a6c9fe5053ba0a448b463348e4b4c78d9f0da 100644 (file)
@@ -40,7 +40,7 @@ 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 "outf.h"
 
 #ifdef __WIN32__
@@ -245,48 +245,89 @@ outf_flush_fatal (void)
 \f
 #ifndef OUTF_VARIANTS_DEFINED
 
+#ifdef ENABLE_SMP
+static pthread_mutex_t stderr_mutex = MUTEX_INITIALIZER;
+static pthread_mutex_t stdout_mutex = MUTEX_INITIALIZER;
+#define LOCKN(which) mutex_lock_noerr (which)
+#define UNLOCKN(which) mutex_unlock_noerr (which)
+
+static void
+mutex_lock_noerr (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_noerr (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 LOCKN(which)
+#define UNLOCKN(which)
+#endif
+
 void
 voutf_console (const char * format, va_list args)
 {
+  LOCKN (&stdout_mutex);
   vfprintf (stdout, format, args);
+  UNLOCKN (&stdout_mutex);
 }
 
 void
 outf_flush_console (void)
 {
+  LOCKN (&stdout_mutex);
   fflush (stdout);
+  UNLOCKN (&stdout_mutex);
 }
 
 void
 voutf_error (const char * format, va_list args)
 {
+  LOCKN (&stderr_mutex);
   vfprintf (stderr, format, args);
+  UNLOCKN (&stderr_mutex);
 }
 
 void
 outf_flush_error (void)
 {
+  LOCKN (&stderr_mutex);
   fflush (stderr);
+  UNLOCKN (&stderr_mutex);
 }
 
 void
 voutf_error_line (const char * format, va_list args)
 {
+  LOCKN (&stderr_mutex);
   vfprintf (stderr, format, args);
   fputc ('\n', stderr);
   fflush (stderr);
+  UNLOCKN (&stderr_mutex);
 }
 
 void
 voutf_fatal (const char * format, va_list args)
 {
+  LOCKN (&stderr_mutex);
   vfprintf (stderr, format, args);
+  UNLOCKN (&stderr_mutex);
 }
 
 void
 outf_flush_fatal (void)
 {
+  LOCKN (&stderr_mutex);
   fflush (stderr);
+  UNLOCKN (&stderr_mutex);
 }
 
 #endif /* not OUTF_VARIANTS_DEFINED */