thread.cpp revision 45fdb697e9030f33bf5fabea82ca7eeafab2f6af
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * IPRT - Threads, common routines.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Copyright (C) 2006-2007 Oracle Corporation
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * available from http://www.virtualbox.org. This file is free software;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * General Public License (GPL) as published by the Free Software
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * The contents of this file may alternatively be used under the terms
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * of the Common Development and Distribution License Version 1.0
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * VirtualBox OSE distribution, in which case the provisions of the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * CDDL are applicable instead of those of the GPL.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * You may elect to license modified versions of this file under the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * terms and conditions of either the GPL or the CDDL or both.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/*******************************************************************************
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync* Header Files *
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync*******************************************************************************/
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/*******************************************************************************
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync* Defined Constants And Macros *
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync*******************************************************************************/
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync# define RT_THREAD_LOCK_RW() RTSpinlockAcquire(g_ThreadSpinlock)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync# define RT_THREAD_UNLOCK_RW() RTSpinlockRelease(g_ThreadSpinlock)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync# define RT_THREAD_LOCK_RD() RTSpinlockAcquire(g_ThreadSpinlock)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync# define RT_THREAD_UNLOCK_RD() RTSpinlockRelease(g_ThreadSpinlock)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/*******************************************************************************
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync* Global Variables *
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync*******************************************************************************/
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/** The AVL thread containing the threads. */
#ifdef IN_RING3
static bool g_frtThreadInitialized;
#ifdef IN_RING3
static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName);
static PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName);
#ifdef IN_RING3
rc = RTSemRWCreateEx(&g_ThreadRWSem, RTSEMRW_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
g_frtThreadInitialized = true;
return VINF_SUCCESS;
int rc;
g_frtThreadInitialized = true;
return VINF_SUCCESS;
return rc;
#ifdef IN_RING3
#ifdef IN_RING3
rtThreadInit();
rtThreadInit();
static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName)
int rc;
if (pThread)
return rc;
RTDECL(int) RTThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, const char *pszName, PRTTHREAD pThread)
int rc;
if (pThread)
return rc;
return hSelf;
PRTTHREADINT rtThreadAlloc(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName)
if (pThread)
int rc;
#ifdef IN_RING3
#ifdef RT_WITH_ICONV_CACHE
return pThread;
bool fRc;
if (pThreadOther)
AssertMsg(pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN, ("%p:%s; %p:%s\n", pThread, pThread->szName, pThreadOther, pThreadOther->szName));
AssertReleaseMsg(fRc, ("Lock problem? %p (%RTnthrd) %s\n", pThread, NativeThread, pThread->szName));
AssertMsg(pThread2 == pThread, ("%p(%s) != %p (%p/%s)\n", pThread2, pThread2 ? pThread2->szName : "<null>",
return pThread;
return pThread;
if (!cRefs)
cRefs = 0;
AssertFailed();
return cRefs;
#ifdef IN_RING3
#ifdef RT_WITH_ICONV_CACHE
#ifdef IN_RING3
#ifdef IPRT_WITH_GENERIC_TLS
DECLCALLBACK(DECLHIDDEN(int)) rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName)
int rc;
#ifdef IN_RING3
AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d enmPriority=%d rc=%Rrc\n",
#ifdef RTSEMRW_STRICT
Log(("rtThreadMain: Terminating: rc=%d pThread=%p NativeThread=%RTnthrd Name=%s pfnThread=%p pvUser=%p\n",
return rc;
int rc;
LogFlow(("RTThreadCreate: pThread=%p pfnThread=%p pvUser=%p cbStack=%#x enmType=%d fFlags=%#x pszName=%p:{%s}\n",
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
AssertMsgFailed(("pszName=%s (max len is %d because of logging)\n", pszName, RTTHREAD_NAME_LEN - 1));
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (pThreadInt)
if (pThread)
return VINF_SUCCESS;
return rc;
int rc;
return rc;
if (pThread)
return NativeThread;
return NIL_RTNATIVETHREAD;
if (pThread)
return pThread;
return NIL_RTTHREAD;
if (pThread)
return szName;
return (char *)NULL;
return (char *)NULL;
if (pThread)
return szName;
return (char *)NULL;
return VERR_INVALID_PARAMETER;
if (!pThread)
return VERR_INVALID_HANDLE;
return VINF_SUCCESS;
if (pThread)
return fRc;
return g_frtThreadInitialized;
int rc;
if (pThread)
return rc;
int rc;
if (pThread)
return rc;
int rc;
if (pThread)
return rc;
int rc;
if (pThread)
return rc;
if (pThread)
if (fAutoResume)
if (prc)
return rc;
return rc;
int rc;
if (pThread)
return rc;
if (pThread)
return enmType;
#ifdef IN_RING3
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
return rc;
if (pThread)
return enmState;
if (pThread)
return enmState;
switch (enmState)
#ifdef IPRT_WITH_GENERIC_TLS
RTAvlPVDoWithAll(&g_ThreadTree, true /* fFromLeft*/, rtThreadClearTlsEntryCallback, (void *)(uintptr_t)iTls);