Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 32965)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 32966)
@@ -503,4 +503,6 @@
 	generic/RTLogWriteDebugger-generic.cpp \
 	generic/RTProcDaemonize-generic.cpp \
+ 	generic/RTSemEventMultiWait-2-ex-generic.cpp \
+ 	generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
 	generic/RTTimeLocalNow-generic.cpp \
 	generic/RTTimerCreate-generic.cpp \
@@ -545,6 +547,4 @@
  	r3/linux/semeventmulti-linux.cpp \
  	r3/linux/semmutex-linux.cpp
-# 	generic/RTSemEventMultiWait-2-ex-generic.cpp \
-# 	generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
 else
  RuntimeR3_SOURCES.linux.x86 += \
@@ -555,6 +555,4 @@
  	r3/linux/semevent-linux.cpp \
  	r3/linux/semeventmulti-linux.cpp
-# 	generic/RTSemEventMultiWait-2-ex-generic.cpp \
-# 	generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
  ifdef RT_NEW_LINUX_MUTEX_CODE
   RuntimeR3_SOURCES.linux.amd64 += \
@@ -631,4 +629,6 @@
 	generic/RTUuidCreate-generic.cpp \
 	generic/mppresent-generic.cpp \
+ 	generic/RTSemEventMultiWait-2-ex-generic.cpp \
+ 	generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
 	generic/semrw-$(if-expr defined(VBOX_WITH_LOCKLESS_SEMRW),lockless-,)generic.cpp \
 	generic/timer-generic.cpp \
@@ -672,4 +672,6 @@
 	generic/RTFileMove-generic.cpp \
 	generic/RTLogWriteDebugger-generic.cpp \
+ 	generic/RTSemEventMultiWait-2-ex-generic.cpp \
+ 	generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
 	generic/RTSystemQueryDmiString-generic.cpp \
 	generic/RTTimeLocalNow-generic.cpp \
@@ -729,4 +731,6 @@
 	generic/RTProcDaemonize-generic.cpp \
 	generic/RTProcIsRunningByName-generic.cpp \
+ 	generic/RTSemEventMultiWait-2-ex-generic.cpp \
+ 	generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
 	generic/RTTimeLocalNow-generic.cpp \
 	generic/RTTimerCreate-generic.cpp \
Index: /trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp	(revision 32965)
+++ /trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp	(revision 32966)
@@ -36,4 +36,5 @@
 #include <iprt/lockvalidator.h>
 #include <iprt/mem.h>
+#include <iprt/time.h>
 
 #include "internal/strict.h"
@@ -68,4 +69,6 @@
     bool volatile       fEverHadSignallers;
 #endif
+    /** Set if we're using the monotonic clock. */
+    bool                fMonotonicClock;
 };
 
@@ -107,4 +110,13 @@
         if (!rc)
         {
+#if defined(CLOCK_MONOTONIC) \
+ && (   (defined(RT_OS_LINUX) && defined(__USE_XOPEN2K) /** @todo check ancient glibc versions */) \
+     || /** @todo check other platforms */ 0)
+            /* ASSUMES RTTimeSystemNanoTS() == RTTimeNanoTS() == clock_gettime(CLOCK_MONOTONIC). */
+            rc = pthread_condattr_setclock(&CondAttr, CLOCK_MONOTONIC);
+            pThis->fMonotonicClock = rc == 0;
+#else
+            pThis->fMonotonicClock = false;
+#endif
             rc = pthread_cond_init(&pThis->Cond, &CondAttr);
             if (!rc)
@@ -329,92 +341,130 @@
 
 
-static int rtSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies, bool fAutoResume)
-{
-    PCRTLOCKVALSRCPOS pSrcPos = NULL;
-
-    /*
-     * Validate input.
-     */
-    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
-    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
-    uint32_t u32 = pThis->u32State;
-    AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE);
-
-    /*
-     * Timed or indefinite wait?
-     */
-    if (cMillies == RT_INDEFINITE_WAIT)
-    {
-        /* take mutex */
-        int rc = pthread_mutex_lock(&pThis->Mutex);
-        if (rc)
-        {
-            AssertMsgFailed(("Failed to lock event multi sem %p, rc=%d.\n", hEventMultiSem, rc));
-            return RTErrConvertFromErrno(rc);
-        }
-        ASMAtomicIncU32(&pThis->cWaiters);
-
-        for (;;)
-        {
-            /* check state. */
-            if (pThis->u32State == EVENTMULTI_STATE_SIGNALED)
+/**
+ * Handle polling (timeout already expired at the time of the call).
+ *
+ * @returns VINF_SUCCESs, VERR_TIMEOUT, VERR_SEM_DESTROYED.
+ * @param   pThis               The semaphore.
+ */
+DECLINLINE(int) rtSemEventMultiPosixWaitPoll(struct RTSEMEVENTMULTIINTERNAL *pThis)
+{
+    int rc = pthread_mutex_lock(&pThis->Mutex);
+    AssertMsgReturn(!rc, ("Failed to lock event multi sem %p, rc=%d.\n", pThis, rc), RTErrConvertFromErrno(rc));
+
+    uint32_t const u32State = pThis->u32State;
+
+    rc = pthread_mutex_unlock(&pThis->Mutex);
+    AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc)); NOREF(rc);
+
+    return u32State == EVENTMULTI_STATE_SIGNALED
+         ? VINF_SUCCESS
+         : u32State != EVENTMULTI_STATE_UNINITIALIZED
+         ? VERR_TIMEOUT
+         : VERR_SEM_DESTROYED;
+}
+
+
+
+/**
+ * Implemens the indefinite wait.
+ *
+ * @returns See RTSemEventMultiWaitEx.
+ * @param   pThis               The semaphore.
+ * @param   fFlags              See RTSemEventMultiWaitEx.
+ * @param   pSrcPos             The source position, can be NULL.
+ */
+static int rtSemEventMultiPosixWaitIndefinite(struct RTSEMEVENTMULTIINTERNAL *pThis, uint32_t fFlags, PCRTLOCKVALSRCPOS pSrcPos)
+{
+    /* take mutex */
+    int rc = pthread_mutex_lock(&pThis->Mutex);
+    AssertMsgReturn(!rc, ("Failed to lock event multi sem %p, rc=%d.\n", pThis, rc), RTErrConvertFromErrno(rc));
+    ASMAtomicIncU32(&pThis->cWaiters);
+
+    for (;;)
+    {
+        /* check state. */
+        uint32_t const u32State = pThis->u32State;
+        if (u32State != EVENTMULTI_STATE_NOT_SIGNALED)
+        {
+            ASMAtomicDecU32(&pThis->cWaiters);
+            rc = pthread_mutex_unlock(&pThis->Mutex);
+            AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc));
+            return u32State == EVENTMULTI_STATE_SIGNALED
+                 ? VINF_SUCCESS
+                 : VERR_SEM_DESTROYED;
+        }
+
+        /* wait */
+#ifdef RTSEMEVENTMULTI_STRICT
+        RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
+        if (pThis->fEverHadSignallers)
+        {
+            rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
+                                                       RT_INDEFINITE_WAIT, RTTHREADSTATE_EVENT_MULTI, true);
+            if (RT_FAILURE(rc))
             {
                 ASMAtomicDecU32(&pThis->cWaiters);
-                rc = pthread_mutex_unlock(&pThis->Mutex);
-                AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc)); NOREF(rc);
-                return VINF_SUCCESS;
+                pthread_mutex_unlock(&pThis->Mutex);
+                return rc;
             }
-            if (pThis->u32State == EVENTMULTI_STATE_UNINITIALIZED)
-            {
-                rc = pthread_mutex_unlock(&pThis->Mutex);
-                AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc)); NOREF(rc);
-                return VERR_SEM_DESTROYED;
-            }
-
-            /* wait */
-#ifdef RTSEMEVENTMULTI_STRICT
-            RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
-            if (pThis->fEverHadSignallers)
-            {
-                rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
-                                                           cMillies, RTTHREADSTATE_EVENT_MULTI, true);
-                if (RT_FAILURE(rc))
-                {
-                    ASMAtomicDecU32(&pThis->cWaiters);
-                    pthread_mutex_unlock(&pThis->Mutex);
-                    return rc;
-                }
-            }
+        }
 #else
-            RTTHREAD hThreadSelf = RTThreadSelf();
-#endif
-            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
-            rc = pthread_cond_wait(&pThis->Cond, &pThis->Mutex);
-            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
-            if (rc)
-            {
-                AssertMsgFailed(("Failed to wait on event multi sem %p, rc=%d.\n", hEventMultiSem, rc));
-                ASMAtomicDecU32(&pThis->cWaiters);
-                int rc2 = pthread_mutex_unlock(&pThis->Mutex);
-                AssertMsg(!rc2, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc2)); NOREF(rc2);
-                return RTErrConvertFromErrno(rc);
-            }
-        }
-    }
-    else
-    {
-        /*
-         * Get current time and calc end of wait time.
-         */
-        /** @todo Something is braindead here. we're getting occational timeouts after no time has
-         * elapsed on linux 2.6.23. (ata code typically)
-         *
-         * The general problem here is that we're using the realtime clock, i.e. the wall clock
-         * that is subject to ntp updates and user alteration, so we will have to compenstate
-         * for this by using RTTimeMilliTS together with the clock_gettime()/gettimeofday() call.
-         * Joy, oh joy. */
-        struct timespec     ts = {0,0};
+        RTTHREAD hThreadSelf = RTThreadSelf();
+#endif
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
+        rc = pthread_cond_wait(&pThis->Cond, &pThis->Mutex);
+        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
+        if (RT_UNLIKELY(rc))
+        {
+            AssertMsgFailed(("Failed to wait on event multi sem %p, rc=%d.\n", pThis, rc));
+            ASMAtomicDecU32(&pThis->cWaiters);
+            int rc2 = pthread_mutex_unlock(&pThis->Mutex);
+            AssertMsg(!rc2, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc2)); NOREF(rc2);
+            return RTErrConvertFromErrno(rc);
+        }
+    }
+}
+
+
+/**
+ * Implements the timed wait.
+ *
+ * @returns See RTSemEventMultiWaitEx
+ * @param   pThis               The semaphore.
+ * @param   fFlags              See RTSemEventMultiWaitEx.
+ * @param   uTimeout            See RTSemEventMultiWaitEx.
+ * @param   pSrcPos             The source position, can be NULL.
+ */
+static int rtSemEventMultiPosixWaitTimed(struct RTSEMEVENTMULTIINTERNAL *pThis, uint32_t fFlags, uint64_t uTimeout,
+                                         PCRTLOCKVALSRCPOS pSrcPos)
+{
+    /*
+     * Convert uTimeout to a relative value in nano seconds.
+     */
+    if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
+        uTimeout = uTimeout < UINT64_MAX / UINT32_C(1000000) * UINT32_C(1000000)
+                 ? uTimeout * UINT32_C(1000000)
+                 : UINT64_MAX;
+    if (uTimeout == UINT64_MAX) /* unofficial way of indicating an indefinite wait */
+        return rtSemEventMultiPosixWaitIndefinite(pThis, fFlags, pSrcPos);
+
+    uint64_t uAbsTimeout = uTimeout;
+    if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
+    {
+        uint64_t u64Now = RTTimeSystemNanoTS();
+        uTimeout = uTimeout > u64Now ? uTimeout - u64Now : 0;
+    }
+
+    if (uTimeout == 0)
+        return rtSemEventMultiPosixWaitPoll(pThis);
+
+    /*
+     * Get current time and calc end of deadline relative to real time.
+     */
+    struct timespec     ts = {0,0};
+    if (!pThis->fMonotonicClock)
+    {
 #ifdef RT_OS_DARWIN
-        struct timeval      tv = {0,0};
+        struct timeval  tv = {0,0};
         gettimeofday(&tv, NULL);
         ts.tv_sec = tv.tv_sec;
@@ -423,93 +473,139 @@
         clock_gettime(CLOCK_REALTIME, &ts);
 #endif
-        if (cMillies != 0)
-        {
-            ts.tv_nsec += (cMillies % 1000) * 1000000;
-            ts.tv_sec  += cMillies / 1000;
-            if (ts.tv_nsec >= 1000000000)
-            {
-                ts.tv_nsec -= 1000000000;
-                ts.tv_sec++;
-            }
-        }
-
-        /* take mutex */
-        int rc = pthread_mutex_lock(&pThis->Mutex);
-        if (rc)
-        {
-            AssertMsg(rc == ETIMEDOUT, ("Failed to lock event multi sem %p, rc=%d.\n", hEventMultiSem, rc));
-            return RTErrConvertFromErrno(rc);
-        }
-        ASMAtomicIncU32(&pThis->cWaiters);
-
-        for (;;)
-        {
-            /* check state. */
-            if (pThis->u32State == EVENTMULTI_STATE_SIGNALED)
+        struct timespec tsAdd;
+        tsAdd.tv_nsec = uTimeout % UINT32_C(1000000000);
+        tsAdd.tv_sec  = uTimeout / UINT32_C(1000000000);
+        if (   sizeof(ts.tv_sec) < sizeof(uint64_t)
+            && (   uTimeout > UINT64_C(1000000000) * UINT32_MAX
+                || (uint64_t)ts.tv_sec + tsAdd.tv_sec >= UINT32_MAX) )
+            return rtSemEventMultiPosixWaitIndefinite(pThis, fFlags, pSrcPos);
+
+        ts.tv_sec  += tsAdd.tv_sec;
+        ts.tv_nsec += tsAdd.tv_nsec;
+        if (ts.tv_nsec >= 1000000000)
+        {
+            ts.tv_nsec -= 1000000000;
+            ts.tv_sec++;
+        }
+        /* Note! No need to complete uAbsTimeout for RTSEMWAIT_FLAGS_RELATIVE in this path. */
+    }
+    else
+    {
+        /* ASSUMES RTTimeSystemNanoTS() == RTTimeNanoTS() == clock_gettime(CLOCK_MONOTONIC). */
+        if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
+            uAbsTimeout += RTTimeSystemNanoTS();
+        if (   sizeof(ts.tv_sec) < sizeof(uint64_t)
+            && uAbsTimeout > UINT64_C(1000000000) * UINT32_MAX)
+            return rtSemEventMultiPosixWaitIndefinite(pThis, fFlags, pSrcPos);
+        ts.tv_nsec = uAbsTimeout % UINT32_C(1000000000);
+        ts.tv_sec  = uAbsTimeout / UINT32_C(1000000000);
+    }
+
+    /*
+     * To business!
+     */
+    /* take mutex */
+    int rc = pthread_mutex_lock(&pThis->Mutex);
+    AssertMsgReturn(rc == 0, ("rc=%d pThis=%p\n", rc, pThis), RTErrConvertFromErrno(rc)); NOREF(rc);
+    ASMAtomicIncU32(&pThis->cWaiters);
+
+    for (;;)
+    {
+        /* check state. */
+        uint32_t const u32State = pThis->u32State;
+        if (u32State != EVENTMULTI_STATE_NOT_SIGNALED)
+        {
+            ASMAtomicDecU32(&pThis->cWaiters);
+            rc = pthread_mutex_unlock(&pThis->Mutex);
+            AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc));
+            return u32State == EVENTMULTI_STATE_SIGNALED
+                 ? VINF_SUCCESS
+                 : VERR_SEM_DESTROYED;
+        }
+
+        /* wait */
+#ifdef RTSEMEVENTMULTI_STRICT
+        RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
+        if (pThis->fEverHadSignallers)
+        {
+            rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
+                                                       uTimeout / UINT32_C(1000000), RTTHREADSTATE_EVENT_MULTI, true);
+            if (RT_FAILURE(rc))
             {
                 ASMAtomicDecU32(&pThis->cWaiters);
-                rc = pthread_mutex_unlock(&pThis->Mutex);
-                AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc)); NOREF(rc);
-                return VINF_SUCCESS;
+                pthread_mutex_unlock(&pThis->Mutex);
+                return rc;
             }
-            if (pThis->u32State == EVENTMULTI_STATE_UNINITIALIZED)
-            {
-                rc = pthread_mutex_unlock(&pThis->Mutex);
-                AssertMsg(!rc, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc)); NOREF(rc);
-                return VERR_SEM_DESTROYED;
-            }
-
-            /* we're done if the timeout is 0. */
-            if (!cMillies)
-            {
-                ASMAtomicDecU32(&pThis->cWaiters);
-                rc = pthread_mutex_unlock(&pThis->Mutex);
-                return VERR_TIMEOUT;
-            }
-
-            /* wait */
-#ifdef RTSEMEVENTMULTI_STRICT
-            RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
-            if (pThis->fEverHadSignallers)
-            {
-                rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
-                                                           cMillies, RTTHREADSTATE_EVENT_MULTI, true);
-                if (RT_FAILURE(rc))
-                {
-                    ASMAtomicDecU32(&pThis->cWaiters);
-                    pthread_mutex_unlock(&pThis->Mutex);
-                    return rc;
-                }
-            }
+        }
 #else
-            RTTHREAD hThreadSelf = RTThreadSelf();
-#endif
-            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
-            rc = pthread_cond_timedwait(&pThis->Cond, &pThis->Mutex, &ts);
-            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
-            if (rc && (rc != EINTR || !fAutoResume)) /* according to SuS this function shall not return EINTR, but linux man page says differently. */
-            {
-                AssertMsg(rc == ETIMEDOUT, ("Failed to wait on event multi sem %p, rc=%d.\n", hEventMultiSem, rc));
-                ASMAtomicDecU32(&pThis->cWaiters);
-                int rc2 = pthread_mutex_unlock(&pThis->Mutex);
-                AssertMsg(!rc2, ("Failed to unlock event multi sem %p, rc=%d.\n", hEventMultiSem, rc2)); NOREF(rc2);
-                return RTErrConvertFromErrno(rc);
-            }
-        }
-    }
-}
-
-
-RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
-{
-    int rc = rtSemEventMultiWait(hEventMultiSem, cMillies, true);
-    Assert(rc != VERR_INTERRUPTED);
-    return rc;
-}
-
-
-RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
-{
-    return rtSemEventMultiWait(hEventMultiSem, cMillies, false);
+        RTTHREAD hThreadSelf = RTThreadSelf();
+#endif
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
+        rc = pthread_cond_timedwait(&pThis->Cond, &pThis->Mutex, &ts);
+        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
+        if (    rc
+            && (   rc != EINTR  /* according to SuS this function shall not return EINTR, but linux man page says differently. */
+                || (fFlags & RTSEMWAIT_FLAGS_NORESUME)) )
+        {
+            AssertMsg(rc == ETIMEDOUT, ("Failed to wait on event multi sem %p, rc=%d.\n", pThis, rc));
+            ASMAtomicDecU32(&pThis->cWaiters);
+            int rc2 = pthread_mutex_unlock(&pThis->Mutex);
+            AssertMsg(!rc2, ("Failed to unlock event multi sem %p, rc=%d.\n", pThis, rc2)); NOREF(rc2);
+            return RTErrConvertFromErrno(rc);
+        }
+
+        /* check the absolute deadline. */
+    }
+}
+
+
+DECLINLINE(int) rtSemEventMultiPosixWait(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
+                                         PCRTLOCKVALSRCPOS pSrcPos)
+{
+    /*
+     * Validate input.
+     */
+    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    uint32_t u32 = pThis->u32State;
+    AssertReturn(u32 == EVENTMULTI_STATE_NOT_SIGNALED || u32 == EVENTMULTI_STATE_SIGNALED, VERR_INVALID_HANDLE);
+    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
+
+    /*
+     * Optimize the case where the event is signalled.
+     */
+    if (ASMAtomicUoReadU32(&pThis->u32State) == EVENTMULTI_STATE_SIGNALED)
+    {
+        int rc = rtSemEventMultiPosixWaitPoll(pThis);
+        if (RT_LIKELY(rc != VERR_TIMEOUT))
+            return rc;
+    }
+
+    /*
+     * Indefinite or timed wait?
+     */
+    if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
+        return rtSemEventMultiPosixWaitIndefinite(pThis, fFlags, pSrcPos);
+    return rtSemEventMultiPosixWaitTimed(pThis, fFlags, uTimeout, pSrcPos);
+}
+
+
+#undef RTSemEventMultiWaitEx
+RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
+{
+#ifndef RTSEMEVENT_STRICT
+    return rtSemEventMultiPosixWait(hEventMultiSem, fFlags, uTimeout, NULL);
+#else
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
+    return rtSemEventMultiPosixWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
+#endif
+}
+
+
+RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
+                                        RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
+    return rtSemEventMultiPosixWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
 }
 
Index: /trunk/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp	(revision 32965)
+++ /trunk/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp	(revision 32966)
@@ -53,9 +53,9 @@
 
     uint64_t u64 = RTTimeSystemMilliTS();
-    RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, 1000), VERR_TIMEOUT, rcCheck);
+    RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, 1000), VERR_TIMEOUT);
     u64 = RTTimeSystemMilliTS() - u64;
     RTTEST_CHECK_MSG(g_hTest, u64 < 1500 && u64 > 950, (g_hTest, "u64=%llu\n", u64));
 
-    RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, 2000), VINF_SUCCESS, rcCheck);
+    RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, 2000), VINF_SUCCESS);
     return VINF_SUCCESS;
 }
@@ -65,5 +65,5 @@
 {
     RTSEMEVENTMULTI hSem = *(PRTSEMEVENTMULTI)pvUser;
-    RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS, rcCheck);
+    RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS);
     return VINF_SUCCESS;
 }
@@ -246,5 +246,5 @@
 int main(int argc, char **argv)
 {
-    RTEXITCODE rcExit = RTTestInitAndCreate("tstSemEventMulti", &g_hTest);
+    RTEXITCODE rcExit = RTTestInitAndCreate("tstRTSemEventMulti", &g_hTest);
     if (rcExit != RTEXITCODE_SUCCESS)
         return rcExit;
