VirtualBox

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

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

Removed rtMpClearPoke function as it's no longer required. (fixes missing 64 bits wrapper too)

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