VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp@ 43117

Last change on this file since 43117 was 39443, checked in by vboxsync, 13 years ago

Introduced RTThreadSleepNoLog for spinlocking in the electric fence heap. (Caused trouble with all logging enabled.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.5 KB
Line 
1/* $Id: thread-r0drv-nt.cpp 39443 2011-11-28 15:01:21Z vboxsync $ */
2/** @file
3 * IPRT - Threads, Ring-0 Driver, NT.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
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
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include "the-nt-kernel.h"
31#include "internal/iprt.h"
32#include <iprt/thread.h>
33
34#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
35# include <iprt/asm-amd64-x86.h>
36#endif
37#include <iprt/assert.h>
38#include <iprt/err.h>
39#include <iprt/mp.h>
40#include "internal-r0drv-nt.h"
41
42
43RT_C_DECLS_BEGIN
44NTSTATUS NTAPI ZwYieldExecution(void);
45RT_C_DECLS_END
46
47
48RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
49{
50 return (RTNATIVETHREAD)PsGetCurrentThread();
51}
52
53
54static int rtR0ThreadNtSleepCommon(RTMSINTERVAL cMillies)
55{
56 LARGE_INTEGER Interval;
57 Interval.QuadPart = -(int64_t)cMillies * 10000;
58 NTSTATUS rcNt = KeDelayExecutionThread(KernelMode, TRUE, &Interval);
59 switch (rcNt)
60 {
61 case STATUS_SUCCESS:
62 return VINF_SUCCESS;
63 case STATUS_ALERTED:
64 case STATUS_USER_APC:
65 return VERR_INTERRUPTED;
66 default:
67 return RTErrConvertFromNtStatus(rcNt);
68 }
69}
70
71
72RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
73{
74 return rtR0ThreadNtSleepCommon(cMillies);
75}
76
77
78RTDECL(int) RTThreadSleepCommon(RTMSINTERVAL cMillies)
79{
80 return rtR0ThreadNtSleepCommon(cMillies);
81}
82
83
84RTDECL(bool) RTThreadYield(void)
85{
86 return ZwYieldExecution() != STATUS_NO_YIELD_PERFORMED;
87}
88
89
90RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread)
91{
92 Assert(hThread == NIL_RTTHREAD);
93 KIRQL Irql = KeGetCurrentIrql();
94 if (Irql > APC_LEVEL)
95 return false;
96 if (!ASMIntAreEnabled())
97 return false;
98 return true;
99}
100
101
102RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
103{
104 Assert(hThread == NIL_RTTHREAD);
105
106 /*
107 * Read the globals and check if they are useful.
108 */
109 uint32_t const offQuantumEnd = g_offrtNtPbQuantumEnd;
110 uint32_t const cbQuantumEnd = g_cbrtNtPbQuantumEnd;
111 uint32_t const offDpcQueueDepth = g_offrtNtPbDpcQueueDepth;
112 if (!offQuantumEnd && !cbQuantumEnd && !offDpcQueueDepth)
113 return false;
114 Assert((offQuantumEnd && cbQuantumEnd) || (!offQuantumEnd && !cbQuantumEnd));
115
116 /*
117 * Disable interrupts so we won't be messed around.
118 */
119 bool fPending;
120 RTCCUINTREG fSavedFlags = ASMIntDisableFlags();
121
122#ifdef RT_ARCH_X86
123 PKPCR pPcr = (PKPCR)__readfsdword(RT_OFFSETOF(KPCR,SelfPcr));
124 uint8_t *pbPrcb = (uint8_t *)pPcr->Prcb;
125
126#elif defined(RT_ARCH_AMD64)
127 /* HACK ALERT! The offset is from windbg/vista64. */
128 PKPCR pPcr = (PKPCR)__readgsqword(RT_OFFSETOF(KPCR,Self));
129 uint8_t *pbPrcb = (uint8_t *)pPcr->CurrentPrcb;
130
131#else
132# error "port me"
133#endif
134
135 /* Check QuantumEnd. */
136 if (cbQuantumEnd == 1)
137 {
138 uint8_t volatile *pbQuantumEnd = (uint8_t volatile *)(pbPrcb + offQuantumEnd);
139 fPending = *pbQuantumEnd == TRUE;
140 }
141 else if (cbQuantumEnd == sizeof(uint32_t))
142 {
143 uint32_t volatile *pu32QuantumEnd = (uint32_t volatile *)(pbPrcb + offQuantumEnd);
144 fPending = *pu32QuantumEnd != 0;
145 }
146
147 /* Check DpcQueueDepth. */
148 if ( !fPending
149 && offDpcQueueDepth)
150 {
151 uint32_t volatile *pu32DpcQueueDepth = (uint32_t volatile *)(pbPrcb + offDpcQueueDepth);
152 fPending = *pu32DpcQueueDepth > 0;
153 }
154
155 ASMSetFlags(fSavedFlags);
156 return fPending;
157}
158
159
160RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
161{
162 /* RTThreadPreemptIsPending is only reliable if we've got both offsets and size. */
163 return g_offrtNtPbQuantumEnd != 0
164 && g_cbrtNtPbQuantumEnd != 0
165 && g_offrtNtPbDpcQueueDepth != 0;
166}
167
168
169RTDECL(bool) RTThreadPreemptIsPossible(void)
170{
171 /* yes, kernel preemption is possible. */
172 return true;
173}
174
175
176RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
177{
178 AssertPtr(pState);
179 Assert(pState->uchOldIrql == 255);
180 Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
181
182 KeRaiseIrql(DISPATCH_LEVEL, &pState->uchOldIrql);
183 RT_ASSERT_PREEMPT_CPUID_DISABLE(pState);
184}
185
186
187RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState)
188{
189 AssertPtr(pState);
190
191 RT_ASSERT_PREEMPT_CPUID_RESTORE(pState);
192 KeLowerIrql(pState->uchOldIrql);
193 pState->uchOldIrql = 255;
194}
195
196
197RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
198{
199 Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
200
201 KIRQL CurIrql = KeGetCurrentIrql();
202 return CurIrql > PASSIVE_LEVEL; /** @todo Is there a more correct way? */
203}
204
Note: See TracBrowser for help on using the repository browser.

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