VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/nt/semmutex-r0drv-nt.cpp@ 25536

Last change on this file since 25536 was 25433, checked in by vboxsync, 15 years ago

semmutex-r0drv-nt.cpp: Corrected the RTSemMutexRequest implementation (it's a non-interruptible wait) and added RTSemMutexRequestNoResume.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.5 KB
Line 
1/* $Id: semmutex-r0drv-nt.cpp 25433 2009-12-16 14:55:18Z vboxsync $ */
2/** @file
3 * IPRT - Mutex Semaphores, 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.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/*******************************************************************************
34* Header Files *
35*******************************************************************************/
36#include "the-nt-kernel.h"
37#include <iprt/semaphore.h>
38#include <iprt/alloc.h>
39#include <iprt/assert.h>
40#include <iprt/asm.h>
41#include <iprt/err.h>
42
43#include "internal/magics.h"
44
45
46/*******************************************************************************
47* Structures and Typedefs *
48*******************************************************************************/
49/**
50 * NT mutex semaphore.
51 */
52typedef struct RTSEMMUTEXINTERNAL
53{
54 /** Magic value (RTSEMMUTEX_MAGIC). */
55 uint32_t volatile u32Magic;
56#ifdef RT_USE_FAST_MUTEX
57 /** The fast mutex object. */
58 FAST_MUTEX Mutex;
59#else
60 /** The NT Mutex object. */
61 KMUTEX Mutex;
62#endif
63} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
64
65
66/* Undefine debug mappings. */
67#undef RTSemMutexRequest
68#undef RTSemMutexRequestNoResume
69
70
71RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
72{
73 Assert(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *));
74 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pMutexInt));
75 if (pMutexInt)
76 {
77 pMutexInt->u32Magic = RTSEMMUTEX_MAGIC;
78#ifdef RT_USE_FAST_MUTEX
79 ExInitializeFastMutex(&pMutexInt->Mutex);
80#else
81 KeInitializeMutex(&pMutexInt->Mutex, 0);
82#endif
83 *pMutexSem = pMutexInt;
84 return VINF_SUCCESS;
85 }
86 return VERR_NO_MEMORY;
87}
88
89
90RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem)
91{
92 /*
93 * Validate input.
94 */
95 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
96 if (!pMutexInt)
97 return VERR_INVALID_PARAMETER;
98 AssertReturn(pMutexInt->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
99
100 /*
101 * Invalidate it and signal the object just in case.
102 */
103 AssertReturn(ASMAtomicCmpXchgU32(&pMutexInt->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
104 RTMemFree(pMutexInt);
105 return VINF_SUCCESS;
106}
107
108
109/**
110 * Internal worker for RTSemMutexRequest and RTSemMutexRequestNoResume
111 *
112 * @returns IPRT status code.
113 * @param MutexSem The mutex handle.
114 * @param cMillies The timeout.
115 * @param fInterruptible Whether it's interruptible
116 * (RTSemMutexRequestNoResume) or not
117 * (RTSemMutexRequest).
118 */
119static int rtSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies, BOOLEAN fInterruptible)
120{
121 /*
122 * Validate input.
123 */
124 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
125 if (!pMutexInt)
126 return VERR_INVALID_PARAMETER;
127 AssertReturn(pMutexInt->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
128
129 /*
130 * Get the mutex.
131 */
132#ifdef RT_USE_FAST_MUTEX
133 AssertMsg(cMillies == RT_INDEFINITE_WAIT, ("timeouts are not supported when using fast mutexes!\n"));
134 ExAcquireFastMutex(&pMutexInt->Mutex);
135#else /* !RT_USE_FAST_MUTEX */
136 NTSTATUS rcNt;
137 if (cMillies == RT_INDEFINITE_WAIT)
138 rcNt = KeWaitForSingleObject(&pMutexInt->Mutex, Executive, KernelMode, fInterruptible, NULL);
139 else
140 {
141 LARGE_INTEGER Timeout;
142 Timeout.QuadPart = -(int64_t)cMillies * 10000;
143 rcNt = KeWaitForSingleObject(&pMutexInt->Mutex, Executive, KernelMode, fInterruptible, &Timeout);
144 }
145 switch (rcNt)
146 {
147 case STATUS_SUCCESS:
148 if (pMutexInt->u32Magic == RTSEMMUTEX_MAGIC)
149 return VINF_SUCCESS;
150 return VERR_SEM_DESTROYED;
151
152 case STATUS_ALERTED:
153 case STATUS_USER_APC:
154 Assert(fInterruptible);
155 return VERR_INTERRUPTED;
156
157 case STATUS_TIMEOUT:
158 return VERR_TIMEOUT;
159
160 default:
161 AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p: wait returned %lx!\n",
162 pMutexInt->u32Magic, pMutexInt, (long)rcNt));
163 return VERR_INTERNAL_ERROR;
164 }
165#endif /* !RT_USE_FAST_MUTEX */
166 return VINF_SUCCESS;
167}
168
169
170RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
171{
172 return rtSemMutexRequest(MutexSem, cMillies, FALSE /*fInterruptible*/);
173}
174
175
176RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
177{
178 return RTSemMutexRequest(MutexSem, cMillies);
179}
180
181
182RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
183{
184 return rtSemMutexRequest(MutexSem, cMillies, TRUE /*fInterruptible*/);
185}
186
187
188RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
189{
190 return RTSemMutexRequestNoResume(MutexSem, cMillies);
191}
192
193
194RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
195{
196 /*
197 * Validate input.
198 */
199 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
200 if (!pMutexInt)
201 return VERR_INVALID_PARAMETER;
202 AssertReturn(pMutexInt->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
203
204 /*
205 * Release the mutex.
206 */
207#ifdef RT_USE_FAST_MUTEX
208 ExReleaseFastMutex(&pMutexInt->Mutex);
209#else
210 KeReleaseMutex(&pMutexInt->Mutex, FALSE /*Wait*/);
211#endif
212 return VINF_SUCCESS;
213}
214
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