From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- src/VBox/Runtime/include/internal/thread.h | 325 +++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 src/VBox/Runtime/include/internal/thread.h (limited to 'src/VBox/Runtime/include/internal/thread.h') diff --git a/src/VBox/Runtime/include/internal/thread.h b/src/VBox/Runtime/include/internal/thread.h new file mode 100644 index 00000000..92af0569 --- /dev/null +++ b/src/VBox/Runtime/include/internal/thread.h @@ -0,0 +1,325 @@ +/* $Id: thread.h $ */ +/** @file + * IPRT - Internal RTThread header. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program 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 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_INTERNAL_thread_h +#define IPRT_INCLUDED_INTERNAL_thread_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include +#include +#include +#ifdef IN_RING3 +# include +# include +#endif +#include "internal/lockvalidator.h" +#include "internal/magics.h" +#ifdef RT_WITH_ICONV_CACHE +# include "internal/string.h" +#endif +#if defined(IPRT_NO_CRT) && defined(IN_RING3) +# include "internal/nocrt.h" +#endif + +RT_C_DECLS_BEGIN + + +#ifdef IPRT_WITH_GENERIC_TLS +/** The number of TLS entries for the generic implementation. */ +# define RTTHREAD_TLS_ENTRIES 64 +#endif + +/** + * Internal representation of a thread. + */ +typedef struct RTTHREADINT +{ + /** Avl node core - the key is the native thread id. */ + AVLPVNODECORE Core; + /** Magic value (RTTHREADINT_MAGIC). */ + uint32_t u32Magic; + /** Reference counter. */ + uint32_t volatile cRefs; + /** The current thread state. */ + RTTHREADSTATE volatile enmState; + /** Set when really sleeping. */ + bool volatile fReallySleeping; +#if defined(RT_OS_WINDOWS) && defined(IN_RING3) + /** 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 +#if defined(RT_OS_SOLARIS) && defined(IN_RING0) + /** Debug thread ID needed for thread_join. */ + uint64_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]; +#if defined(IPRT_NO_CRT) && defined(IN_RING3) + /** No-CRT per thread data. */ + RTNOCRTTHREADDATA NoCrt; +#endif +} 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) +/** @} */ + +/** Counters for each thread type. */ +extern DECL_HIDDEN_DATA(uint32_t volatile) g_acRTThreadTypeStats[RTTHREADTYPE_END]; + + +/** + * 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); + +#ifdef IN_RING3 +/** + * Called when IPRT was first initialized in unobtrusive mode and later changed + * to obtrustive. + * + * This is only applicable in ring-3. + */ +DECLHIDDEN(void) rtThreadNativeReInitObtrusive(void); +#endif + +/** + * 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); + +#ifdef IN_RING3 +/** + * Called to check whether the thread is still alive or not before we start + * waiting. + * + * This is a kludge to deal with windows threads being killed wholesale in + * certain process termination scenarios and we don't want to hang the last + * thread because it's waiting on the semaphore of a dead thread. + * + * @returns true if alive, false if not. + * @param pThread The thread structure. + */ +DECLHIDDEN(bool) rtThreadNativeIsAliveKludge(PRTTHREADINT pThread); +#endif + +#ifdef IN_RING0 +/** + * Called from rtThreadWait when the last thread has completed in order to make + * sure it's all the way out of IPRT before RTR0Term is called. + * + * @param pThread The thread structure. + */ +DECLHIDDEN(void) rtThreadNativeWaitKludge(PRTTHREADINT pThread); +#endif + + +/** + * 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); + +/** + * Internal function for informing the debugger about a thread. + * @param pThread The thread. May differ from the calling thread. + */ +DECLHIDDEN(void) rtThreadNativeInformDebugger(PRTTHREADINT pThread); +# endif +#endif /* IN_RING3 */ + + +/* thread.cpp */ +DECL_HIDDEN_CALLBACK(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); +#ifdef IN_RING3 +DECLHIDDEN(void) rtThreadReInitObtrusive(void); +#endif +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 RT_OS_WINDOWS +DECLHIDDEN(void) rtThreadWinTlsDestruction(void); /* in tls-win.cpp */ +#endif + +/* thread-posix.cpp */ +#ifdef IN_RING3 +# if !defined(RT_OS_WINDOWS) && !defined(RT_OS_OS2) && !defined(RT_OS_DARWIN) +# define RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY +# endif +# ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY +DECLHIDDEN(bool) rtThreadPosixPriorityProxyStart(void); +DECLHIDDEN(int) rtThreadPosixPriorityProxyCall(PRTTHREADINT pTargetThread, PFNRT pfnFunction, int cArgs, ...); +# endif +#endif + +#ifdef IPRT_INCLUDED_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 /* !IPRT_INCLUDED_INTERNAL_thread_h */ -- cgit v1.2.3