VirtualBox

Changeset 6957 in vbox


Ignore:
Timestamp:
Feb 14, 2008 3:10:17 PM (17 years ago)
Author:
vboxsync
Message:

Implemented RTTls on win32.

Location:
trunk/src/VBox/Runtime
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r6910 r6957  
    274274        r3/win/time-win.cpp \
    275275        r3/win/timer-win.cpp \
     276        r3/win/tls-win.cpp \
    276277        r3/win/utf16locale-win.cpp \
    277278        r3/win/utf8-win.cpp \
  • trunk/src/VBox/Runtime/r3/win/tls-win.cpp

    r6956 r6957  
    11/* $Id$ */
    22/** @file
    3  * innotek Portable Runtime - Threads, Win32.
     3 * innotek Portable Runtime - Thread Local Storage (TLS), Win32.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 innotek GmbH
     7 * Copyright (C) 2008 innotek GmbH
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3232#include <Windows.h>
    3333
    34 #include <errno.h>
    35 #include <process.h>
    36 
    3734#include <iprt/thread.h>
    3835#include <iprt/log.h>
    3936#include <iprt/assert.h>
    40 #include <iprt/alloc.h>
    41 #include <iprt/asm.h>
    4237#include <iprt/err.h>
    4338#include "internal/thread.h"
    4439
    4540
    46 /*******************************************************************************
    47 *   Defined Constants And Macros                                               *
    48 *******************************************************************************/
    49 /** The TLS index allocated for storing the RTTHREADINT pointer. */
    50 static DWORD g_dwSelfTLS = TLS_OUT_OF_INDEXES;
     41AssertCompile(sizeof(RTTLS) >= sizeof(DWORD));
    5142
    5243
    53 /*******************************************************************************
    54 *   Internal Functions                                                         *
    55 *******************************************************************************/
    56 static unsigned __stdcall rtThreadNativeMain(void *pvArgs);
    57 
    58 
    59 int rtThreadNativeInit(void)
     44RTR3DECL(RTTLS) RTTlsAlloc(void)
    6045{
    61     g_dwSelfTLS = TlsAlloc();
    62     if (g_dwSelfTLS == TLS_OUT_OF_INDEXES)
    63         return VERR_NO_TLS_FOR_SELF;
    64     return VINF_SUCCESS;
     46    DWORD iTls = TlsAlloc();
     47    return iTls != TLS_OUT_OF_INDEXES ? (RTTLS)iTls : NIL_RTTLS;
    6548}
    6649
    6750
    68 void rtThreadNativeDetach(void)
     51RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor)
    6952{
    70     /*
    71      * Deal with alien threads.
    72      */
    73     PRTTHREADINT pThread = (PRTTHREADINT)TlsGetValue(g_dwSelfTLS);
    74     if (    pThread
    75         &&  (pThread->fIntFlags & RTTHREADINT_FLAGS_ALIEN))
     53    AssertReturn(!pfnDestructor, VERR_NOT_SUPPORTED);
     54    DWORD iTls = TlsAlloc();
     55    if (iTls != TLS_OUT_OF_INDEXES)
    7656    {
    77         rtThreadTerminate(pThread, 0);
    78         TlsSetValue(g_dwSelfTLS, NULL);
     57        Assert((RTTLS)iTls != NIL_RTTLS);
     58        *piTls = (RTTLS)iTls;
     59        Assert((DWORD)*piTls == iTls);
     60        return VINF_SUCCESS;
    7961    }
     62
     63    return VERR_NO_MEMORY;
    8064}
    8165
    8266
    83 int rtThreadNativeAdopt(PRTTHREADINT pThread)
     67RTR3DECL(int) RTTlsFree(RTTLS iTls)
    8468{
    85     if (!TlsSetValue(g_dwSelfTLS, pThread))
    86         return VERR_FAILED_TO_SET_SELF_TLS;
    87     return VINF_SUCCESS;
     69    if (iTls == NIL_RTTLS)
     70        return VINF_SUCCESS;
     71    if (TlsFree(iTls))
     72        return VINF_SUCCESS;
     73    return RTErrConvertFromWin32(GetLastError());
     74
    8875}
    8976
    9077
    91 /**
    92  * Wrapper which unpacks the param stuff and calls thread function.
    93  */
    94 static unsigned __stdcall rtThreadNativeMain(void *pvArgs)
     78RTR3DECL(void *) RTTlsGet(RTTLS iTls)
    9579{
    96     DWORD           dwThreadId = GetCurrentThreadId();
    97     PRTTHREADINT    pThread = (PRTTHREADINT)pvArgs;
    98 
    99     if (!TlsSetValue(g_dwSelfTLS, pThread))
    100         AssertReleaseMsgFailed(("failed to set self TLS. lasterr=%d thread '%s'\n", GetLastError(), pThread->szName));
    101 
    102     int rc = rtThreadMain(pThread, dwThreadId, &pThread->szName[0]);
    103 
    104     TlsSetValue(g_dwSelfTLS, NULL);
    105     _endthreadex(rc);
    106     return rc;
     80    return TlsGetValue(iTls);
    10781}
    10882
    10983
    110 int rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
     84RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue)
    11185{
    112     AssertReturn(pThread->cbStack < ~(unsigned)0, VERR_INVALID_PARAMETER);
    113 
    114     /*
    115      * Create the thread.
    116      */
    117     pThread->hThread = (uintptr_t)INVALID_HANDLE_VALUE;
    118     unsigned    uThreadId = 0;
    119     uintptr_t   hThread = _beginthreadex(NULL, (unsigned)pThread->cbStack, rtThreadNativeMain, pThread, 0, &uThreadId);
    120     if (hThread != 0 && hThread != ~0U)
     86    void *pv = TlsGetValue(iTls);
     87    if (pv)
    12188    {
    122         pThread->hThread = hThread;
    123         *pNativeThread = uThreadId;
     89        *ppvValue = pv;
    12490        return VINF_SUCCESS;
    12591    }
    126     return RTErrConvertFromErrno(errno);
     92
     93    /* TlsGetValue always updates last error */
     94    *ppvValue = NULL;
     95    return RTErrConvertFromWin32(GetLastError());
    12796}
    12897
    12998
    130 RTDECL(RTTHREAD) RTThreadSelf(void)
     99RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue)
    131100{
    132     PRTTHREADINT pThread = (PRTTHREADINT)TlsGetValue(g_dwSelfTLS);
    133     /** @todo import alien threads ? */
    134     return pThread;
     101    if (TlsSetValue(iTls, pvValue))
     102        return VINF_SUCCESS;
     103    return RTErrConvertFromWin32(GetLastError());
    135104}
    136105
    137 
    138 RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
    139 {
    140     return (RTNATIVETHREAD)GetCurrentThreadId();
    141 }
    142 
    143 
    144 RTR3DECL(int)   RTThreadSleep(unsigned cMillies)
    145 {
    146     LogFlow(("RTThreadSleep: cMillies=%d\n", cMillies));
    147     Sleep(cMillies);
    148     LogFlow(("RTThreadSleep: returning %Vrc (cMillies=%d)\n", VINF_SUCCESS, cMillies));
    149     return VINF_SUCCESS;
    150 }
    151 
    152 
    153 RTR3DECL(bool) RTThreadYield(void)
    154 {
    155     uint64_t u64TS = ASMReadTSC();
    156     Sleep(0);
    157     u64TS = ASMReadTSC() - u64TS;
    158     bool fRc = u64TS > 1500;
    159     LogFlow(("RTThreadYield: returning %d (%llu ticks)\n", fRc, u64TS));
    160     return fRc;
    161 }
    162 
    163 
    164 #if 0 /* noone is using this ... */
    165 /**
    166  * Returns the processor number the current thread was running on during this call
    167  *
    168  * @returns processor nr
    169  */
    170 static int rtThreadGetCurrentProcessorNumber(void)
    171 {
    172     static bool           fInitialized = false;
    173     static DWORD (WINAPI *pfnGetCurrentProcessorNumber)(void) = NULL;
    174     if (!fInitialized)
    175     {
    176         HMODULE hmodKernel32 = GetModuleHandle("KERNEL32.DLL");
    177         if (hmodKernel32)
    178             pfnGetCurrentProcessorNumber = (DWORD (WINAPI*)(void))GetProcAddress(hmodKernel32, "GetCurrentProcessorNumber");
    179         fInitialized = true;
    180     }
    181     if (pfnGetCurrentProcessorNumber)
    182         return pfnGetCurrentProcessorNumber();
    183     return -1;
    184 }
    185 #endif
    186 
    187 
    188 RTR3DECL(int) RTThreadSetAffinity(uint64_t u64Mask)
    189 {
    190     Assert((DWORD_PTR)u64Mask == u64Mask || u64Mask == ~(uint64_t)0);
    191     DWORD dwRet = SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR)u64Mask);
    192     if (dwRet)
    193         return VINF_SUCCESS;
    194 
    195     int iLastError = GetLastError();
    196     AssertMsgFailed(("SetThreadAffinityMask failed, LastError=%d\n", iLastError));
    197     return RTErrConvertFromWin32(iLastError);
    198 }
    199 
    200 
    201 RTR3DECL(uint64_t) RTThreadGetAffinity(void)
    202 {
    203     /*
    204      * Haven't found no query api, but the set api returns the old mask, so let's use that.
    205      */
    206     DWORD_PTR dwIgnored;
    207     DWORD_PTR dwProcAff = 0;
    208     if (GetProcessAffinityMask(GetCurrentProcess(), &dwProcAff, &dwIgnored))
    209     {
    210         HANDLE hThread = GetCurrentThread();
    211         DWORD dwRet = SetThreadAffinityMask(hThread, dwProcAff);
    212         if (dwRet)
    213         {
    214             DWORD dwSet = SetThreadAffinityMask(hThread, dwRet);
    215             Assert(dwSet == dwProcAff); NOREF(dwRet);
    216             return dwRet;
    217         }
    218     }
    219 
    220     int iLastError = GetLastError();
    221     AssertMsgFailed(("SetThreadAffinityMask or GetProcessAffinityMask failed, LastError=%d\n", iLastError));
    222     return RTErrConvertFromWin32(iLastError);
    223 }
    224 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette