thread.h revision dd056d1ed5f111d091a3edba0a082b9673f3f73d
45e9809aff7304721fddb95654901b32195c9c7avboxsync/* $Id$ */
45e9809aff7304721fddb95654901b32195c9c7avboxsync/** @file
45e9809aff7304721fddb95654901b32195c9c7avboxsync * IPRT - Internal RTThread header.
45e9809aff7304721fddb95654901b32195c9c7avboxsync */
45e9809aff7304721fddb95654901b32195c9c7avboxsync
45e9809aff7304721fddb95654901b32195c9c7avboxsync/*
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Copyright (C) 2006-2007 Oracle Corporation
45e9809aff7304721fddb95654901b32195c9c7avboxsync *
45e9809aff7304721fddb95654901b32195c9c7avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
45e9809aff7304721fddb95654901b32195c9c7avboxsync * available from http://www.virtualbox.org. This file is free software;
45e9809aff7304721fddb95654901b32195c9c7avboxsync * you can redistribute it and/or modify it under the terms of the GNU
45e9809aff7304721fddb95654901b32195c9c7avboxsync * General Public License (GPL) as published by the Free Software
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
45e9809aff7304721fddb95654901b32195c9c7avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
45e9809aff7304721fddb95654901b32195c9c7avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
45e9809aff7304721fddb95654901b32195c9c7avboxsync *
45e9809aff7304721fddb95654901b32195c9c7avboxsync * The contents of this file may alternatively be used under the terms
45e9809aff7304721fddb95654901b32195c9c7avboxsync * of the Common Development and Distribution License Version 1.0
45e9809aff7304721fddb95654901b32195c9c7avboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
45e9809aff7304721fddb95654901b32195c9c7avboxsync * VirtualBox OSE distribution, in which case the provisions of the
45e9809aff7304721fddb95654901b32195c9c7avboxsync * CDDL are applicable instead of those of the GPL.
45e9809aff7304721fddb95654901b32195c9c7avboxsync *
45e9809aff7304721fddb95654901b32195c9c7avboxsync * You may elect to license modified versions of this file under the
45e9809aff7304721fddb95654901b32195c9c7avboxsync * terms and conditions of either the GPL or the CDDL or both.
45e9809aff7304721fddb95654901b32195c9c7avboxsync */
45e9809aff7304721fddb95654901b32195c9c7avboxsync
45e9809aff7304721fddb95654901b32195c9c7avboxsync#ifndef ___thread_h
45e9809aff7304721fddb95654901b32195c9c7avboxsync#define ___thread_h
45e9809aff7304721fddb95654901b32195c9c7avboxsync
45e9809aff7304721fddb95654901b32195c9c7avboxsync#include <iprt/types.h>
45e9809aff7304721fddb95654901b32195c9c7avboxsync#include <iprt/thread.h>
45e9809aff7304721fddb95654901b32195c9c7avboxsync#include <iprt/avl.h>
45e9809aff7304721fddb95654901b32195c9c7avboxsync#ifdef IN_RING3
45e9809aff7304721fddb95654901b32195c9c7avboxsync# include <iprt/process.h>
45e9809aff7304721fddb95654901b32195c9c7avboxsync# include <iprt/critsect.h>
45e9809aff7304721fddb95654901b32195c9c7avboxsync#endif
45e9809aff7304721fddb95654901b32195c9c7avboxsync#include "internal/lockvalidator.h"
45e9809aff7304721fddb95654901b32195c9c7avboxsync#include "internal/magics.h"
45e9809aff7304721fddb95654901b32195c9c7avboxsync#ifdef RT_WITH_ICONV_CACHE
45e9809aff7304721fddb95654901b32195c9c7avboxsync# include "internal/string.h"
45e9809aff7304721fddb95654901b32195c9c7avboxsync#endif
45e9809aff7304721fddb95654901b32195c9c7avboxsync
45e9809aff7304721fddb95654901b32195c9c7avboxsyncRT_C_DECLS_BEGIN
45e9809aff7304721fddb95654901b32195c9c7avboxsync
45e9809aff7304721fddb95654901b32195c9c7avboxsync
45e9809aff7304721fddb95654901b32195c9c7avboxsync/** Max thread name length. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync#define RTTHREAD_NAME_LEN 16
45e9809aff7304721fddb95654901b32195c9c7avboxsync#ifdef IPRT_WITH_GENERIC_TLS
45e9809aff7304721fddb95654901b32195c9c7avboxsync/** The number of TLS entries for the generic implementation. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync# define RTTHREAD_TLS_ENTRIES 64
45e9809aff7304721fddb95654901b32195c9c7avboxsync#endif
45e9809aff7304721fddb95654901b32195c9c7avboxsync
45e9809aff7304721fddb95654901b32195c9c7avboxsync/**
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Internal representation of a thread.
45e9809aff7304721fddb95654901b32195c9c7avboxsync */
45e9809aff7304721fddb95654901b32195c9c7avboxsynctypedef struct RTTHREADINT
45e9809aff7304721fddb95654901b32195c9c7avboxsync{
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Avl node core - the key is the native thread id. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync AVLPVNODECORE Core;
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Magic value (RTTHREADINT_MAGIC). */
45e9809aff7304721fddb95654901b32195c9c7avboxsync uint32_t u32Magic;
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Reference counter. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync uint32_t volatile cRefs;
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** The current thread state. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync RTTHREADSTATE volatile enmState;
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** Set when really sleeping. */
45e9809aff7304721fddb95654901b32195c9c7avboxsync bool volatile fReallySleeping;
45e9809aff7304721fddb95654901b32195c9c7avboxsync#if defined(RT_OS_WINDOWS) && defined(IN_RING3)
45e9809aff7304721fddb95654901b32195c9c7avboxsync /** The thread handle
* This is not valid until the create function has returned! */
uintptr_t hThread;
#endif
#if defined(RT_OS_LINUX) && defined(IN_RING3)
/** The thread ID.
* This is not valid before rtThreadMain has been called by the new thread. */
pid_t tid;
#endif
/** The user event semaphore. */
RTSEMEVENTMULTI EventUser;
/** The terminated event semaphore. */
RTSEMEVENTMULTI EventTerminated;
/** The thread type. */
RTTHREADTYPE enmType;
/** The thread creation flags. (RTTHREADFLAGS) */
unsigned fFlags;
/** Internal flags. (RTTHREADINT_FLAGS_ *) */
uint32_t fIntFlags;
/** The result code. */
int rc;
/** Thread function. */
PFNRTTHREAD pfnThread;
/** Thread function argument. */
void *pvUser;
/** Actual stack size. */
size_t cbStack;
#ifdef IN_RING3
/** The lock validator data. */
RTLOCKVALPERTHREAD LockValidator;
#endif /* IN_RING3 */
#ifdef RT_WITH_ICONV_CACHE
/** Handle cache for iconv.
* @remarks ASSUMES sizeof(void *) >= sizeof(iconv_t). */
void *ahIconvs[RTSTRICONV_END];
#endif
#ifdef IPRT_WITH_GENERIC_TLS
/** The TLS entries for this thread. */
void *apvTlsEntries[RTTHREAD_TLS_ENTRIES];
#endif
/** Thread name. */
char szName[RTTHREAD_NAME_LEN];
} RTTHREADINT;
/** Pointer to the internal representation of a thread. */
typedef RTTHREADINT *PRTTHREADINT;
/** @name RTTHREADINT::fIntFlags Masks and Bits.
* @{ */
/** Set if the thread is an alien thread.
* Clear if the thread was created by IPRT. */
#define RTTHREADINT_FLAGS_ALIEN RT_BIT(0)
/** Set if the thread has terminated.
* Clear if the thread is running. */
#define RTTHREADINT_FLAGS_TERMINATED RT_BIT(1)
/** This bit is set if the thread is in the AVL tree. */
#define RTTHREADINT_FLAG_IN_TREE_BIT 2
/** @copydoc RTTHREADINT_FLAG_IN_TREE_BIT */
#define RTTHREADINT_FLAG_IN_TREE RT_BIT(RTTHREADINT_FLAG_IN_TREE_BIT)
/** Set if it's the main thread. */
#define RTTHREADINT_FLAGS_MAIN RT_BIT(3)
/** @} */
/**
* Initialize the native part of the thread management.
*
* Generally a TLS entry will be allocated at this point (Ring-3).
*
* @returns iprt status code.
*/
DECLHIDDEN(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.
*/
DECLHIDDEN(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.
*/
DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread);
/**
* Called from rtThreadDestroy so that the TLS entry and any native data in the
* thread structure can be cleared.
*
* @param pThread The thread structure.
*/
DECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread);
/**
* Sets the priority of the thread according to the thread type
* and current process priority.
*
* The RTTHREADINT::enmType member has not yet been updated and will be updated by
* the caller on a successful return.
*
* @returns iprt status code.
* @param pThread The thread in question.
* @param enmType The thread type.
* @remark Located in sched.
*/
DECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType);
#ifdef IN_RING3
# ifdef RT_OS_WINDOWS
/**
* Callback for when a native thread is detaching.
*
* It give the Win32/64 backend a chance to terminate alien
* threads properly.
*/
DECLHIDDEN(void) rtThreadNativeDetach(void);
# endif
#endif /* !IN_RING0 */
/* thread.cpp */
DECLCALLBACK(DECLHIDDEN(int)) rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName);
DECLHIDDEN(uint32_t) rtThreadRelease(PRTTHREADINT pThread);
DECLHIDDEN(void) rtThreadTerminate(PRTTHREADINT pThread, int rc);
DECLHIDDEN(PRTTHREADINT) rtThreadGetByNative(RTNATIVETHREAD NativeThread);
DECLHIDDEN(PRTTHREADINT) rtThreadGet(RTTHREAD Thread);
DECLHIDDEN(int) rtThreadInit(void);
DECLHIDDEN(void) rtThreadTerm(void);
DECLHIDDEN(void) rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
#ifdef IN_RING3
DECLHIDDEN(int) rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority);
#endif /* !IN_RING0 */
#ifdef IPRT_WITH_GENERIC_TLS
DECLHIDDEN(void) rtThreadClearTlsEntry(RTTLS iTls);
DECLHIDDEN(void) rtThreadTlsDestruction(PRTTHREADINT pThread); /* in tls-generic.cpp */
#endif
#ifdef ___iprt_asm_h
/**
* Gets the thread state.
*
* @returns The thread state.
* @param pThread The thread.
*/
DECLINLINE(RTTHREADSTATE) rtThreadGetState(PRTTHREADINT pThread)
{
return pThread->enmState;
}
/**
* Sets the thread state.
*
* @param pThread The thread.
* @param enmNewState The new thread state.
*/
DECLINLINE(void) rtThreadSetState(PRTTHREADINT pThread, RTTHREADSTATE enmNewState)
{
AssertCompile(sizeof(pThread->enmState) == sizeof(uint32_t));
ASMAtomicWriteU32((uint32_t volatile *)&pThread->enmState, enmNewState);
}
#endif
RT_C_DECLS_END
#endif