VirtualBox

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

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

iprt: Adjuested the remaining RTSemMutex implementations.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.7 KB
Line 
1/* $Id: semmutex-r0drv-nt.cpp 25714 2010-01-11 12:40:15Z vboxsync $ */
2/** @file
3 * IPRT - Mutex Semaphores, Ring-0 Driver, NT.
4 */
5
6/*
7 * Copyright (C) 2006-2010 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
67RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phMutexSem)
68{
69 return RTSemMutexCreateEx(phMutexSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
70}
71
72
73RTDECL(int) RTSemMutexCreateEx(PRTSEMMUTEX phMutexSem, uint32_t fFlags,
74 RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...)
75{
76 AssertReturn(!(fFlags & ~RTSEMMUTEX_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
77
78 AssertCompile(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *));
79 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis));
80 if (!pThis)
81 return VERR_NO_MEMORY;
82
83 pThis->u32Magic = RTSEMMUTEX_MAGIC;
84#ifdef RT_USE_FAST_MUTEX
85 ExInitializeFastMutex(&pThis->Mutex);
86#else
87 KeInitializeMutex(&pThis->Mutex, 0);
88#endif
89
90 *phMutexSem = pThis;
91 return VINF_SUCCESS;
92}
93
94
95RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem)
96{
97 /*
98 * Validate input.
99 */
100 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem;
101 if (pThis == NIL_RTSEMMUTEX)
102 return VINF_SUCCESS;
103 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
104 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
105
106 /*
107 * Invalidate it and signal the object just in case.
108 */
109 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
110 RTMemFree(pThis);
111 return VINF_SUCCESS;
112}
113
114
115/**
116 * Internal worker for RTSemMutexRequest and RTSemMutexRequestNoResume
117 *
118 * @returns IPRT status code.
119 * @param MutexSem The mutex handle.
120 * @param cMillies The timeout.
121 * @param fInterruptible Whether it's interruptible
122 * (RTSemMutexRequestNoResume) or not
123 * (RTSemMutexRequest).
124 */
125static int rtSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies, BOOLEAN fInterruptible)
126{
127 /*
128 * Validate input.
129 */
130 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem;
131 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
132 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
133
134 /*
135 * Get the mutex.
136 */
137#ifdef RT_USE_FAST_MUTEX
138 AssertMsg(cMillies == RT_INDEFINITE_WAIT, ("timeouts are not supported when using fast mutexes!\n"));
139 ExAcquireFastMutex(&pThis->Mutex);
140#else /* !RT_USE_FAST_MUTEX */
141 NTSTATUS rcNt;
142 if (cMillies == RT_INDEFINITE_WAIT)
143 rcNt = KeWaitForSingleObject(&pThis->Mutex, Executive, KernelMode, fInterruptible, NULL);
144 else
145 {
146 LARGE_INTEGER Timeout;
147 Timeout.QuadPart = -(int64_t)cMillies * 10000;
148 rcNt = KeWaitForSingleObject(&pThis->Mutex, Executive, KernelMode, fInterruptible, &Timeout);
149 }
150 switch (rcNt)
151 {
152 case STATUS_SUCCESS:
153 if (pThis->u32Magic == RTSEMMUTEX_MAGIC)
154 return VINF_SUCCESS;
155 return VERR_SEM_DESTROYED;
156
157 case STATUS_ALERTED:
158 case STATUS_USER_APC:
159 Assert(fInterruptible);
160 return VERR_INTERRUPTED;
161
162 case STATUS_TIMEOUT:
163 return VERR_TIMEOUT;
164
165 default:
166 AssertMsgFailed(("pThis->u32Magic=%RX32 pThis=%p: wait returned %lx!\n",
167 pThis->u32Magic, pThis, (long)rcNt));
168 return VERR_INTERNAL_ERROR;
169 }
170#endif /* !RT_USE_FAST_MUTEX */
171 return VINF_SUCCESS;
172}
173
174
175#undef RTSemMutexRequest
176RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
177{
178 return rtSemMutexRequest(MutexSem, cMillies, FALSE /*fInterruptible*/);
179}
180
181
182RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
183{
184 return RTSemMutexRequest(MutexSem, cMillies);
185}
186
187
188#undef RTSemMutexRequestNoResume
189RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX MutexSem, unsigned cMillies)
190{
191 return rtSemMutexRequest(MutexSem, cMillies, TRUE /*fInterruptible*/);
192}
193
194
195RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX MutexSem, unsigned cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
196{
197 return RTSemMutexRequestNoResume(MutexSem, cMillies);
198}
199
200
201RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
202{
203 /*
204 * Validate input.
205 */
206 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)MutexSem;
207 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
208 AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
209
210 /*
211 * Release the mutex.
212 */
213#ifdef RT_USE_FAST_MUTEX
214 ExReleaseFastMutex(&pThis->Mutex);
215#else
216 KeReleaseMutex(&pThis->Mutex, FALSE /*Wait*/);
217#endif
218 return VINF_SUCCESS;
219}
220
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