thread.h revision 881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/* $Id$ */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** @file
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * InnoTek Portable Runtime - Internal RTThread header.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License as published by the Free Software Foundation,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * If you received this file as part of a commercial VirtualBox
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * distribution, then only the terms of your commercial VirtualBox
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * license agreement apply instead of the previous paragraph.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#ifndef __thread_h__
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#define __thread_h__
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <iprt/types.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <iprt/thread.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <iprt/avl.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#ifdef IN_RING3
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync# include <iprt/process.h>
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync# include <iprt/critsect.h>
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#include "internal/magics.h"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync__BEGIN_DECLS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/**
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * The thread state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef enum RTTHREADSTATE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync{
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The usual invalid 0 value. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_INVALID = 0,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The thread is being initialized. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_INITIALIZING,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The thread has terminated */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_TERMINATED,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Probably running. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_RUNNING,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Waiting on a critical section. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_CRITSECT,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Waiting on a mutex. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_MUTEX,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Waiting on a event semaphore. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_EVENT,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Waiting on a event multiple wakeup semaphore. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_EVENTMULTI,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The thread is sleeping. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_SLEEP,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The usual 32-bit size hack. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE_32BIT_HACK = 0x7fffffff
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync} RTTHREADSTATE;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Checks if a thread state indicates that the thread is sleeping. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define RTTHREAD_IS_SLEEPING(enmState) ( (enmState) == RTTHREADSTATE_CRITSECT \
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync || (enmState) == RTTHREADSTATE_MUTEX \
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync || (enmState) == RTTHREADSTATE_EVENT \
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync || (enmState) == RTTHREADSTATE_EVENTMULTI \
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync || (enmState) == RTTHREADSTATE_SLEEP \
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync )
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Max thread name length. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define RTTHREAD_NAME_LEN 16
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/**
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Internal represenation of a thread.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef struct RTTHREADINT
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync{
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Avl node core - the key is the native thread id. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AVLPVNODECORE Core;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Magic value (RTTHREADINT_MAGIC). */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uint32_t u32Magic;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Reference counter. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uint32_t volatile cRefs;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The current thread state. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADSTATE volatile enmState;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#if defined(__WIN__) && defined(IN_RING3)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The thread handle.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This is not valid until the create function has returned! */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uintptr_t hThread;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The user event semaphore. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTSEMEVENTMULTI EventUser;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The terminated event semaphore. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTSEMEVENTMULTI EventTerminated;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The thread type. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTTHREADTYPE enmType;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The thread creation flags. (RTTHREADFLAGS) */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync unsigned fFlags;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Internal flags. (RTTHREADINT_FLAGS_ *) */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uint32_t fIntFlags;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** The result code. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync int rc;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Thread function. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PFNRTTHREAD pfnThread;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Thread function argument. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync void *pvUser;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Actual stack size. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync size_t cbStack;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#ifdef IN_RING3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** What we're blocking on. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync union RTTHREADINTBLOCKID
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync uint64_t u64;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PRTCRITSECT pCritSect;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTSEMEVENT Event;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTSEMEVENTMULTI EventMulti;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTSEMMUTEX Mutex;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync } Block;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Where we're blocking. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync const char volatile *pszBlockFile;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Where we're blocking. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync unsigned volatile uBlockLine;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Where we're blocking. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RTUINTPTR volatile uBlockId;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif /* IN_RING3 */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Thread name. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync char szName[RTTHREAD_NAME_LEN];
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync} RTTHREADINT, *PRTTHREADINT;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** @name RTTHREADINT::fIntFlags Masks and Bits.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @{ */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Set if the thread is an alien thread.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Clear if the thread was created by IPRT. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define RTTHREADINT_FLAGS_ALIEN BIT(0)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Set if the thread has terminated.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Clear if the thread is running. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define RTTHREADINT_FLAGS_TERMINATED 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 BIT(RTTHREADINT_FLAG_IN_TREE_BIT)
/** @} */
/**
* Initialize the native part of the thread management.
*
* 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);
/**
* 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 Thread The thread in question.
* @param enmType The thread type.
* @remark Located in sched.
*/
int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType);
#ifdef IN_RING3
# ifdef __WIN__
/**
* Callback for when a native thread is detaching.
*
* It give the Win32/64 backend a chance to terminate alien
* threads properly.
*/
void rtThreadNativeDetach(void);
# endif
#endif /* !IN_RING0 */
/* thread.cpp */
int rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName);
void rtThreadBlocking(PRTTHREADINT pThread, RTTHREADSTATE enmState, uint64_t u64Block,
const char *pszFile, unsigned uLine, RTUINTPTR uId);
void rtThreadUnblocked(PRTTHREADINT pThread, RTTHREADSTATE enmCurState);
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 */
__END_DECLS
#endif