Index: trunk/src/emx/include/sys/fmutex.h
===================================================================
--- trunk/src/emx/include/sys/fmutex.h	(revision 2023)
+++ trunk/src/emx/include/sys/fmutex.h	(revision 2027)
@@ -6,9 +6,10 @@
 
 #ifndef _SYS_FMUTEX_H
-    #define _SYS_FMUTEX_H
+#define _SYS_FMUTEX_H
 
-    #include <sys/cdefs.h>
-    #include <stdlib.h> /* need abort */
-    #include <InnoTekLIBC/FastInfoBlocks.h>
+#include <sys/cdefs.h>
+#include <stdlib.h> /* need abort */
+#include <InnoTekLIBC/FastInfoBlocks.h>
+#include <386/builtin.h>
 
 __BEGIN_DECLS
@@ -16,24 +17,25 @@
 /* Constants for _fmutex.fs.  See _fmutex_available() for ordering. */
 
-    #define _FMS_UNINIT       0
-    #define _FMS_AVAILABLE    1
-    #define _FMS_OWNED_SIMPLE 2
-    #define _FMS_OWNED_HARD   3
+#define _FMS_AUTO_INITIALIZE    (-1)
+#define _FMS_UNINIT       0
+#define _FMS_AVAILABLE    1
+#define _FMS_OWNED_SIMPLE 2
+#define _FMS_OWNED_HARD   3
 
 /* Constants for _fmutex_create() */
 
-    #define _FMC_SHARED         0x01
-    #define _FMC_MUST_COMPLETE  0x02
-    #define _FMC_DUMMY          0x04    /* internal */
+#define _FMC_SHARED         0x01
+#define _FMC_MUST_COMPLETE  0x02
+#define _FMC_DUMMY          0x04    /* internal */
 
 /* Constants for _fmutex_request() */
 
-    #define _FMR_IGNINT     0x01
-    #define _FMR_NOWAIT     0x02
+#define _FMR_IGNINT     0x01
+#define _FMR_NOWAIT     0x02
 
 /* We cannot use __attribute__ ((__packed__)) because G++ does not
    support this. */
 
-    #pragma pack(1)
+#pragma pack(1)
 typedef struct
 {
@@ -51,6 +53,8 @@
     const char             *pszDesc;
 } _fmutex;
-    #pragma pack()
+#pragma pack()
 
+#define _FMUTEX_INITIALIZER                         _FMUTEX_INITIALIZER_EX(0, __FILE__)
+#define _FMUTEX_INITIALIZER_EX(fFlags, pszDesc)     { 0, _FMS_AUTO_INITIALIZE, fFlags, {0x42,0x42}, 0, pszDesc }
 
 
Index: trunk/src/emx/src/lib/process/fmutex.c
===================================================================
--- trunk/src/emx/src/lib/process/fmutex.c	(revision 2023)
+++ trunk/src/emx/src/lib/process/fmutex.c	(revision 2027)
@@ -45,5 +45,5 @@
     sem->flags      = flags;
     sem->padding[0] = 'f';
-    sem->padding[0] = 'm';
+    sem->padding[1] = 'm';
     sem->pszDesc    = pszDesc;
     rc = DosCreateEventSemEx(NULL, (PHEV)&sem->hev,
@@ -79,4 +79,24 @@
         LIBC_ASSERTM_FAILED("Invalid handle, fs == _FMS_UNINIT\n");
         LIBCLOG_RETURN_UINT(ERROR_INVALID_HANDLE);
+    }
+
+    if (fs == _FMS_AUTO_INITIALIZE || !sem->hev)
+    {
+        HEV hev;
+        rc = DosCreateEventSemEx(NULL, &hev, sem->flags & _FMC_SHARED ? DC_SEM_SHARED : 0, FALSE);
+        if (rc)
+        {
+            LIBC_ASSERTM_FAILED("Failed to create event semaphore for fmutex '%s', rc=%d. flags=%#x\n", sem->pszDesc, rc, sem->flags);
+            LIBCLOG_RETURN_UINT(ERROR_INVALID_HANDLE);
+        }
+        if (__atomic_cmpxchg32((volatile uint32_t *)&sem->hev, hev, 0))
+        {
+            LIBCLOG_MSG("auto initialized fmutex %p '%s'\n", (void *)sem, sem->pszDesc);
+            __atomic_xchg(&sem->Owner, fibGetTidPid());
+            LIBCLOG_RETURN_UINT(NO_ERROR);
+        }
+        LIBCLOG_MSG("lost auto initialization race for fmutex %p '%s'\n", (void *)sem, sem->pszDesc);
+        DosCloseEventSemEx(hev);
+        fs = _FMS_OWNED_HARD;
     }
 
@@ -160,4 +180,5 @@
     int     rc;
     ULONG   ulNesting = 0;
+    signed char fs;
     FS_VAR();
 
@@ -168,13 +189,43 @@
     }
 
-    FS_SAVE_LOAD();
     DosEnterMustComplete(&ulNesting);
+    fs = __cxchg(&sem->fs, _FMS_OWNED_SIMPLE);
+    if (fs == _FMS_AVAILABLE)
+    {
+        __atomic_xchg(&sem->Owner, fibGetTidPid());
+        FS_RESTORE();
+        LIBCLOG_RETURN_UINT(0);
+    }
+
+    if (fs == _FMS_AUTO_INITIALIZE || !sem->hev)
+    {
+        HEV hev;
+        rc = DosCreateEventSemEx(NULL, &hev, sem->flags & _FMC_SHARED ? DC_SEM_SHARED : 0, FALSE);
+        if (rc)
+        {
+            LIBC_ASSERTM_FAILED("Failed to create event semaphore for fmutex '%s', rc=%d. flags=%#x\n", sem->pszDesc, rc, sem->flags);
+            LIBCLOG_RETURN_UINT(ERROR_INVALID_HANDLE);
+        }
+        if (__atomic_cmpxchg32((volatile uint32_t *)&sem->hev, hev, 0))
+        {
+            LIBCLOG_MSG("auto initialized fmutex %p '%s'\n", (void *)sem, sem->pszDesc);
+            __atomic_xchg(&sem->Owner, fibGetTidPid());
+            LIBCLOG_RETURN_UINT(NO_ERROR);
+        }
+        LIBCLOG_MSG("lost auto initialization race for fmutex %p '%s'\n", (void *)sem, sem->pszDesc);
+        DosCloseEventSemEx(hev);
+        fs = _FMS_OWNED_HARD;
+    }
+
     if (flags & _FMR_NOWAIT)
     {
-        if (__cxchg(&sem->fs, _FMS_OWNED_HARD) == _FMS_AVAILABLE)
-        {
-            __atomic_xchg(&sem->Owner, fibGetTidPid());
-            FS_RESTORE();
-            LIBCLOG_RETURN_UINT(0);
+        if (fs == _FMS_OWNED_HARD)
+        {
+            if (__cxchg(&sem->fs, _FMS_OWNED_HARD) == _FMS_AVAILABLE)
+            {
+                __atomic_xchg(&sem->Owner, fibGetTidPid());
+                FS_RESTORE();
+                LIBCLOG_RETURN_UINT(0);
+            }
         }
         DosExitMustComplete(&ulNesting);
