Index: /trunk/src/kmk/job.h
===================================================================
--- /trunk/src/kmk/job.h	(revision 3193)
+++ /trunk/src/kmk/job.h	(revision 3194)
@@ -68,10 +68,18 @@
 /* Public functions emulated/provided in posixfcn.c.  */
 int fcntl (intptr_t fd, int cmd, ...);
+#  ifdef CONFIG_NEW_WIN_CHILDREN
+intptr_t create_mutex (char *mtxname, size_t size);
+#  else
 intptr_t create_mutex (void);
+#  endif
 int same_stream (FILE *f1, FILE *f2);
 
 #  define RECORD_SYNC_MUTEX(m) record_sync_mutex(m)
 void record_sync_mutex (const char *str);
+#  ifdef CONFIG_NEW_WIN_CHILDREN
+void prepare_mutex_handle_string (const char *mtxname);
+#  else
 void prepare_mutex_handle_string (intptr_t hdl);
+#  endif
 # else  /* !WINDOWS32 */
 
Index: /trunk/src/kmk/kmkbuiltin/kSubmit.c
===================================================================
--- /trunk/src/kmk/kmkbuiltin/kSubmit.c	(revision 3193)
+++ /trunk/src/kmk/kmkbuiltin/kSubmit.c	(revision 3194)
@@ -1492,6 +1492,9 @@
         if (pWorker)
         {
-            if (!pszExecutable)
-                pszExecutable = argv[iArg];
+            /* Before we send off the job, we should dump pending output, since
+               the kWorker process currently does not coordinate its output with
+               the output.c mechanics. */
+            if (pCtx->pOut)
+                output_dump(pCtx->pOut);
 
             rcExit = kSubmitSendJobMessage(pCtx, pWorker, pvMsg, cbMsg, 0 /*fNoRespawning*/, cVerbosity);
Index: /trunk/src/kmk/main.c
===================================================================
--- /trunk/src/kmk/main.c	(revision 3193)
+++ /trunk/src/kmk/main.c	(revision 3194)
@@ -478,4 +478,12 @@
   -O[TYPE], --output-sync[=TYPE]\n\
                               Synchronize output of parallel jobs by TYPE.\n"),
+#elif defined(KBUILD_OS_WINDOWS)
+    N_("\
+  -O[TYPE], --output-sync[=TYPE]\n\
+                              Synchronize output of parallel jobs by TYPE:\n\
+                                none    = no synchronization.\n\
+                                line    = receip line output\n\
+                                target  = entire receip output (default)\n\
+                                recurse = entire recursive invocation\n"),
 #else
     N_("\
@@ -730,5 +738,9 @@
    of each job stay together.  */
 
+#if defined(KMK) && defined(KBUILD_OS_WINDOWS)
+int output_sync = OUTPUT_SYNC_TARGET;
+#else
 int output_sync = OUTPUT_SYNC_NONE;
+#endif
 
 /* Nonzero if the "--trace" option was given.  */
@@ -1112,4 +1124,14 @@
    command-line argument.  */
 void
+# ifdef CONFIG_NEW_WIN_CHILDREN
+prepare_mutex_handle_string (const char *mtxname)
+{
+  if (!sync_mutex)
+    {
+      sync_mutex = xstrdup(mtxname);
+      define_makeflags (1, 0);
+    }
+}
+# else
 prepare_mutex_handle_string (sync_handle_t handle)
 {
@@ -1123,4 +1145,5 @@
     }
 }
+# endif
 
 #endif  /* NO_OUTPUT_SYNC */
Index: /trunk/src/kmk/output.c
===================================================================
--- /trunk/src/kmk/output.c	(revision 3193)
+++ /trunk/src/kmk/output.c	(revision 3194)
@@ -94,7 +94,9 @@
       void *sem = acquire_semaphore ();
 
+# ifndef KMK /* this drives me bananas. */
       /* Log the working directory for this dump.  */
       if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
         traced = log_working_directory (1);
+# endif
 
       /* Work the out and err sequences in parallel. */
@@ -124,15 +126,17 @@
             fflush(prevdst);
           prevdst = dst;
-#ifdef KBUILD_OS_WINDOWS
+# ifdef KBUILD_OS_WINDOWS
           maybe_con_fwrite (src, len, 1, dst);
-#else
+# else
           fwrite (src, len, 1, dst);
-#endif
+# endif
         }
       if (prevdst)
         fflush (prevdst);
 
+# ifndef KMK /* this drives me bananas. */
       if (traced)
         log_working_directory (0);
+# endif
 
       /* Exit the critical section.  */
@@ -599,4 +603,26 @@
 
 #ifdef WINDOWS32
+# ifdef CONFIG_NEW_WIN_CHILDREN
+  if (STREAM_OK (stdout))
+    {
+      if (STREAM_OK (stderr))
+        {
+          char mtxname[256];
+          sync_handle = create_mutex (mtxname, sizeof (mtxname));
+          if (sync_handle != -1)
+            {
+              prepare_mutex_handle_string (mtxname);
+              return same_stream (stdout, stderr);
+            }
+          perror_with_name ("output-sync suppressed: ", "create_mutex");
+        }
+      else
+        perror_with_name ("output-sync suppressed: ", "stderr");
+    }
+  else
+    perror_with_name ("output-sync suppressed: ", "stdout");
+  output_sync = OUTPUT_SYNC_NONE;
+
+# else  /* !CONFIG_NEW_WIN_CHILDREN */
   if ((!STREAM_OK (stdout) && !STREAM_OK (stderr))
       || (sync_handle = create_mutex ()) == -1)
@@ -610,4 +636,5 @@
       prepare_mutex_handle_string (sync_handle);
     }
+# endif /* !CONFIG_NEW_WIN_CHILDREN */
 
 #else
@@ -1032,7 +1059,14 @@
 #endif
 
+#ifndef KMK
   /* If we're not syncing this output per-line or per-target, make sure we emit
      the "Entering..." message where appropriate.  */
   if (output_sync == OUTPUT_SYNC_NONE || output_sync == OUTPUT_SYNC_RECURSE)
+#else
+  /* Indiscriminately output "Entering..." and "Leaving..." message for each
+     command line or target is plain annoying!  And when there is no recursion
+     it's actually inappropriate.   Haven't got a simple way of detecting that,
+     so back to the old behavior for now.  [bird] */
+#endif
     if (! stdio_traced && print_directory_flag)
       stdio_traced = log_working_directory (1);
Index: /trunk/src/kmk/w32/compat/posixfcn.c
===================================================================
--- /trunk/src/kmk/w32/compat/posixfcn.c	(revision 3193)
+++ /trunk/src/kmk/w32/compat/posixfcn.c	(revision 3194)
@@ -154,4 +154,14 @@
 record_sync_mutex (const char *str)
 {
+#ifdef CONFIG_NEW_WIN_CHILDREN
+  HANDLE hmtx = OpenMutexA(SYNCHRONIZE, FALSE /*fInheritable*/, str);
+  if (hmtx)
+    mutex_handle = (intptr_t)hmtx;
+  else
+    {
+      mutex_handle = -1;
+      errno = ENOENT;
+    }
+#else
   char *endp;
   intptr_t hmutex = strtol (str, &endp, 16);
@@ -164,11 +174,18 @@
       errno = EINVAL;
     }
+#endif
 }
 
 /* Create a new mutex or reuse one created by our parent.  */
 intptr_t
+#ifdef CONFIG_NEW_WIN_CHILDREN
+create_mutex (char *mtxname, size_t size)
+#else
 create_mutex (void)
-{
+#endif
+{
+#ifndef CONFIG_NEW_WIN_CHILDREN
   SECURITY_ATTRIBUTES secattr;
+#endif
   intptr_t hmutex = -1;
 
@@ -176,6 +193,18 @@
      that.  */
   if (mutex_handle > 0)
-    return mutex_handle;
-
+    {
+#ifdef CONFIG_NEW_WIN_CHILDREN
+      mtxname[0] = '\0';
+#endif
+      return mutex_handle;
+    }
+
+#ifdef CONFIG_NEW_WIN_CHILDREN
+  /* We're the top-level Make. Child Make processes will open our mutex, since
+     children does not inherit any handles other than the three standard ones. */
+  snprintf(mtxname, size, "Make-output-%u-%u-%u", GetCurrentProcessId(),
+           GetCurrentThreadId(), GetTickCount());
+  hmutex = (intptr_t)CreateMutexA (NULL, FALSE /*Locked*/, mtxname);
+#else
   /* We are the top-level Make, and we want the handle to be inherited
      by our child processes.  */
@@ -185,4 +214,5 @@
 
   hmutex = (intptr_t)CreateMutex (&secattr, FALSE, NULL);
+#endif
   if (!hmutex)
     {
