Changeset 6957 in vbox
- Timestamp:
- Feb 14, 2008 3:10:17 PM (17 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r6910 r6957 274 274 r3/win/time-win.cpp \ 275 275 r3/win/timer-win.cpp \ 276 r3/win/tls-win.cpp \ 276 277 r3/win/utf16locale-win.cpp \ 277 278 r3/win/utf8-win.cpp \ -
trunk/src/VBox/Runtime/r3/win/tls-win.cpp
r6956 r6957 1 1 /* $Id$ */ 2 2 /** @file 3 * innotek Portable Runtime - Thread s, Win32.3 * innotek Portable Runtime - Thread Local Storage (TLS), Win32. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 200 6-2007innotek GmbH7 * Copyright (C) 2008 innotek GmbH 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 32 32 #include <Windows.h> 33 33 34 #include <errno.h>35 #include <process.h>36 37 34 #include <iprt/thread.h> 38 35 #include <iprt/log.h> 39 36 #include <iprt/assert.h> 40 #include <iprt/alloc.h>41 #include <iprt/asm.h>42 37 #include <iprt/err.h> 43 38 #include "internal/thread.h" 44 39 45 40 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; 41 AssertCompile(sizeof(RTTLS) >= sizeof(DWORD)); 51 42 52 43 53 /******************************************************************************* 54 * Internal Functions * 55 *******************************************************************************/ 56 static unsigned __stdcall rtThreadNativeMain(void *pvArgs); 57 58 59 int rtThreadNativeInit(void) 44 RTR3DECL(RTTLS) RTTlsAlloc(void) 60 45 { 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; 65 48 } 66 49 67 50 68 void rtThreadNativeDetach(void)51 RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor) 69 52 { 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) 76 56 { 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; 79 61 } 62 63 return VERR_NO_MEMORY; 80 64 } 81 65 82 66 83 int rtThreadNativeAdopt(PRTTHREADINT pThread)67 RTR3DECL(int) RTTlsFree(RTTLS iTls) 84 68 { 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 88 75 } 89 76 90 77 91 /** 92 * Wrapper which unpacks the param stuff and calls thread function. 93 */ 94 static unsigned __stdcall rtThreadNativeMain(void *pvArgs) 78 RTR3DECL(void *) RTTlsGet(RTTLS iTls) 95 79 { 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); 107 81 } 108 82 109 83 110 int rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)84 RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue) 111 85 { 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) 121 88 { 122 pThread->hThread = hThread; 123 *pNativeThread = uThreadId; 89 *ppvValue = pv; 124 90 return VINF_SUCCESS; 125 91 } 126 return RTErrConvertFromErrno(errno); 92 93 /* TlsGetValue always updates last error */ 94 *ppvValue = NULL; 95 return RTErrConvertFromWin32(GetLastError()); 127 96 } 128 97 129 98 130 RT DECL(RTTHREAD) RTThreadSelf(void)99 RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue) 131 100 { 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()); 135 104 } 136 105 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 call167 *168 * @returns processor nr169 */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 #endif186 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.