VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win32/thread-win32.cpp@ 5285

Last change on this file since 5285 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.1 KB
Line 
1/* $Id: thread-win32.cpp 4071 2007-08-07 17:07:59Z vboxsync $ */
2/** @file
3 * innotek Portable Runtime - Threads, Win32.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP RTLOGGROUP_THREAD
23#include <Windows.h>
24
25#include <errno.h>
26#include <process.h>
27
28#include <iprt/thread.h>
29#include <iprt/log.h>
30#include <iprt/assert.h>
31#include <iprt/alloc.h>
32#include <iprt/asm.h>
33#include <iprt/err.h>
34#include "internal/thread.h"
35
36
37/*******************************************************************************
38* Defined Constants And Macros *
39*******************************************************************************/
40/** The TLS index allocated for storing the RTTHREADINT pointer. */
41static DWORD g_dwSelfTLS = TLS_OUT_OF_INDEXES;
42
43
44/*******************************************************************************
45* Internal Functions *
46*******************************************************************************/
47static unsigned __stdcall rtThreadNativeMain(void *pvArgs);
48
49
50int rtThreadNativeInit(void)
51{
52 g_dwSelfTLS = TlsAlloc();
53 if (g_dwSelfTLS == TLS_OUT_OF_INDEXES)
54 return VERR_NO_TLS_FOR_SELF;
55 return VINF_SUCCESS;
56}
57
58
59void rtThreadNativeDetach(void)
60{
61 /*
62 * Deal with alien threads.
63 */
64 PRTTHREADINT pThread = (PRTTHREADINT)TlsGetValue(g_dwSelfTLS);
65 if ( pThread
66 && (pThread->fIntFlags & RTTHREADINT_FLAGS_ALIEN))
67 {
68 rtThreadTerminate(pThread, 0);
69 TlsSetValue(g_dwSelfTLS, NULL);
70 }
71}
72
73
74int rtThreadNativeAdopt(PRTTHREADINT pThread)
75{
76 if (!TlsSetValue(g_dwSelfTLS, pThread))
77 return VERR_FAILED_TO_SET_SELF_TLS;
78 return VINF_SUCCESS;
79}
80
81
82/**
83 * Wrapper which unpacks the param stuff and calls thread function.
84 */
85static unsigned __stdcall rtThreadNativeMain(void *pvArgs)
86{
87 DWORD dwThreadId = GetCurrentThreadId();
88 PRTTHREADINT pThread = (PRTTHREADINT)pvArgs;
89
90 if (!TlsSetValue(g_dwSelfTLS, pThread))
91 AssertReleaseMsgFailed(("failed to set self TLS. lasterr=%d thread '%s'\n", GetLastError(), pThread->szName));
92
93 int rc = rtThreadMain(pThread, dwThreadId, &pThread->szName[0]);
94
95 TlsSetValue(g_dwSelfTLS, NULL);
96 _endthreadex(rc);
97 return rc;
98}
99
100
101int rtThreadNativeCreate(PRTTHREADINT pThread, PRTNATIVETHREAD pNativeThread)
102{
103 AssertReturn(pThread->cbStack < ~(unsigned)0, VERR_INVALID_PARAMETER);
104
105 /*
106 * Create the thread.
107 */
108 pThread->hThread = (uintptr_t)INVALID_HANDLE_VALUE;
109 unsigned uThreadId = 0;
110 uintptr_t hThread = _beginthreadex(NULL, (unsigned)pThread->cbStack, rtThreadNativeMain, pThread, 0, &uThreadId);
111 if (hThread != 0 && hThread != ~0U)
112 {
113 pThread->hThread = hThread;
114 *pNativeThread = uThreadId;
115 return VINF_SUCCESS;
116 }
117 return RTErrConvertFromErrno(errno);
118}
119
120
121RTDECL(RTTHREAD) RTThreadSelf(void)
122{
123 PRTTHREADINT pThread = (PRTTHREADINT)TlsGetValue(g_dwSelfTLS);
124 /** @todo import alien threads ? */
125 return pThread;
126}
127
128
129RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
130{
131 return (RTNATIVETHREAD)GetCurrentThreadId();
132}
133
134
135RTR3DECL(int) RTThreadSleep(unsigned cMillies)
136{
137 LogFlow(("RTThreadSleep: cMillies=%d\n", cMillies));
138 Sleep(cMillies);
139 LogFlow(("RTThreadSleep: returning %Vrc (cMillies=%d)\n", VINF_SUCCESS, cMillies));
140 return VINF_SUCCESS;
141}
142
143
144RTR3DECL(bool) RTThreadYield(void)
145{
146 uint64_t u64TS = ASMReadTSC();
147 Sleep(0);
148 u64TS = ASMReadTSC() - u64TS;
149 bool fRc = u64TS > 1500;
150 LogFlow(("RTThreadYield: returning %d (%llu ticks)\n", fRc, u64TS));
151 return fRc;
152}
153
154
155#if 0 /* noone is using this ... */
156/**
157 * Returns the processor number the current thread was running on during this call
158 *
159 * @returns processor nr
160 */
161static int rtThreadGetCurrentProcessorNumber(void)
162{
163 static bool fInitialized = false;
164 static DWORD (WINAPI *pfnGetCurrentProcessorNumber)(void) = NULL;
165 if (!fInitialized)
166 {
167 HMODULE hmodKernel32 = GetModuleHandle("KERNEL32.DLL");
168 if (hmodKernel32)
169 pfnGetCurrentProcessorNumber = (DWORD (WINAPI*)(void))GetProcAddress(hmodKernel32, "GetCurrentProcessorNumber");
170 fInitialized = true;
171 }
172 if (pfnGetCurrentProcessorNumber)
173 return pfnGetCurrentProcessorNumber();
174 return -1;
175}
176#endif
177
178
179RTR3DECL(int) RTThreadSetAffinity(uint64_t u64Mask)
180{
181 Assert((DWORD_PTR)u64Mask == u64Mask || u64Mask == ~(uint64_t)0);
182 DWORD dwRet = SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR)u64Mask);
183 if (dwRet)
184 return VINF_SUCCESS;
185
186 int iLastError = GetLastError();
187 AssertMsgFailed(("SetThreadAffinityMask failed, LastError=%d\n", iLastError));
188 return RTErrConvertFromWin32(iLastError);
189}
190
191
192RTR3DECL(uint64_t) RTThreadGetAffinity(void)
193{
194 /*
195 * Haven't found no query api, but the set api returns the old mask, so let's use that.
196 */
197 DWORD_PTR dwIgnored;
198 DWORD_PTR dwProcAff = 0;
199 if (GetProcessAffinityMask(GetCurrentProcess(), &dwProcAff, &dwIgnored))
200 {
201 HANDLE hThread = GetCurrentThread();
202 DWORD dwRet = SetThreadAffinityMask(hThread, dwProcAff);
203 if (dwRet)
204 {
205 DWORD dwSet = SetThreadAffinityMask(hThread, dwRet);
206 Assert(dwSet == dwProcAff); NOREF(dwRet);
207 return dwRet;
208 }
209 }
210
211 int iLastError = GetLastError();
212 AssertMsgFailed(("SetThreadAffinityMask or GetProcessAffinityMask failed, LastError=%d\n", iLastError));
213 return RTErrConvertFromWin32(iLastError);
214}
215
Note: See TracBrowser for help on using the repository browser.

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