Index: /trunk/include/iprt/thread.h
===================================================================
--- /trunk/include/iprt/thread.h	(revision 402)
+++ /trunk/include/iprt/thread.h	(revision 403)
@@ -165,5 +165,5 @@
     RTTHREADTYPE_TIMER,
     /** Only used for validation. */
-    RTTHREADTYPE_LAST
+    RTTHREADTYPE_END
 } RTTHREADTYPE;
 
@@ -234,5 +234,44 @@
 RTDECL(int) RTThreadSetType(RTTHREAD Thread, RTTHREADTYPE enmType);
 
-#ifdef IN_RING3
+/**
+ * Wait for the thread to terminate, resume on interruption.
+ *
+ * @returns     iprt status code.
+ *              Will not return VERR_INTERRUPTED.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ * @param       prc             Where to store the return code of the thread. Optional.
+ */
+RTDECL(int) RTThreadWait(RTTHREAD Thread, unsigned cMillies, int *prc);
+
+/**
+ * Wait for the thread to terminate, return on interruption.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ * @param       prc             Where to store the return code of the thread. Optional.
+ */
+RTDECL(int) RTThreadWaitNoResume(RTTHREAD Thread, unsigned cMillies, int *prc);
+
+/**
+ * Gets the name of the current thread thread.
+ *
+ * @returns Pointer to readonly name string.
+ * @returns NULL on failure.
+ */
+RTDECL(const char *) RTThreadSelfName(void);
+
+/**
+ * Gets the name of a thread.
+ *
+ * @returns Pointer to readonly name string.
+ * @returns NULL on failure.
+ * @param   Thread      Thread handle of the thread to query the name of.
+ */
+RTDECL(const char *) RTThreadGetName(RTTHREAD Thread);
+
 /**
  * Gets the type of the specified thread.
@@ -242,5 +281,52 @@
  * @param   Thread      The thread in question.
  */
-RTR3DECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread);
+RTDECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread);
+
+/**
+ * Sets the name of a thread.
+ *
+ * @returns iprt status code.
+ * @param   Thread      Thread handle of the thread to query the name of.
+ * @param   pszName     The thread name.
+ */
+RTDECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName);
+
+/**
+ * Signal the user event.
+ *
+ * @returns     iprt status code.
+ */
+RTDECL(int) RTThreadUserSignal(RTTHREAD Thread);
+
+/**
+ * Wait for the user event.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ */
+RTDECL(int) RTThreadUserWait(RTTHREAD Thread, unsigned cMillies);
+
+/**
+ * Wait for the user event, return on interruption.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to wait for.
+ * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ *                              an indefinite wait.
+ */
+RTDECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, unsigned cMillies);
+
+/**
+ * Reset the user event.
+ *
+ * @returns     iprt status code.
+ * @param       Thread          The thread to reset.
+ */
+RTDECL(int) RTThreadUserReset(RTTHREAD Thread);
+
+
+#ifdef IN_RING3
 
 /**
@@ -256,88 +342,4 @@
 
 /**
- * Gets the name of the current thread thread.
- *
- * @returns Pointer to readonly name string.
- * @returns NULL on failure.
- */
-RTR3DECL(const char *) RTThreadSelfName(void);
-
-/**
- * Gets the name of a thread.
- *
- * @returns Pointer to readonly name string.
- * @returns NULL on failure.
- * @param   Thread      Thread handle of the thread to query the name of.
- */
-RTR3DECL(const char *) RTThreadGetName(RTTHREAD Thread);
-
-/**
- * Sets the name of a thread.
- *
- * @returns iprt status code.
- * @param   Thread      Thread handle of the thread to query the name of.
- * @param   pszName     The thread name.
- */
-RTR3DECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName);
-
-/**
- * Signal the user event.
- *
- * @returns     iprt status code.
- */
-RTR3DECL(int) RTThreadUserSignal(RTTHREAD Thread);
-
-/**
- * Wait for the user event.
- *
- * @returns     iprt status code.
- * @param       Thread          The thread to wait for.
- * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
- *                              an indefinite wait.
- */
-RTR3DECL(int) RTThreadUserWait(RTTHREAD Thread, unsigned cMillies);
-
-/**
- * Wait for the user event, return on interruption.
- *
- * @returns     iprt status code.
- * @param       Thread          The thread to wait for.
- * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
- *                              an indefinite wait.
- */
-RTR3DECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, unsigned cMillies);
-
-/**
- * Reset the user event.
- *
- * @returns     iprt status code.
- * @param       Thread          The thread to reset.
- */
-RTR3DECL(int) RTThreadUserReset(RTTHREAD Thread);
-
-/**
- * Wait for the thread to terminate, resume on interruption.
- *
- * @returns     iprt status code.
- *              Will not return VERR_INTERRUPTED.
- * @param       Thread          The thread to wait for.
- * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
- *                              an indefinite wait.
- * @param       prc             Where to store the return code of the thread. Optional.
- */
-RTR3DECL(int) RTThreadWait(RTTHREAD Thread, unsigned cMillies, int *prc);
-
-/**
- * Wait for the thread to terminate, return on interruption.
- *
- * @returns     iprt status code.
- * @param       Thread          The thread to wait for.
- * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
- *                              an indefinite wait.
- * @param       prc             Where to store the return code of the thread. Optional.
- */
-RTR3DECL(int) RTThreadWaitNoResume(RTTHREAD Thread, unsigned cMillies, int *prc);
-
-/**
  * Gets the affinity mask of the current thread.
  *
Index: /trunk/src/VBox/HostDrivers/Support/SUPDRVShared.c
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDRVShared.c	(revision 402)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDRVShared.c	(revision 403)
@@ -113,7 +113,21 @@
     { "RTSpinlockAcquireNoInts",                (void *)RTSpinlockAcquireNoInts },
     { "RTSpinlockReleaseNoInts",                (void *)RTSpinlockReleaseNoInts },
-    { "RTThreadSelf",                           (void *)RTThreadSelf },
+    { "RTThreadNativeSelf",                     (void *)RTThreadNativeSelf },
     { "RTThreadSleep",                          (void *)RTThreadSleep },
     { "RTThreadYield",                          (void *)RTThreadYield },
+#if 0 /* Thread APIs, Part 2. */
+    { "RTThreadSelf",                           (void *)RTThreadSelf },
+    { "RTThreadCreate",                         (void *)RTThreadCreate },
+    { "RTThreadGetNative",                      (void *)RTThreadGetNative },
+    { "RTThreadWait",                           (void *)RTThreadWait },
+    { "RTThreadWaitNoResume",                   (void *)RTThreadWaitNoResume },
+    { "RTThreadGetName",                        (void *)RTThreadGetName },
+    { "RTThreadSelfName",                       (void *)RTThreadSelfName },
+    { "RTThreadGetType",                        (void *)RTThreadGetType },
+    { "RTThreadUserSignal",                     (void *)RTThreadUserSignal },
+    { "RTThreadUserReset",                      (void *)RTThreadUserReset },
+    { "RTThreadUserWait",                       (void *)RTThreadUserWait },
+    { "RTThreadUserWaitNoResume",               (void *)RTThreadUserWaitNoResume },
+#endif
     { "RTLogDefaultInstance",                   (void *)RTLogDefaultInstance },
     { "RTLogRelDefaultInstance",                (void *)RTLogRelDefaultInstance },
Index: /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 402)
+++ /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 403)
@@ -284,4 +284,5 @@
 
     memset(&g_DevExt, 0, sizeof(g_DevExt));
+    dprintf(("VBoxSupDrvStop - done\n"));
     return KMOD_RETURN_SUCCESS;
 }
Index: /trunk/src/VBox/Runtime/Makefile
===================================================================
--- /trunk/src/VBox/Runtime/Makefile	(revision 402)
+++ /trunk/src/VBox/Runtime/Makefile	(revision 403)
@@ -532,4 +532,5 @@
 	strformatrt.cpp \
 	strtonum.cpp \
+	strprintf.cpp \
 	VBox/strformat-vbox.cpp \
 	r0drv/alloc-r0drv.cpp \
@@ -539,4 +540,5 @@
 	generic/RTLogWriteUser-generic.cpp \
 	VBox/log-vbox.cpp \
+	table/avlpv.cpp \
 	crc32.cpp \
 	crc64.cpp
@@ -570,5 +572,4 @@
 	string/memchr.asm \
 	r0drv/memobj-r0drv.cpp \
-	r0drv/thread-r0drv.cpp \
 	r0drv/darwin/alloc-r0drv-darwin.cpp \
 	r0drv/darwin/memobj-r0drv-darwin.cpp \
@@ -579,5 +580,7 @@
 	r0drv/darwin/spinlock-r0drv-darwin.cpp \
 	r0drv/darwin/thread-r0drv-darwin.cpp \
+	r0drv/darwin/thread2-r0drv-darwin.cpp \
 	r0drv/darwin/time-r0drv-darwin.cpp \
+	thread.cpp \
 	generic/timer-generic.cpp \
 
Index: /trunk/src/VBox/Runtime/generic/sched-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/generic/sched-generic.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/generic/sched-generic.cpp	(revision 403)
@@ -41,5 +41,5 @@
 int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
 {
-    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
+    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     return VINF_SUCCESS;
 }
@@ -76,5 +76,5 @@
 int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
 {
-    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
+    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/Runtime/generic/semsrw-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/generic/semsrw-generic.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/generic/semsrw-generic.cpp	(revision 403)
@@ -101,5 +101,5 @@
 
 
-RTR3DECL(int)   RTSemRWCreate(PRTSEMRW pRWSem)
+RTDECL(int)   RTSemRWCreate(PRTSEMRW pRWSem)
 {
     int rc;
@@ -160,5 +160,5 @@
 
 
-RTR3DECL(int)   RTSemRWDestroy(RTSEMRW RWSem)
+RTDECL(int)   RTSemRWDestroy(RTSEMRW RWSem)
 {
     /*
@@ -235,5 +235,5 @@
 
 
-RTR3DECL(int)   RTSemRWRequestRead(RTSEMRW RWSem, unsigned cMillies)
+RTDECL(int)   RTSemRWRequestRead(RTSEMRW RWSem, unsigned cMillies)
 {
     /*
@@ -366,5 +366,5 @@
 
 
-RTR3DECL(int)   RTSemRWRequestReadNoResume(RTSEMRW RWSem, unsigned cMillies)
+RTDECL(int)   RTSemRWRequestReadNoResume(RTSEMRW RWSem, unsigned cMillies)
 {
     return RTSemRWRequestRead(RWSem, cMillies);
@@ -372,5 +372,5 @@
 
 
-RTR3DECL(int)   RTSemRWReleaseRead(RTSEMRW RWSem)
+RTDECL(int)   RTSemRWReleaseRead(RTSEMRW RWSem)
 {
     /*
@@ -438,5 +438,5 @@
 
 
-RTR3DECL(int) RTSemRWRequestWrite(RTSEMRW RWSem, unsigned cMillies)
+RTDECL(int) RTSemRWRequestWrite(RTSEMRW RWSem, unsigned cMillies)
 {
     /*
@@ -582,5 +582,5 @@
 
 
-RTR3DECL(int) RTSemRWRequestWriteNoResume(RTSEMRW RWSem, unsigned cMillies)
+RTDECL(int) RTSemRWRequestWriteNoResume(RTSEMRW RWSem, unsigned cMillies)
 {
     return RTSemRWRequestWrite(RWSem, cMillies);
@@ -589,5 +589,5 @@
 
 
-RTR3DECL(int)   RTSemRWReleaseWrite(RTSEMRW RWSem)
+RTDECL(int)   RTSemRWReleaseWrite(RTSEMRW RWSem)
 {
     /*
Index: /trunk/src/VBox/Runtime/generic/timer-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/generic/timer-generic.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/generic/timer-generic.cpp	(revision 403)
@@ -32,4 +32,5 @@
 #include <iprt/time.h>
 #include <iprt/log.h>
+
 
 
@@ -153,7 +154,5 @@
      * If it's suspended we can safely set the destroy flag and signal it.
      */
-#ifdef IN_RING3
     RTTHREAD Thread = pTimer->Thread;
-#endif
     if (!pTimer->fSuspended)
     {
@@ -170,7 +169,5 @@
     }
 
-#ifdef IN_RING3
     RTThreadWait(Thread, 250, NULL);
-#endif
     return VINF_SUCCESS;
 }
@@ -189,6 +186,6 @@
     u64First += RTTimeNanoTS();
     ASMAtomicXchgU64(&pTimer->iTick, 0);
-    ASMAtomicXchgU64(&pTimer->iTick, u64First);
     ASMAtomicXchgU64(&pTimer->u64StartTS, u64First);
+    ASMAtomicXchgU64(&pTimer->u64NextTS, u64First);
     ASMAtomicXchgU8(&pTimer->fSuspended, false);
     int rc = RTSemEventSignal(pTimer->Event);
@@ -216,5 +213,4 @@
     AssertRC(rc);
     return rc;
-
 }
 
Index: /trunk/src/VBox/Runtime/include/internal/thread.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/thread.h	(revision 402)
+++ /trunk/src/VBox/Runtime/include/internal/thread.h	(revision 403)
@@ -25,14 +25,12 @@
 #include <iprt/types.h>
 #include <iprt/thread.h>
+#include <iprt/avl.h>
 #ifdef IN_RING3
 # include <iprt/process.h>
 # include <iprt/critsect.h>
-# include <iprt/avl.h>
 #endif
 
 __BEGIN_DECLS
 
-
-#ifdef IN_RING3
 
 
@@ -89,5 +87,5 @@
     /** The current thread state. */
     RTTHREADSTATE volatile  enmState;
-#ifdef __WIN__
+#if defined(__WIN__) && defined(IN_RING3)
     /** The thread handle.
      * This is not valid until the create function has returned! */
@@ -112,4 +110,5 @@
     /** Actual stack size. */
     size_t                  cbStack;
+#ifdef IN_RING3
     /** What we're blocking on. */
     union RTTHREADINTBLOCKID
@@ -127,4 +126,5 @@
     /** Where we're blocking. */
     RTUINTPTR volatile      uBlockId;
+#endif /* IN_RING3 */
     /** Thread name. */
     char                    szName[RTTHREAD_NAME_LEN];
@@ -154,9 +154,27 @@
  * Initialize the native part of the thread management.
  *
- * Generally a TLS entry will be allocated at this point.
+ * Generally a TLS entry will be allocated at this point (Ring-3).
  *
  * @returns iprt status code.
  */
 int rtThreadNativeInit(void);
+
+/**
+ * Create a native thread.
+ * This creates the thread as described in pThreadInt and stores the thread id in *pThread.
+ *
+ * @returns iprt status code.
+ * @param   pThreadInt      The thread data structure for the thread.
+ * @param   pNativeThread   Where to store the native thread identifier.
+ */
+int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread);
+
+/**
+ * Adopts a thread, this is called immediately after allocating the
+ * thread structure.
+ *
+ * @param   pThread     Pointer to the thread structure.
+ */
+int rtThreadNativeAdopt(PRTTHREADINT pThread);
 
 /**
@@ -174,23 +192,6 @@
 int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType);
 
-/**
- * Create a native thread.
- * This creates the thread as described in pThreadInt and stores the thread id in *pThread.
- *
- * @returns iprt status code.
- * @param   pThreadInt      The thread data structure for the thread.
- * @param   pNativeThread   Where to store the native thread identifier.
- */
-int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread);
-
-/**
- * Adopts a thread, this is called immediately after allocating the
- * thread structure.
- *
- * @param   pThread     Pointer to the thread structure.
- */
-int rtThreadNativeAdopt(PRTTHREADINT pThread);
-
-#ifdef __WIN__
+#ifdef IN_RING3
+# ifdef __WIN__
 /**
  * Callback for when a native thread is detaching.
@@ -200,58 +201,22 @@
  */
 void rtThreadNativeDetach(void);
-#endif
-
-int rtThreadInit(void);
+# endif
+#endif /* !IN_RING0 */
+
+
+/* thread.cpp */
 int rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
-void rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
-PRTTHREADINT rtThreadGetByNative(RTNATIVETHREAD NativeThread);
-PRTTHREADINT rtThreadGet(RTTHREAD Thread);
-uint32_t rtThreadRelease(PRTTHREADINT pThread);
-int rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority);
-void rtThreadTerminate(PRTTHREADINT pThread, int rc);
 void rtThreadBlocking(PRTTHREADINT pThread, RTTHREADSTATE enmState, uint64_t u64Block,
                       const char *pszFile, unsigned uLine, RTUINTPTR uId);
 void rtThreadUnblocked(PRTTHREADINT pThread, RTTHREADSTATE enmCurState);
-
-
-#elif defined(IN_RING0)
-
-/**
- * Argument package for a ring-0 thread.
- */
-typedef struct RTR0THREADARGS
-{
-    /** The thread function. */
-    PFNRTTHREAD     pfnThread;
-    /** The thread function argument. */
-    void           *pvUser;
-    /** The thread type. */
-    RTTHREADTYPE    enmType;
-} RTR0THREADARGS, *PRTR0THREADARGS;
-
-
-
-int rtThreadMain(PRTR0THREADARGS pArgs, RTNATIVETHREAD NativeThread);
-
-/**
- * Do the actual thread creation.
- *
- * @returns IPRT status code.
- *          On failure, no thread has been created.
- * @param   pArgs           The argument package.
- * @param   pNativeThread   Where to return the native thread handle.
- */
-int rtThreadNativeCreate(PRTR0THREADARGS pArgs, PRTNATIVETHREAD pNativeThread);
-
-/**
- * Do the actual thread priority change.
- *
- * @returns IPRT status code.
- * @param   Thread      The thread which priority should be changed.
- *                      This is currently restricted to the current thread.
- * @param   enmType     The new thread priority type (valid).
- */
-int rtThreadNativeSetPriority(RTTHREAD Thread, RTTHREADTYPE enmType);
-
+uint32_t rtThreadRelease(PRTTHREADINT pThread);
+void rtThreadTerminate(PRTTHREADINT pThread, int rc);
+PRTTHREADINT rtThreadGetByNative(RTNATIVETHREAD NativeThread);
+PRTTHREADINT rtThreadGet(RTTHREAD Thread);
+int rtThreadInit(void);
+void rtThreadTerm(void);
+void rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
+#ifdef IN_RING3
+int rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority);
 #endif /* !IN_RING0 */
 
Index: /trunk/src/VBox/Runtime/r0drv/darwin/semaphore-r0drv-darwin.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/darwin/semaphore-r0drv-darwin.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/r0drv/darwin/semaphore-r0drv-darwin.cpp	(revision 403)
@@ -56,4 +56,26 @@
 #define RTSEMEVENT_MAGIC 0x19601110
 
+
+/**
+ * Darwin multiple release event semaphore.
+ */
+typedef struct RTSEMEVENTMULTIINTERNAL
+{
+    /** Magic value (RTSEMEVENTMULTI_MAGIC). */
+    uint32_t volatile   u32Magic;
+    /** The number of waiting threads. */
+    uint32_t volatile   cWaiters;
+    /** Set if the event object is signaled. */
+    uint8_t volatile    fSignaled;
+    /** The number of threads in the process of waking up. */
+    uint32_t volatile   cWaking;
+    /** The spinlock protecting us. */
+    lck_spin_t         *pSpinlock;
+} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
+
+/** Magic for the Darwin multiple release event semaphore structure. (Isaac Asimov) */
+#define RTSEMEVENTMULTI_MAGIC 0x19200102
+
+
 #if 0 /** @todo */
 /**
@@ -187,5 +209,5 @@
         Assert(!pEventInt->cWaiters);
         ASMAtomicXchgU8(&pEventInt->fSignaled, false);
-        rc = 0;
+        rc = VINF_SUCCESS;
     }
     else
@@ -270,4 +292,203 @@
     return rtSemEventWait(EventSem, cMillies, TRUE /* interruptable */);
 }
+
+
+
+RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem)
+{
+    Assert(sizeof(RTSEMEVENTMULTIINTERNAL) > sizeof(void *));
+    AssertPtrReturn(pEventMultiSem, VERR_INVALID_POINTER);
+
+    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pEventMultiInt));
+    if (pEventMultiInt)
+    {
+        pEventMultiInt->u32Magic = RTSEMEVENTMULTI_MAGIC;
+        pEventMultiInt->cWaiters = 0;
+        pEventMultiInt->cWaking = 0;
+        pEventMultiInt->fSignaled = 0;
+        Assert(g_pDarwinLockGroup);
+        pEventMultiInt->pSpinlock = lck_spin_alloc_init(g_pDarwinLockGroup, LCK_ATTR_NULL);
+        if (pEventMultiInt->pSpinlock)
+        {
+            *pEventMultiSem = pEventMultiInt;
+            return VINF_SUCCESS;
+        }
+
+        pEventMultiInt->u32Magic = 0;
+        RTMemFree(pEventMultiInt);
+    }
+    return VERR_NO_MEMORY;
+}
+
+
+RTDECL(int)  RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem)
+{
+    if (EventMultiSem == NIL_RTSEMEVENTMULTI)     /* don't bitch */
+        return VERR_INVALID_HANDLE;
+    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
+    AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
+                    ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
+                    VERR_INVALID_HANDLE);
+
+    lck_spin_lock(pEventMultiInt->pSpinlock);
+    ASMAtomicIncU32(&pEventMultiInt->u32Magic); /* make the handle invalid */
+    if (pEventMultiInt->cWaiters > 0)
+    {
+        /* abort waiting thread, last man cleans up. */
+        ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters);
+        thread_wakeup_prim((event_t)pEventMultiInt, FALSE /* all threads */, THREAD_RESTART);
+        lck_spin_unlock(pEventMultiInt->pSpinlock);
+    }
+    else if (pEventMultiInt->cWaking)
+        /* the last waking thread is gonna do the cleanup */
+        lck_spin_unlock(pEventMultiInt->pSpinlock);
+    else
+    {
+        lck_spin_unlock(pEventMultiInt->pSpinlock);
+        lck_spin_destroy(pEventMultiInt->pSpinlock, g_pDarwinLockGroup);
+        RTMemFree(pEventMultiInt);
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
+{
+    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
+    AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
+                    ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
+                    VERR_INVALID_HANDLE);
+
+    lck_spin_lock(pEventMultiInt->pSpinlock);
+
+    ASMAtomicXchgU8(&pEventMultiInt->fSignaled, true);
+    if (pEventMultiInt->cWaiters > 0)
+    {
+        ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters);
+        ASMAtomicXchgU32(&pEventMultiInt->cWaiters, 0);
+        thread_wakeup_prim((event_t)pEventMultiInt, FALSE /* all threads */, THREAD_AWAKENED);
+    }
+
+    lck_spin_unlock(pEventMultiInt->pSpinlock);
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
+{
+    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
+    AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
+                    ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
+                    VERR_INVALID_HANDLE);
+
+    lck_spin_lock(pEventMultiInt->pSpinlock);
+    ASMAtomicXchgU8(&pEventMultiInt->fSignaled, false);
+    lck_spin_unlock(pEventMultiInt->pSpinlock);
+    return VINF_SUCCESS;
+}
+
+
+static int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, wait_interrupt_t fInterruptible)
+{
+    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
+    AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
+                    ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
+                    VERR_INVALID_HANDLE);
+
+    lck_spin_lock(pEventMultiInt->pSpinlock);
+
+    int rc;
+    if (pEventMultiInt->fSignaled)
+    {
+        ASMAtomicXchgU8(&pEventMultiInt->fSignaled, false);
+        rc = VINF_SUCCESS;
+    }
+    else
+    {
+        ASMAtomicIncU32(&pEventMultiInt->cWaiters);
+
+        wait_result_t rcWait;
+        if (cMillies == RT_INDEFINITE_WAIT)
+            rcWait = lck_spin_sleep(pEventMultiInt->pSpinlock, LCK_SLEEP_DEFAULT, (event_t)pEventMultiInt, fInterruptible);
+        else
+        {
+            uint64_t u64AbsTime;
+            nanoseconds_to_absolutetime(cMillies * UINT64_C(1000000), &u64AbsTime);
+            u64AbsTime += mach_absolute_time();
+
+            rcWait = lck_spin_sleep_deadline(pEventMultiInt->pSpinlock, LCK_SLEEP_DEFAULT,
+                                             (event_t)pEventMultiInt, fInterruptible, u64AbsTime);
+        }
+        switch (rcWait)
+        {
+            case THREAD_AWAKENED:
+                Assert(pEventMultiInt->cWaking > 0);
+                if (    !ASMAtomicDecU32(&pEventMultiInt->cWaking)
+                    &&  pEventMultiInt->u32Magic != RTSEMEVENTMULTI_MAGIC)
+                {
+                    /* the event was destroyed after we woke up, as the last thread do the cleanup. */
+                    lck_spin_unlock(pEventMultiInt->pSpinlock);
+                    Assert(g_pDarwinLockGroup);
+                    lck_spin_destroy(pEventMultiInt->pSpinlock, g_pDarwinLockGroup);
+                    RTMemFree(pEventMultiInt);
+                    return VINF_SUCCESS;
+                }
+                rc = VINF_SUCCESS;
+                break;
+
+            case THREAD_TIMED_OUT:
+                Assert(cMillies != RT_INDEFINITE_WAIT);
+                ASMAtomicDecU32(&pEventMultiInt->cWaiters);
+                rc = VERR_TIMEOUT;
+                break;
+
+            case THREAD_INTERRUPTED:
+                Assert(fInterruptible);
+                ASMAtomicDecU32(&pEventMultiInt->cWaiters);
+                rc = VERR_INTERRUPTED;
+                break;
+
+            case THREAD_RESTART:
+                /* Last one out does the cleanup. */
+                if (!ASMAtomicDecU32(&pEventMultiInt->cWaking))
+                {
+                    lck_spin_unlock(pEventMultiInt->pSpinlock);
+                    Assert(g_pDarwinLockGroup);
+                    lck_spin_destroy(pEventMultiInt->pSpinlock, g_pDarwinLockGroup);
+                    RTMemFree(pEventMultiInt);
+                    return VERR_SEM_DESTROYED;
+                }
+
+                rc = VERR_SEM_DESTROYED;
+                break;
+
+            default:
+                AssertMsgFailed(("rcWait=%d\n", rcWait));
+                rc = VERR_GENERAL_FAILURE;
+                break;
+        }
+    }
+
+    lck_spin_unlock(pEventMultiInt->pSpinlock);
+    return rc;
+}
+
+
+RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
+{
+    return rtSemEventMultiWait(EventMultiSem, cMillies, FALSE /* not interruptable */);
+}
+
+
+RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
+{
+    return rtSemEventMultiWait(EventMultiSem, cMillies, TRUE /* interruptable */);
+}
+
 
 
Index: /trunk/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp	(revision 403)
@@ -26,15 +26,14 @@
 #include <iprt/thread.h>
 #include <iprt/err.h>
-#include <iprt/assert.h>
-#include "internal/thread.h"
 
 
-RTDECL(RTTHREAD) RTThreadSelf(void)
+
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
 {
-    return (RTTHREAD)current_thread();
+    return (RTNATIVETHREAD)current_thread();
 }
 
 
-RTDECL(int)   RTThreadSleep(unsigned cMillies)
+RTDECL(int) RTThreadSleep(unsigned cMillies)
 {
     uint64_t u64Deadline;
@@ -51,110 +50,2 @@
 }
 
-
-int rtThreadNativeSetPriority(RTTHREAD Thread, RTTHREADTYPE enmType)
-{
-    /*
-     * Convert the priority type to scheduling policies.
-     */
-    bool                            fSetExtended = false;
-    thread_extended_policy          Extended = { true };
-    bool                            fSetTimeContstraint = false;
-    thread_time_constraint_policy   TimeConstraint = { 0, 0, 0, true };
-    thread_precedence_policy        Precedence = { 0 };
-    switch (enmType)
-    {
-        case RTTHREADTYPE_INFREQUENT_POLLER:
-            Precedence.importance = 1;
-            break;
-
-        case RTTHREADTYPE_EMULATION:
-            Precedence.importance = 30;
-            break;
-
-        case RTTHREADTYPE_DEFAULT:
-            Precedence.importance = 31;
-            break;
-
-        case RTTHREADTYPE_MSG_PUMP:
-            Precedence.importance = 34;
-            break;
-
-        case RTTHREADTYPE_IO:
-            Precedence.importance = 98;
-            break;
-
-        case RTTHREADTYPE_TIMER:
-            Precedence.importance = 0x7fffffff;
-
-            fSetExtended = true;
-            Extended.timeshare = FALSE;
-
-            fSetTimeContstraint = true;
-            TimeConstraint.period = 0; /* not really true for a real timer thread, but we've really no idea. */
-            TimeConstraint.computation = rtDarwinAbsTimeFromNano(100000); /* 100 us*/
-            TimeConstraint.constraint = rtDarwinAbsTimeFromNano(500000);  /* 500 us */
-            TimeConstraint.preemptible = FALSE;
-            break;
-
-        default:
-            AssertMsgFailed(("enmType=%d\n", enmType));
-            return VERR_INVALID_PARAMETER;
-    }
-
-    /*
-     * Do the actual modification.
-     */
-    kern_return_t rc = thread_policy_set((thread_t)Thread, THREAD_PRECEDENCE_POLICY,
-                                         (thread_policy_t)&Precedence, THREAD_PRECEDENCE_POLICY_COUNT);
-    AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc)); NOREF(rc);
-
-    if (fSetExtended)
-    {
-        rc = thread_policy_set((thread_t)Thread, THREAD_EXTENDED_POLICY,
-                               (thread_policy_t)&Extended, THREAD_EXTENDED_POLICY_COUNT);
-        AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc));
-    }
-
-    if (fSetTimeContstraint)
-    {
-        rc = thread_policy_set((thread_t)Thread, THREAD_TIME_CONSTRAINT_POLICY,
-                               (thread_policy_t)&TimeConstraint, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
-        AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc));
-    }
-
-    return VINF_SUCCESS; /* ignore any errors for now */
-}
-
-
-/**
- * Native kernel thread wrapper function.
- *
- * This will forward to rtThreadMain and do termination upon return.
- *
- * @param pvArg         Pointer to the argument package.
- * @param Ignored       Wait result, which we ignore.
- */
-static void rtThreadNativeMain(void *pvArg, wait_result_t Ignored)
-{
-    const thread_t Self = current_thread();
-
-    rtThreadMain((PRTR0THREADARGS)pvArg, (RTNATIVETHREAD)Self);
-
-    kern_return_t rc = thread_terminate(Self);
-    AssertFatalMsgFailed(("rc=%d\n", rc));
-}
-
-
-int rtThreadNativeCreate(PRTR0THREADARGS pArgs, PRTNATIVETHREAD pNativeThread)
-{
-    thread_t NativeThread;
-    kern_return_t rc = kernel_thread_start(rtThreadNativeMain, pArgs, &NativeThread);
-    if (rc == KERN_SUCCESS)
-    {
-        *pNativeThread = (RTNATIVETHREAD)NativeThread;
-        thread_deallocate(NativeThread);
-        return VINF_SUCCESS;
-    }
-    return RTErrConvertFromMachKernReturn(rc);
-}
-
Index: /trunk/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp	(revision 403)
+++ /trunk/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp	(revision 403)
@@ -0,0 +1,158 @@
+/* $Id$ */
+/** @file
+ * InnoTek Portable Runtime - Threads (Part 2), Ring-0 Driver, Darwin.
+ */
+
+/*
+ * Copyright (C) 2006 InnoTek Systemberatung GmbH
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation,
+ * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
+ * distribution. VirtualBox OSE is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * If you received this file as part of a commercial VirtualBox
+ * distribution, then only the terms of your commercial VirtualBox
+ * license agreement apply instead of the previous paragraph.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-darwin-kernel.h"
+#include <iprt/thread.h>
+#include <iprt/err.h>
+#include <iprt/assert.h>
+#include "internal/thread.h"
+
+
+int rtThreadNativeInit(void)
+{
+    /* No TLS in Ring-0. :-/ */
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(RTTHREAD) RTThreadSelf(void)
+{
+    return rtThreadGetByNative((RTNATIVETHREAD)current_thread());
+}
+
+
+int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+{
+    /*
+     * Convert the priority type to scheduling policies.
+     * (This is really just guess work.)
+     */
+    bool                            fSetExtended = false;
+    thread_extended_policy          Extended = { true };
+    bool                            fSetTimeContstraint = false;
+    thread_time_constraint_policy   TimeConstraint = { 0, 0, 0, true };
+    thread_precedence_policy        Precedence = { 0 };
+    switch (enmType)
+    {
+        case RTTHREADTYPE_INFREQUENT_POLLER:
+            Precedence.importance = 1;
+            break;
+
+        case RTTHREADTYPE_EMULATION:
+            Precedence.importance = 30;
+            break;
+
+        case RTTHREADTYPE_DEFAULT:
+            Precedence.importance = 31;
+            break;
+
+        case RTTHREADTYPE_MSG_PUMP:
+            Precedence.importance = 34;
+            break;
+
+        case RTTHREADTYPE_IO:
+            Precedence.importance = 98;
+            break;
+
+        case RTTHREADTYPE_TIMER:
+            Precedence.importance = 0x7fffffff;
+
+            fSetExtended = true;
+            Extended.timeshare = FALSE;
+
+            fSetTimeContstraint = true;
+            TimeConstraint.period = 0; /* not really true for a real timer thread, but we've really no idea. */
+            TimeConstraint.computation = rtDarwinAbsTimeFromNano(100000); /* 100 us*/
+            TimeConstraint.constraint = rtDarwinAbsTimeFromNano(500000);  /* 500 us */
+            TimeConstraint.preemptible = FALSE;
+            break;
+
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            return VERR_INVALID_PARAMETER;
+    }
+
+    /*
+     * Do the actual modification.
+     */
+    kern_return_t kr = thread_policy_set((thread_t)pThread->Core.Key, THREAD_PRECEDENCE_POLICY,
+                                         (thread_policy_t)&Precedence, THREAD_PRECEDENCE_POLICY_COUNT);
+    AssertMsg(kr == KERN_SUCCESS, ("%rc\n", kr)); NOREF(kr);
+
+    if (fSetExtended)
+    {
+        kr = thread_policy_set((thread_t)pThread->Core.Key, THREAD_EXTENDED_POLICY,
+                               (thread_policy_t)&Extended, THREAD_EXTENDED_POLICY_COUNT);
+        AssertMsg(kr == KERN_SUCCESS, ("%rc\n", kr));
+    }
+
+    if (fSetTimeContstraint)
+    {
+        kr = thread_policy_set((thread_t)pThread->Core.Key, THREAD_TIME_CONSTRAINT_POLICY,
+                               (thread_policy_t)&TimeConstraint, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
+        AssertMsg(kr == KERN_SUCCESS, ("%rc\n", kr));
+    }
+
+    return VINF_SUCCESS; /* ignore any errors for now */
+}
+
+
+int rtThreadNativeAdopt(PRTTHREADINT pThread)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * Native kernel thread wrapper function.
+ *
+ * This will forward to rtThreadMain and do termination upon return.
+ *
+ * @param pvArg         Pointer to the argument package.
+ * @param Ignored       Wait result, which we ignore.
+ */
+static void rtThreadNativeMain(void *pvArg, wait_result_t Ignored)
+{
+    const thread_t Self = current_thread();
+
+    rtThreadMain((PRTTHREADINT)pvArg, (RTNATIVETHREAD)Self);
+
+    kern_return_t kr = thread_terminate(Self);
+    AssertFatalMsgFailed(("kr=%d\n", kr));
+}
+
+
+int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+{
+    thread_t NativeThread;
+    kern_return_t kr = kernel_thread_start(rtThreadNativeMain, pThreadInt, &NativeThread);
+    if (kr == KERN_SUCCESS)
+    {
+        *pNativeThread = (RTNATIVETHREAD)NativeThread;
+        thread_deallocate(NativeThread);
+        return VINF_SUCCESS;
+    }
+    return RTErrConvertFromMachKernReturn(kr);
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/initterm-r0drv.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/initterm-r0drv.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/r0drv/initterm-r0drv.cpp	(revision 403)
@@ -26,5 +26,8 @@
 #include <iprt/initterm.h>
 #include <iprt/assert.h>
+#include <iprt/err.h>
+
 #include "internal/initterm.h"
+#include "internal/thread.h"
 
 
@@ -37,6 +40,18 @@
 RTR0DECL(int) RTR0Init(unsigned fReserved)
 {
+    int rc;
     Assert(fReserved == 0);
-    return rtR0InitNative();
+    rc = rtR0InitNative();
+    if (RT_SUCCESS(rc))
+    {
+#if !defined(__LINUX__) && !defined(__WIN__)
+        rc = rtThreadInit();
+#endif
+        if (RT_SUCCESS(rc))
+            return rc;
+
+        rtR0TermNative();
+    }
+    return rc;
 }
 
@@ -47,5 +62,8 @@
 RTR0DECL(void) RTR0Term(void)
 {
-    return rtR0TermNative();
+#if !defined(__LINUX__) && !defined(__WIN__)
+    rtThreadTerm();
+#endif
+    rtR0TermNative();
 }
 
Index: /trunk/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c	(revision 402)
+++ /trunk/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c	(revision 403)
@@ -29,7 +29,7 @@
 
 
-RTDECL(RTTHREAD) RTThreadSelf(void)
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
 {
-    return (RTTHREAD)current;
+    return (RTNATIVETHREAD)current;
 }
 
Index: /trunk/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c	(revision 403)
+++ /trunk/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c	(revision 403)
@@ -0,0 +1,36 @@
+/* $Id$ */
+/** @file
+ * InnoTek Portable Runtime - Threads (Part 2), Ring-0 Driver, Linux.
+ */
+
+/*
+ * Copyright (C) 2006 InnoTek Systemberatung GmbH
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation,
+ * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
+ * distribution. VirtualBox OSE is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * If you received this file as part of a commercial VirtualBox
+ * distribution, then only the terms of your commercial VirtualBox
+ * license agreement apply instead of the previous paragraph.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-linux-kernel.h"
+
+#include <iprt/thread.h>
+#include <iprt/err.h>
+#include "internal/thread.h"
+
+
+RTDECL(RTTHREAD) RTThreadSelf(void)
+{
+    return rtThreadGetByNative(((RTNATIVETHREAD)current);
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp	(revision 403)
@@ -33,7 +33,7 @@
 
 
-RTDECL(RTTHREAD) RTThreadSelf(void)
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
 {
-    return (RTTHREAD)PsGetCurrentThread();
+    return (RTNATIVETHREAD)PsGetCurrentThread();
 }
 
@@ -62,2 +62,3 @@
 }
 
+
Index: /trunk/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp	(revision 403)
+++ /trunk/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp	(revision 403)
@@ -0,0 +1,37 @@
+/* $Id$ */
+/** @file
+ * InnoTek Portable Runtime - Threads (Part 2), Ring-0 Driver, NT.
+ */
+
+/*
+ * Copyright (C) 2006 InnoTek Systemberatung GmbH
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation,
+ * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
+ * distribution. VirtualBox OSE is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * If you received this file as part of a commercial VirtualBox
+ * distribution, then only the terms of your commercial VirtualBox
+ * license agreement apply instead of the previous paragraph.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-nt-kernel.h"
+
+#include <iprt/thread.h>
+#include <iprt/err.h>
+
+#include "internal/thread.h"
+
+
+RTDECL(RTTHREAD) RTThreadSelf(void)
+{
+    return rtThreadGetByNative((RTNATIVETHREAD)PsGetCurrentThread());
+}
+
Index: unk/src/VBox/Runtime/r0drv/thread-r0drv.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/thread-r0drv.cpp	(revision 402)
+++ 	(revision )
@@ -1,153 +1,0 @@
-/* $Id$ */
-/** @file
- * InnoTek Portable Runtime - Threads, Ring-0 Driver, Common Bits.
- */
-
-/*
- * Copyright (C) 2006 InnoTek Systemberatung GmbH
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License as published by the Free Software Foundation,
- * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
- * distribution. VirtualBox OSE is distributed in the hope that it will
- * be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * If you received this file as part of a commercial VirtualBox
- * distribution, then only the terms of your commercial VirtualBox
- * license agreement apply instead of the previous paragraph.
- */
-
-/*******************************************************************************
-*   Header Files                                                               *
-*******************************************************************************/
-#define LOG_GROUP RTLOGGROUP_THREAD
-#include "internal/thread.h"
-#include <iprt/thread.h>
-#include <iprt/alloc.h>
-#include <iprt/assert.h>
-#include <iprt/log.h>
-#include <iprt/err.h>
-#include <iprt/string.h>
-
-
-/* In ring-0 RTTHREAD == RTNATIVETHREAD. */
-
-RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
-{
-    return (RTNATIVETHREAD)RTThreadSelf();
-}
-
-RTDECL(RTNATIVETHREAD) RTThreadGetNative(RTTHREAD Thread)
-{
-    return (RTNATIVETHREAD)Thread;
-}
-
-RTDECL(RTTHREAD) RTThreadFromNative(RTNATIVETHREAD NativeThread)
-{
-    return (RTTHREAD)NativeThread;
-}
-
-
-/**
- * Checks that the give thread type is valid for a ring-0 context.
- *
- * @returns true if it's valid, otherwise false is returned.
- * @param   enmType   The thread type.
- */
-static bool rtThreadIsTypeValid(RTTHREADTYPE enmType)
-{
-    switch (enmType)
-    {
-        case RTTHREADTYPE_INFREQUENT_POLLER:
-        case RTTHREADTYPE_EMULATION:
-        case RTTHREADTYPE_DEFAULT:
-        case RTTHREADTYPE_MSG_PUMP:
-        case RTTHREADTYPE_IO:
-        case RTTHREADTYPE_TIMER:
-            return true;
-        default:
-            return false;
-    }
-}
-
-
-RTDECL(int) RTThreadSetType(RTTHREAD Thread, RTTHREADTYPE enmType)
-{
-    /*
-     * Validate input.
-     */
-    AssertMsgReturn(RTThreadSelf() == Thread, ("%RTthrd != %RTthrd\n", RTThreadSelf(), Thread), VERR_INVALID_HANDLE);
-    AssertMsgReturn(rtThreadIsTypeValid(enmType), ("enmType=%d\n", enmType), VERR_INVALID_PARAMETER);
-
-    /*
-     * Call the native function to do the actual job.
-     */
-    return rtThreadNativeSetPriority(Thread, enmType);
-}
-
-
-/**
- * Common thread wrapper function.
- *
- * This will adjust the priority and invoke the IPRT thread function.
- *
- * @param pArgs         Pointer to the argument package.
- * @param NativeThread  The native thread handle.
- */
-int rtThreadMain(PRTR0THREADARGS pArgs, RTNATIVETHREAD NativeThread)
-{
-    RTR0THREADARGS Args = *pArgs;
-    RTMemTmpFree(pArgs);
-
-    /*
-     * Set thread priority and invoke the thread function.
-     */
-    int rc = rtThreadNativeSetPriority((RTTHREAD)NativeThread, Args.enmType);
-    AssertRC(rc);
-    return Args.pfnThread((RTTHREAD)NativeThread, Args.pvUser);
-}
-
-
-RTDECL(int) RTThreadCreate(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
-                           RTTHREADTYPE enmType, unsigned fFlags, const char *pszName)
-{
-    LogFlow(("RTThreadCreate: pThread=%p pfnThread=%p pvUser=%p cbStack=%#x enmType=%d fFlags=%#x pszName=%p:{%s}\n",
-             pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszName, pszName));
-
-    /*
-     * Validate input.
-     */
-    AssertPtrNullReturn(pThread, VERR_INVALID_POINTER);
-    AssertPtrReturn(pfnThread, VERR_INVALID_POINTER);
-    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
-    AssertMsgReturn(strlen(pszName) < 16, ("%.*64s", pszName), VERR_INVALID_PARAMETER);
-    AssertMsgReturn(!(fFlags & ~RTTHREADFLAGS_MASK), ("fFlags=%#x\n", fFlags), VERR_INVALID_PARAMETER);
-    AssertMsgReturn(cbStack == 0, ("cbStack=%#x - only default (0) is allowed for Ring-0!\n", cbStack), VERR_INVALID_PARAMETER);
-
-    /*
-     * Allocate thread argument.
-     */
-    PRTR0THREADARGS pArgs = (PRTR0THREADARGS)RTMemTmpAlloc(sizeof(*pArgs));
-    if (!pArgs)
-        return VERR_NO_TMP_MEMORY;
-
-    pArgs->pvUser = pvUser;
-    pArgs->pfnThread = pfnThread;
-    pArgs->enmType = enmType;
-    RTNATIVETHREAD NativeThread;
-    int rc = rtThreadNativeCreate(pArgs, &NativeThread);
-    if (RT_SUCCESS(rc))
-    {
-        Log(("RTThreadCreate: Created thread %RTnthrd %s\n", NativeThread, pszName));
-        if (pThread)
-            *pThread = (RTTHREAD)NativeThread;
-        return VINF_SUCCESS;
-    }
-    RTMemTmpFree(pArgs);
-    LogFlow(("RTThreadCreate: Failed to create thread, rc=%Rrc\n", rc));
-    AssertRC(rc);
-    return rc;
-}
-
Index: /trunk/src/VBox/Runtime/r3/linux/sched-linux.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/linux/sched-linux.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/r3/linux/sched-linux.cpp	(revision 403)
@@ -124,5 +124,5 @@
  * to only be lowering the priority.
  */
-static const PROCPRIORITYTYPE g_aTypesLinuxFree[RTTHREADTYPE_LAST] =
+static const PROCPRIORITYTYPE g_aTypesLinuxFree[RTTHREADTYPE_END] =
 {
     { RTTHREADTYPE_INVALID,                 -999999999 },
@@ -143,5 +143,5 @@
  * Deltas for a process in which we are restricted and can only lower the priority.
  */
-static const PROCPRIORITYTYPE g_aTypesLinuxRestricted[RTTHREADTYPE_LAST] =
+static const PROCPRIORITYTYPE g_aTypesLinuxRestricted[RTTHREADTYPE_END] =
 {
     { RTTHREADTYPE_INVALID,                 -999999999 },
@@ -165,5 +165,5 @@
  * to the process default of a thread created by a low priority thread.
  */
-static const PROCPRIORITYTYPE g_aTypesLinuxFlat[RTTHREADTYPE_LAST] =
+static const PROCPRIORITYTYPE g_aTypesLinuxFlat[RTTHREADTYPE_END] =
 {
     { RTTHREADTYPE_INVALID,                 -999999999 },
@@ -465,5 +465,5 @@
 int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
 {
-    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
+    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
 
     /*
@@ -518,5 +518,5 @@
      */
     int rc = VINF_SUCCESS;
-    int i = RTTHREADTYPE_LAST;
+    int i = RTTHREADTYPE_END;
     while (--i > RTTHREADTYPE_INVALID)
     {
@@ -598,5 +598,5 @@
 {
     /* sanity */
-    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
+    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     Assert(enmType == g_pProcessPriority->paTypes[enmType].enmType);
     Assert((pthread_t)pThread->Core.Key == pthread_self());
Index: /trunk/src/VBox/Runtime/r3/posix/sched-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/sched-posix.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/r3/posix/sched-posix.cpp	(revision 403)
@@ -122,5 +122,5 @@
  * certain).
  */
-static const PROCPRIORITYTYPE g_aTypesThread[RTTHREADTYPE_LAST] =
+static const PROCPRIORITYTYPE g_aTypesThread[RTTHREADTYPE_END] =
 {
     { RTTHREADTYPE_INVALID,                 -999999999 },
@@ -138,5 +138,5 @@
 };
 
-static const PROCPRIORITYTYPE g_aTypesThreadFlat[RTTHREADTYPE_LAST] =
+static const PROCPRIORITYTYPE g_aTypesThreadFlat[RTTHREADTYPE_END] =
 {
     { RTTHREADTYPE_INVALID,                 ~0 },
@@ -184,5 +184,5 @@
  * to only be lowering the priority.
  */
-static const PROCPRIORITYTYPE g_aTypesUnixFree[RTTHREADTYPE_LAST] =
+static const PROCPRIORITYTYPE g_aTypesUnixFree[RTTHREADTYPE_END] =
 {
     { RTTHREADTYPE_INVALID,                 -999999999 },
@@ -204,5 +204,5 @@
  * to only be lowering the priority.
  */
-static const PROCPRIORITYTYPE g_aTypesUnixRestricted[RTTHREADTYPE_LAST] =
+static const PROCPRIORITYTYPE g_aTypesUnixRestricted[RTTHREADTYPE_END] =
 {
     { RTTHREADTYPE_INVALID,                 -999999999 },
@@ -224,5 +224,5 @@
  * to only be lowering the priority.
  */
-static const PROCPRIORITYTYPE g_aTypesUnixFlat[RTTHREADTYPE_LAST] =
+static const PROCPRIORITYTYPE g_aTypesUnixFlat[RTTHREADTYPE_END] =
 {
     { RTTHREADTYPE_INVALID,                 -999999999 },
@@ -506,5 +506,5 @@
 int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
 {
-    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
+    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
 
     /*
@@ -584,5 +584,5 @@
                 int iMin = sched_get_priority_min(SavedPriority.iPolicy);
                 pthread_t Self = pthread_self();
-                for (int i = RTTHREADTYPE_INVALID + 1; i < RTTHREADTYPE_LAST; i++)
+                for (int i = RTTHREADTYPE_INVALID + 1; i < RTTHREADTYPE_END; i++)
                 {
                     struct sched_param SchedParam = SavedPriority.PthreadSchedParam;
@@ -607,5 +607,5 @@
         case OSPRIOSUP_THREAD_LEVEL:
         {
-            int i = RTTHREADTYPE_LAST;
+            int i = RTTHREADTYPE_END;
             while (--i > RTTHREADTYPE_INVALID)
             {
@@ -737,5 +737,5 @@
 int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
 {
-    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
+    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     Assert(enmType == g_pProcessPriority->paTypes[enmType].enmType);
     Assert((pthread_t)pThread->Core.Key == pthread_self());
Index: /trunk/src/VBox/Runtime/r3/win32/sched-win32.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win32/sched-win32.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/r3/win32/sched-win32.cpp	(revision 403)
@@ -61,5 +61,5 @@
         /** The Win32 thread priority. */
         DWORD           dwThreadPriority;
-    } aTypes[RTTHREADTYPE_LAST];
+    } aTypes[RTTHREADTYPE_END];
 } PROCPRIORITY;
 
@@ -254,5 +254,5 @@
 int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
 {
-    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
+    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     return VINF_SUCCESS;
 }
@@ -303,5 +303,5 @@
 int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
 {
-    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
+    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
     AssertMsg(g_pProcessPriority && g_pProcessPriority->aTypes[enmType].enmType == enmType,
               ("enmType=%d entry=%d\n", enmType, g_pProcessPriority->aTypes[enmType].enmType));
Index: /trunk/src/VBox/Runtime/thread.cpp
===================================================================
--- /trunk/src/VBox/Runtime/thread.cpp	(revision 402)
+++ /trunk/src/VBox/Runtime/thread.cpp	(revision 403)
@@ -32,4 +32,7 @@
 #include <iprt/assert.h>
 #include <iprt/semaphore.h>
+#ifdef IN_RING0
+# include <iprt/spinlock.h>
+#endif
 #include <iprt/asm.h>
 #include <iprt/err.h>
@@ -43,8 +46,17 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-#define RT_THREAD_LOCK_RW()     rtThreadLockRW()
-#define RT_THREAD_UNLOCK_RW()   rtThreadUnLockRW()
-#define RT_THREAD_LOCK_RD()     rtThreadLockRD()
-#define RT_THREAD_UNLOCK_RD()   rtThreadUnLockRD()
+#ifdef IN_RING0
+# define RT_THREAD_LOCK_TMP(Tmp)    RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER
+# define RT_THREAD_LOCK_RW(Tmp)     RTSpinlockAcquireNoInts(g_ThreadSpinlock, &(Tmp))
+# define RT_THREAD_UNLOCK_RW(Tmp)   RTSpinlockReleaseNoInts(g_ThreadSpinlock, &(Tmp))
+# define RT_THREAD_LOCK_RD(Tmp)     RTSpinlockAcquireNoInts(g_ThreadSpinlock, &(Tmp))
+# define RT_THREAD_UNLOCK_RD(Tmp)   RTSpinlockReleaseNoInts(g_ThreadSpinlock, &(Tmp))
+#else
+# define RT_THREAD_LOCK_TMP(Tmp)
+# define RT_THREAD_LOCK_RW(Tmp)     rtThreadLockRW()
+# define RT_THREAD_UNLOCK_RW(Tmp)   rtThreadUnLockRW()
+# define RT_THREAD_LOCK_RD(Tmp)     rtThreadLockRD()
+# define RT_THREAD_UNLOCK_RD(Tmp)   rtThreadUnLockRD()
+#endif
 
 
@@ -54,6 +66,11 @@
 /** The AVL thread containing the threads. */
 static PAVLPVNODECORE   g_ThreadTree;
+#ifdef IN_RING3
 /** The RW lock protecting the tree. */
 static RTSEMRW          g_ThreadRWSem = NIL_RTSEMRW;
+#else
+/** The spinlocks protecting the tree. */
+static RTSPINLOCK       g_ThreadSpinlock = NIL_RTSPINLOCK;
+#endif
 
 
@@ -87,9 +104,13 @@
  * thread id. RTThreadSelf() then have to be implemented using a pointer stored
  * in thread local storage (TLS).
- */
-
-
-/**
- * Initializes the thread data base.
+ *
+ * In Ring-0 we only try keep track of kernel threads created by RTCreateThread
+ * at the moment. There we really only need the 'join' feature, but doing things
+ * the same way allow us to name threads and similar stuff.
+ */
+
+
+/**
+ * Initializes the thread database.
  *
  * @returns iprt status code.
@@ -97,4 +118,5 @@
 int rtThreadInit(void)
 {
+#ifdef IN_RING3
     int rc = VINF_ALREADY_INITIALIZED;
     if (g_ThreadRWSem == NIL_RTSEMRW)
@@ -108,8 +130,10 @@
         {
             rc = rtThreadNativeInit();
+#ifdef IN_RING3
             if (RT_SUCCESS(rc))
                 rc = rtThreadAdopt(RTTHREADTYPE_DEFAULT, 0, "main");
             if (RT_SUCCESS(rc))
                 rc = rtSchedNativeCalcDefaultPriority(RTTHREADTYPE_DEFAULT);
+#endif
             if (RT_SUCCESS(rc))
                 return VINF_SUCCESS;
@@ -120,6 +144,82 @@
         }
     }
-    return rc;
-}
+
+#elif defined(IN_RING0)
+
+    /*
+     * Create the spinlock and to native init.
+     */
+    Assert(g_ThreadSpinlock == NIL_RTSPINLOCK);
+    int rc = RTSpinlockCreate(&g_ThreadSpinlock);
+    if (RT_SUCCESS(rc))
+    {
+        rc = rtThreadNativeInit();
+        if (RT_SUCCESS(rc))
+            return VINF_SUCCESS;
+
+        /* failed, clear out */
+        RTSpinlockDestroy(g_ThreadSpinlock);
+        g_ThreadSpinlock = NIL_RTSPINLOCK;
+    }
+#else
+# error "!IN_RING0 && !IN_RING3"
+#endif
+    return rc;
+}
+
+
+/**
+ * Terminates the thread database.
+ */
+void rtThreadTerm(void)
+{
+#ifdef IN_RING3
+    /* we don't cleanup here yet */
+
+#elif defined(IN_RING0)
+    /* just destroy the spinlock and assume the thread is fine... */
+    RTSpinlockDestroy(g_ThreadSpinlock);
+    g_ThreadSpinlock = NIL_RTSPINLOCK;
+    if (g_ThreadTree != NULL)
+        AssertMsg2("WARNING: g_ThreadTree=%p\n", g_ThreadTree);
+#endif
+}
+
+
+
+#ifdef IN_RING3
+
+inline void rtThreadLockRW(void)
+{
+    if (g_ThreadRWSem == NIL_RTSEMRW)
+        rtThreadInit();
+    int rc = RTSemRWRequestWrite(g_ThreadRWSem, RT_INDEFINITE_WAIT);
+    AssertReleaseRC(rc);
+}
+
+
+inline void rtThreadLockRD(void)
+{
+    if (g_ThreadRWSem == NIL_RTSEMRW)
+        rtThreadInit();
+    int rc = RTSemRWRequestRead(g_ThreadRWSem, RT_INDEFINITE_WAIT);
+    AssertReleaseRC(rc);
+}
+
+
+inline void rtThreadUnLockRW(void)
+{
+    int rc = RTSemRWReleaseWrite(g_ThreadRWSem);
+    AssertReleaseRC(rc);
+}
+
+
+inline void rtThreadUnLockRD(void)
+{
+    int rc = RTSemRWReleaseRead(g_ThreadRWSem);
+    AssertReleaseRC(rc);
+}
+
+#endif /* IN_RING3 */
 
 
@@ -193,36 +293,4 @@
         *pThread = Thread;
     return rc;
-}
-
-
-inline void rtThreadLockRW(void)
-{
-    if (!g_ThreadRWSem)
-        rtThreadInit();
-    int rc = RTSemRWRequestWrite(g_ThreadRWSem, RT_INDEFINITE_WAIT);
-    AssertReleaseRC(rc);
-}
-
-
-inline void rtThreadLockRD(void)
-{
-    if (!g_ThreadRWSem)
-        rtThreadInit();
-    int rc = RTSemRWRequestRead(g_ThreadRWSem, RT_INDEFINITE_WAIT);
-    AssertReleaseRC(rc);
-}
-
-
-inline void rtThreadUnLockRW(void)
-{
-    int rc = RTSemRWReleaseWrite(g_ThreadRWSem);
-    AssertReleaseRC(rc);
-}
-
-
-inline void rtThreadUnLockRD(void)
-{
-    int rc = RTSemRWReleaseRead(g_ThreadRWSem);
-    AssertReleaseRC(rc);
 }
 
@@ -285,5 +353,6 @@
     Assert(pThread->u32Magic == RTTHREADINT_MAGIC);
 
-    RT_THREAD_LOCK_RW();
+    RT_THREAD_LOCK_TMP(Tmp);
+    RT_THREAD_LOCK_RW(Tmp);
 
     /*
@@ -317,5 +386,5 @@
     }
 
-    RT_THREAD_UNLOCK_RW();
+    RT_THREAD_UNLOCK_RW(Tmp);
 }
 
@@ -343,8 +412,9 @@
 static void rtThreadRemove(PRTTHREADINT pThread)
 {
-    RT_THREAD_LOCK_RW();
+    RT_THREAD_LOCK_TMP(Tmp);
+    RT_THREAD_LOCK_RW(Tmp);
     if (ASMAtomicBitTestAndClear(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT))
         rtThreadRemoveLocked(pThread);
-    RT_THREAD_UNLOCK_RW();
+    RT_THREAD_UNLOCK_RW(Tmp);
 }
 
@@ -374,7 +444,8 @@
      * Simple tree lookup.
      */
-    RT_THREAD_LOCK_RD();
+    RT_THREAD_LOCK_TMP(Tmp);
+    RT_THREAD_LOCK_RD(Tmp);
     PRTTHREADINT pThread = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
-    RT_THREAD_UNLOCK_RD();
+    RT_THREAD_UNLOCK_RD(Tmp);
     return pThread;
 }
@@ -507,6 +578,11 @@
      */
     int rc = rtThreadNativeSetPriority(pThread, pThread->enmType);
+#ifdef IN_RING3
     AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d enmPriority=%d rc=%Vrc\n",
                      pThread, NativeThread, pThread->szName, pThread->enmType, g_enmProcessPriority, rc));
+#else
+    AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d rc=%Vrc\n",
+                     pThread, NativeThread, pThread->szName, pThread->enmType, rc));
+#endif
 
     /*
@@ -848,5 +924,5 @@
  * @param       prc             Where to store the return code of the thread. Optional.
  */
-RTR3DECL(int) RTThreadWait(RTTHREAD Thread, unsigned cMillies, int *prc)
+RTDECL(int) RTThreadWait(RTTHREAD Thread, unsigned cMillies, int *prc)
 {
     int rc = rtThreadWait(Thread, cMillies, prc, true);
@@ -885,5 +961,5 @@
     int     rc;
     if (    enmType > RTTHREADTYPE_INVALID
-        &&  enmType < RTTHREADTYPE_LAST)
+        &&  enmType < RTTHREADTYPE_END)
     {
         PRTTHREADINT pThread = rtThreadGet(Thread);
@@ -895,11 +971,12 @@
                  * Do the job.
                  */
-                RT_THREAD_UNLOCK_RW();
+                RT_THREAD_LOCK_TMP(Tmp);
+                RT_THREAD_LOCK_RW(Tmp);
                 rc = rtThreadNativeSetPriority(pThread, enmType);
                 if (RT_SUCCESS(rc))
                     ASMAtomicXchgSize(&pThread->enmType, enmType);
-                else
+                RT_THREAD_UNLOCK_RW(Tmp);
+                if (RT_FAILURE(rc))
                     Log(("RTThreadSetType: failed on thread %p (%s), rc=%Vrc!!!\n", Thread, pThread->szName, rc));
-                RT_THREAD_LOCK_RW();
             }
             else
@@ -939,4 +1016,6 @@
 
 
+#ifdef IN_RING3
+
 /**
  * Recalculates scheduling attributes for the the default process
@@ -951,7 +1030,8 @@
 int rtThreadDoCalcDefaultPriority(RTTHREADTYPE enmType)
 {
-    RT_THREAD_LOCK_RW();
+    RT_THREAD_LOCK_TMP(Tmp);
+    RT_THREAD_LOCK_RW(Tmp);
     int rc = rtSchedNativeCalcDefaultPriority(enmType);
-    RT_THREAD_UNLOCK_RW();
+    RT_THREAD_UNLOCK_RW(Tmp);
     return rc;
 }
@@ -997,5 +1077,6 @@
      * scheduling attributes defined by the specified process priority.
      */
-    RT_THREAD_LOCK_RW();
+    RT_THREAD_LOCK_TMP(Tmp);
+    RT_THREAD_LOCK_RW(Tmp);
     int rc = rtProcNativeSetPriority(enmPriority);
     if (RT_SUCCESS(rc))
@@ -1016,5 +1097,5 @@
         }
     }
-    RT_THREAD_UNLOCK_RW();
+    RT_THREAD_UNLOCK_RW(Tmp);
     LogFlow(("rtThreadDoSetProcPriority: returns %Vrc\n", rc));
     return rc;
@@ -1215,2 +1296,4 @@
 }
 
+#endif /* IN_RING3 */
+
