VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/thread-win.cpp@ 19167

Last change on this file since 19167 was 13837, checked in by vboxsync, 16 years ago

s/%Vr\([acfs]\)/%Rr\1/g - since I'm upsetting everyone anyway, better make the most of it...

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