Changeset 45152 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Mar 23, 2013 8:36:23 PM (12 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 1 added
- 11 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r45091 r45152 181 181 VMMAll/PDMAll.cpp \ 182 182 VMMAll/PDMAllCritSect.cpp \ 183 VMMAll/PDMAllCritSectRw.cpp \ 184 VMMAll/PDMAllCritSectBoth.cpp \ 183 185 VMMAll/PDMAllQueue.cpp \ 184 186 VMMAll/PGMAll.cpp \ … … 412 414 VMMAll/PDMAll.cpp \ 413 415 VMMAll/PDMAllCritSect.cpp \ 416 VMMAll/PDMAllCritSectBoth.cpp \ 414 417 VMMAll/PDMAllQueue.cpp \ 415 418 VMMAll/PGMAll.cpp \ … … 519 522 VMMAll/PDMAll.cpp \ 520 523 VMMAll/PDMAllCritSect.cpp \ 524 VMMAll/PDMAllCritSectBoth.cpp \ 521 525 VMMAll/PDMAllQueue.cpp \ 522 526 VMMAll/PGMAll.cpp \ -
trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
r44528 r45152 1 1 /* $Id$ */ 2 2 /** @file 3 * PDM - Critical Sections, All Contexts.3 * PDM - Write-Only Critical Section, All Contexts. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2006-201 2Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 176 176 * @returns VINF_SUCCESS if entered successfully. 177 177 * @returns rcBusy when encountering a busy critical section in GC/R0. 178 * @returns VERR_SEM_DESTROYED if the critical section is dead. 178 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 179 * during the operation. 179 180 * 180 181 * @param pCritSect The PDM critical section to enter. … … 312 313 * 313 314 * @returns VINF_SUCCESS if entered successfully. 314 * @returns rcBusy when encountering a busy critical section in GC/R0. 315 * @returns VERR_SEM_DESTROYED if the critical section is dead. 315 * @returns rcBusy when encountering a busy critical section in RC/R0. 316 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 317 * during the operation. 316 318 * 317 319 * @param pCritSect The PDM critical section to enter. 318 * @param rcBusy The status code to return when we're in GC or R0320 * @param rcBusy The status code to return when we're in RC or R0 319 321 * and the section is busy. Pass VINF_SUCCESS to 320 322 * acquired the critical section thru a ring-3 … … 336 338 * 337 339 * @returns VINF_SUCCESS if entered successfully. 338 * @returns rcBusy when encountering a busy critical section in GC/R0. 339 * @returns VERR_SEM_DESTROYED if the critical section is dead. 340 * @returns rcBusy when encountering a busy critical section in RC/R0. 341 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 342 * during the operation. 340 343 * 341 344 * @param pCritSect The PDM critical section to enter. 342 * @param rcBusy The status code to return when we're in GC or R0345 * @param rcBusy The status code to return when we're in RC or R0 343 346 * and the section is busy. Pass VINF_SUCCESS to 344 347 * acquired the critical section thru a ring-3 … … 370 373 * @retval VERR_SEM_BUSY if the critsect was owned. 371 374 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 372 * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. 375 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 376 * during the operation. 373 377 * 374 378 * @param pCritSect The critical section. … … 425 429 * @retval VERR_SEM_BUSY if the critsect was owned. 426 430 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 427 * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. 431 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 432 * during the operation. 428 433 * 429 434 * @param pCritSect The critical section. … … 446 451 * @retval VERR_SEM_BUSY if the critsect was owned. 447 452 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 448 * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting. 453 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 454 * during the operation. 449 455 * 450 456 * @param pCritSect The critical section. … … 475 481 * @returns VINF_SUCCESS if entered successfully. 476 482 * @returns rcBusy when encountering a busy critical section in GC/R0. 477 * @returns VERR_SEM_DESTROYED if the critical section is dead. 483 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 484 * during the operation. 478 485 * 479 486 * @param pCritSect The PDM critical section to enter. … … 623 630 uint32_t i = pVCpu->pdm.s.cQueuedCritSectLeaves++; 624 631 LogFlow(("PDMCritSectLeave: [%d]=%p => R3\n", i, pCritSect)); 625 AssertFatal(i < RT_ELEMENTS(pVCpu->pdm.s.apQueuedCritSect sLeaves));626 pVCpu->pdm.s.apQueuedCritSect sLeaves[i] = MMHyperCCToR3(pVM, pCritSect);632 AssertFatal(i < RT_ELEMENTS(pVCpu->pdm.s.apQueuedCritSectLeaves)); 633 pVCpu->pdm.s.apQueuedCritSectLeaves[i] = MMHyperCCToR3(pVM, pCritSect); 627 634 VMCPU_FF_SET(pVCpu, VMCPU_FF_PDM_CRITSECT); 628 635 VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3); … … 634 641 return VINF_SUCCESS; 635 642 } 636 637 638 #if defined(IN_RING3) || defined(IN_RING0)639 /**640 * Process the critical sections queued for ring-3 'leave'.641 *642 * @param pVCpu Pointer to the VMCPU.643 */644 VMMDECL(void) PDMCritSectFF(PVMCPU pVCpu)645 {646 Assert(pVCpu->pdm.s.cQueuedCritSectLeaves > 0);647 648 const RTUINT c = pVCpu->pdm.s.cQueuedCritSectLeaves;649 for (RTUINT i = 0; i < c; i++)650 {651 # ifdef IN_RING3652 PPDMCRITSECT pCritSect = pVCpu->pdm.s.apQueuedCritSectsLeaves[i];653 # else654 PPDMCRITSECT pCritSect = (PPDMCRITSECT)MMHyperR3ToCC(pVCpu->CTX_SUFF(pVM), pVCpu->pdm.s.apQueuedCritSectsLeaves[i]);655 # endif656 657 PDMCritSectLeave(pCritSect);658 LogFlow(("PDMR3CritSectFF: %p\n", pCritSect));659 }660 661 pVCpu->pdm.s.cQueuedCritSectLeaves = 0;662 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PDM_CRITSECT);663 }664 #endif /* IN_RING3 || IN_RING0 */665 643 666 644 … … 748 726 return RTCritSectGetRecursion(&pCritSect->s.Core); 749 727 } 728 -
trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp
r45119 r45152 29 29 * Header Files * 30 30 *******************************************************************************/ 31 #define RTCRITSECTRW_WITHOUT_REMAPPING 32 #define RTASSERT_QUIET 33 #include <iprt/critsect.h> 34 #include "internal/iprt.h" 35 31 #define LOG_GROUP LOG_GROUP_PDM//_CRITSECT 32 #include "PDMInternal.h" 33 #include <VBox/vmm/pdmcritsectrw.h> 34 #include <VBox/vmm/mm.h> 35 #include <VBox/vmm/vmm.h> 36 #include <VBox/vmm/vm.h> 37 #include <VBox/err.h> 38 #include <VBox/vmm/hm.h> 39 40 #include <VBox/log.h> 36 41 #include <iprt/asm.h> 42 #include <iprt/asm-amd64-x86.h> 37 43 #include <iprt/assert.h> 38 #include <iprt/err.h> 39 #include <iprt/lockvalidator.h> 40 #include <iprt/mem.h> 41 #include <iprt/semaphore.h> 42 #include <iprt/thread.h> 43 44 #include "internal/magics.h" 45 #include "internal/strict.h" 44 #ifdef IN_RING3 45 # include <iprt/lockvalidator.h> 46 # include <iprt/semaphore.h> 47 #endif 48 #if defined(IN_RING3) || defined(IN_RING0) 49 # include <iprt/thread.h> 50 #endif 46 51 47 52 … … 49 54 * Defined Constants And Macros * 50 55 *******************************************************************************/ 51 /* Note! Using RTCSRW instead of RTCRITSECTRW to save space. */ 52 #define RTCSRW_CNT_BITS 15 53 #define RTCSRW_CNT_MASK UINT64_C(0x00007fff) 54 55 #define RTCSRW_CNT_RD_SHIFT 0 56 #define RTCSRW_CNT_RD_MASK (RTCSRW_CNT_MASK << RTCSRW_CNT_RD_SHIFT) 57 #define RTCSRW_CNT_WR_SHIFT 16 58 #define RTCSRW_CNT_WR_MASK (RTCSRW_CNT_MASK << RTCSRW_CNT_WR_SHIFT) 59 #define RTCSRW_DIR_SHIFT 31 60 #define RTCSRW_DIR_MASK RT_BIT_64(RTCSRW_DIR_SHIFT) 61 #define RTCSRW_DIR_READ UINT64_C(0) 62 #define RTCSRW_DIR_WRITE UINT64_C(1) 63 64 #define RTCSRW_WAIT_CNT_RD_SHIFT 32 65 #define RTCSRW_WAIT_CNT_RD_MASK (RTCSRW_CNT_MASK << RTCSRW_WAIT_CNT_RD_SHIFT) 66 //#define RTCSRW_WAIT_CNT_WR_SHIFT 48 67 //#define RTCSRW_WAIT_CNT_WR_MASK (RTCSRW_CNT_MASK << RTCSRW_WAIT_CNT_WR_SHIFT) 68 69 70 RTDECL(int) RTCritSectRwInit(PRTCRITSECTRW pThis) 71 { 72 return RTCritSectRwInitEx(pThis, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, "RTCritSectRw"); 73 } 74 RT_EXPORT_SYMBOL(RTCritSectRwInit); 75 76 77 RTDECL(int) RTCritSectRwInitEx(PRTCRITSECTRW pThis, uint32_t fFlags, 78 RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...) 79 { 80 int rc; 81 AssertReturn(!(fFlags & ~( RTCRITSECT_FLAGS_NO_NESTING | RTCRITSECT_FLAGS_NO_LOCK_VAL | RTCRITSECT_FLAGS_BOOTSTRAP_HACK 82 | RTCRITSECT_FLAGS_NOP )), 83 VERR_INVALID_PARAMETER); 84 85 /* 86 * Initialize the structure, allocate the lock validator stuff and sems. 87 */ 88 pThis->u32Magic = RTCRITSECTRW_MAGIC_DEAD; 89 pThis->fNeedReset = false; 90 pThis->u64State = 0; 91 pThis->hNativeWriter = NIL_RTNATIVETHREAD; 92 pThis->cWriterReads = 0; 93 pThis->cWriteRecursions = 0; 94 pThis->hEvtWrite = NIL_RTSEMEVENT; 95 pThis->hEvtRead = NIL_RTSEMEVENTMULTI; 96 pThis->pValidatorWrite = NULL; 97 pThis->pValidatorRead = NULL; 98 #if HC_ARCH_BITS == 32 99 pThis->HCPtrPadding = NIL_RTHCPTR; 100 #endif 101 102 #ifdef RTCRITSECTRW_STRICT 103 bool const fLVEnabled = !(fFlags & RTSEMRW_FLAGS_NO_LOCK_VAL); 104 if (!pszNameFmt) 105 { 106 static uint32_t volatile s_iAnon = 0; 107 uint32_t i = ASMAtomicIncU32(&s_iAnon) - 1; 108 rc = RTLockValidatorRecExclCreate(&pThis->pValidatorWrite, hClass, uSubClass, pThis, 109 fLVEnabled, "RTCritSectRw-%u", i); 110 if (RT_SUCCESS(rc)) 111 rc = RTLockValidatorRecSharedCreate(&pThis->pValidatorRead, hClass, uSubClass, pThis, 112 false /*fSignaller*/, fLVEnabled, "RTCritSectRw-%u", i); 113 } 114 else 115 { 116 va_list va; 117 va_start(va, pszNameFmt); 118 rc = RTLockValidatorRecExclCreateV(&pThis->pValidatorWrite, hClass, uSubClass, pThis, 119 fLVEnabled, pszNameFmt, va); 120 va_end(va); 121 if (RT_SUCCESS(rc)) 122 { 123 va_start(va, pszNameFmt); 124 RTLockValidatorRecSharedCreateV(&pThis->pValidatorRead, hClass, uSubClass, pThis, 125 false /*fSignaller*/, fLVEnabled, pszNameFmt, va); 126 va_end(va); 127 } 128 } 129 if (RT_SUCCESS(rc)) 130 rc = RTLockValidatorRecMakeSiblings(&pThis->pValidatorWrite->Core, &pThis->pValidatorRead->Core); 131 132 if (RT_SUCCESS(rc)) 133 #endif 134 { 135 rc = RTSemEventMultiCreate(&pThis->hEvtRead); 136 if (RT_SUCCESS(rc)) 137 { 138 rc = RTSemEventCreate(&pThis->hEvtWrite); 139 if (RT_SUCCESS(rc)) 140 { 141 pThis->u32Magic = RTCRITSECTRW_MAGIC; 142 return VINF_SUCCESS; 143 } 144 RTSemEventMultiDestroy(pThis->hEvtRead); 145 } 146 } 147 148 #ifdef RTCRITSECTRW_STRICT 149 RTLockValidatorRecSharedDestroy(&pThis->pValidatorRead); 150 RTLockValidatorRecExclDestroy(&pThis->pValidatorWrite); 151 #endif 152 return rc; 153 } 154 RT_EXPORT_SYMBOL(RTCritSectRwInitEx); 155 156 157 RTDECL(uint32_t) RTCritSectRwSetSubClass(PRTCRITSECTRW pThis, uint32_t uSubClass) 56 /** The number loops to spin for shared access in ring-3. */ 57 #define PDMCRITSECTRW_SHRD_SPIN_COUNT_R3 20 58 /** The number loops to spin for shared access in ring-0. */ 59 #define PDMCRITSECTRW_SHRD_SPIN_COUNT_R0 128 60 /** The number loops to spin for shared access in the raw-mode context. */ 61 #define PDMCRITSECTRW_SHRD_SPIN_COUNT_RC 128 62 63 /** The number loops to spin for exclusive access in ring-3. */ 64 #define PDMCRITSECTRW_EXCL_SPIN_COUNT_R3 20 65 /** The number loops to spin for exclusive access in ring-0. */ 66 #define PDMCRITSECTRW_EXCL_SPIN_COUNT_R0 256 67 /** The number loops to spin for exclusive access in the raw-mode context. */ 68 #define PDMCRITSECTRW_EXCL_SPIN_COUNT_RC 256 69 70 71 /* Undefine the automatic VBOX_STRICT API mappings. */ 72 #undef PDMCritSectRwEnterExcl 73 #undef PDMCritSectRwTryEnterExcl 74 #undef PDMCritSectRwEnterShared 75 #undef PDMCritSectRwTryEnterShared 76 77 78 /** 79 * Gets the ring-3 native thread handle of the calling thread. 80 * 81 * @returns native thread handle (ring-3). 82 * @param pThis The read/write critical section. This is only used in 83 * R0 and RC. 84 */ 85 DECL_FORCE_INLINE(RTNATIVETHREAD) pdmCritSectRwGetNativeSelf(PCPDMCRITSECTRW pThis) 86 { 87 #ifdef IN_RING3 88 NOREF(pThis); 89 RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf(); 90 #else 91 AssertMsgReturn(pThis->s.Core.u32Magic == RTCRITSECT_MAGIC, ("%RX32\n", pThis->s.Core.u32Magic), 92 NIL_RTNATIVETHREAD); 93 PVM pVM = pThis->s.CTX_SUFF(pVM); AssertPtr(pVM); 94 PVMCPU pVCpu = VMMGetCpu(pVM); AssertPtr(pVCpu); 95 RTNATIVETHREAD hNativeSelf = pVCpu->hNativeThread; Assert(hNativeSelf != NIL_RTNATIVETHREAD); 96 #endif 97 return hNativeSelf; 98 } 99 100 101 102 103 104 #ifdef IN_RING3 105 /** 106 * Changes the lock validator sub-class of the read/write critical section. 107 * 108 * It is recommended to try make sure that nobody is using this critical section 109 * while changing the value. 110 * 111 * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the 112 * lock validator isn't compiled in or either of the parameters are 113 * invalid. 114 * @param pThis Pointer to the read/write critical section. 115 * @param uSubClass The new sub-class value. 116 */ 117 VMMDECL(uint32_t) PDMR3CritSectRwSetSubClass(PPDMCRITSECTRW pThis, uint32_t uSubClass) 158 118 { 159 119 AssertPtrReturn(pThis, RTLOCKVAL_SUB_CLASS_INVALID); 160 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, RTLOCKVAL_SUB_CLASS_INVALID);161 # ifdef RTCRITSECTRW_STRICT162 AssertReturn(!(pThis-> fFlags & RTCRITSECT_FLAGS_NOP), RTLOCKVAL_SUB_CLASS_INVALID);163 164 RTLockValidatorRecSharedSetSubClass(pThis-> pValidatorRead, uSubClass);165 return RTLockValidatorRecExclSetSubClass(pThis-> pValidatorWrite, uSubClass);166 # else120 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, RTLOCKVAL_SUB_CLASS_INVALID); 121 # ifdef PDMCRITSECTRW_STRICT 122 AssertReturn(!(pThis->s.Core.fFlags & RTCRITSECT_FLAGS_NOP), RTLOCKVAL_SUB_CLASS_INVALID); 123 124 RTLockValidatorRecSharedSetSubClass(pThis->s.Core.pValidatorRead, uSubClass); 125 return RTLockValidatorRecExclSetSubClass(pThis->s.Core.pValidatorWrite, uSubClass); 126 # else 167 127 NOREF(uSubClass); 168 128 return RTLOCKVAL_SUB_CLASS_INVALID; 169 # endif170 } 171 RT_EXPORT_SYMBOL(RTCritSectRwSetSubClass); 172 173 174 static int rtCritSectRwEnterShared(PRTCRITSECTRW pThis, PCRTLOCKVALSRCPOS pSrcPos, bool fTryOnly)129 # endif 130 } 131 #endif /* IN_RING3 */ 132 133 134 static int pdmCritSectRwEnterShared(PPDMCRITSECTRW pThis, int rcBusy, PCRTLOCKVALSRCPOS pSrcPos, bool fTryOnly) 175 135 { 176 136 /* … … 178 138 */ 179 139 AssertPtr(pThis); 180 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED);181 182 #ifdef RTCRITSECTRW_STRICT140 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED); 141 142 #ifdef PDMCRITSECTRW_STRICT 183 143 RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt(); 184 144 if (!fTryOnly) … … 186 146 int rc9; 187 147 RTNATIVETHREAD hNativeWriter; 188 ASMAtomicUoReadHandle(&pThis-> hNativeWriter, &hNativeWriter);189 if (hNativeWriter != NIL_RTTHREAD && hNativeWriter == RTThreadNativeSelf())190 rc9 = RTLockValidatorRecExclCheckOrder(pThis-> pValidatorWrite, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT);148 ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter); 149 if (hNativeWriter != NIL_RTTHREAD && hNativeWriter == pdmCritSectRwGetNativeSelf(pThis)) 150 rc9 = RTLockValidatorRecExclCheckOrder(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT); 191 151 else 192 rc9 = RTLockValidatorRecSharedCheckOrder(pThis-> pValidatorRead, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT);152 rc9 = RTLockValidatorRecSharedCheckOrder(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT); 193 153 if (RT_FAILURE(rc9)) 194 154 return rc9; … … 199 159 * Get cracking... 200 160 */ 201 uint64_t u64State = ASMAtomicReadU64(&pThis-> u64State);161 uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 202 162 uint64_t u64OldState = u64State; 203 163 … … 212 172 u64State &= ~RTCSRW_CNT_RD_MASK; 213 173 u64State |= c << RTCSRW_CNT_RD_SHIFT; 214 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))215 { 216 #ifdef RTCRITSECTRW_STRICT217 RTLockValidatorRecSharedAddOwner(pThis-> pValidatorRead, hThreadSelf, pSrcPos);174 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 175 { 176 #ifdef PDMCRITSECTRW_STRICT 177 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 218 178 #endif 219 179 break; … … 225 185 u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK); 226 186 u64State |= (UINT64_C(1) << RTCSRW_CNT_RD_SHIFT) | (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT); 227 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))228 { 229 Assert(!pThis-> fNeedReset);230 #ifdef RTCRITSECTRW_STRICT231 RTLockValidatorRecSharedAddOwner(pThis-> pValidatorRead, hThreadSelf, pSrcPos);187 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 188 { 189 Assert(!pThis->s.Core.fNeedReset); 190 #ifdef PDMCRITSECTRW_STRICT 191 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 232 192 #endif 233 193 break; … … 237 197 { 238 198 /* Is the writer perhaps doing a read recursion? */ 239 RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();199 RTNATIVETHREAD hNativeSelf = pdmCritSectRwGetNativeSelf(pThis); 240 200 RTNATIVETHREAD hNativeWriter; 241 ASMAtomicUoReadHandle(&pThis-> hNativeWriter, &hNativeWriter);201 ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter); 242 202 if (hNativeSelf == hNativeWriter) 243 203 { 244 #ifdef RTCRITSECTRW_STRICT245 int rc9 = RTLockValidatorRecExclRecursionMixed(pThis-> pValidatorWrite, &pThis->pValidatorRead->Core, pSrcPos);204 #ifdef PDMCRITSECTRW_STRICT 205 int rc9 = RTLockValidatorRecExclRecursionMixed(pThis->s.Core.pValidatorWrite, &pThis->s.Core.pValidatorRead->Core, pSrcPos); 246 206 if (RT_FAILURE(rc9)) 247 207 return rc9; 248 208 #endif 249 Assert(pThis-> cWriterReads < UINT32_MAX / 2);250 ASMAtomicIncU32(&pThis-> cWriterReads);209 Assert(pThis->s.Core.cWriterReads < UINT32_MAX / 2); 210 ASMAtomicIncU32(&pThis->s.Core.cWriterReads); 251 211 return VINF_SUCCESS; /* don't break! */ 252 212 } … … 269 229 u64State |= (c << RTCSRW_CNT_RD_SHIFT) | (cWait << RTCSRW_WAIT_CNT_RD_SHIFT); 270 230 271 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))231 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 272 232 { 273 233 for (uint32_t iLoop = 0; ; iLoop++) 274 234 { 275 235 int rc; 276 #ifdef RTCRITSECTRW_STRICT277 rc = RTLockValidatorRecSharedCheckBlocking(pThis-> pValidatorRead, hThreadSelf, pSrcPos, true,236 #ifdef PDMCRITSECTRW_STRICT 237 rc = RTLockValidatorRecSharedCheckBlocking(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos, true, 278 238 RT_INDEFINITE_WAIT, RTTHREADSTATE_RW_READ, false); 279 239 if (RT_SUCCESS(rc)) … … 283 243 #endif 284 244 { 285 rc = RTSemEventMultiWait(pThis->hEvtRead, RT_INDEFINITE_WAIT); 245 do 246 rc = SUPSemEventMultiWaitNoResume(pThis->s.CTX_SUFF(pVM)->pSession, 247 (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead, 248 RT_INDEFINITE_WAIT); 249 while (rc == VERR_INTERRUPTED && pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC); 286 250 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_READ); 287 if (pThis-> u32Magic != RTCRITSECTRW_MAGIC)251 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 288 252 return VERR_SEM_DESTROYED; 289 253 } … … 293 257 for (;;) 294 258 { 295 u64OldState = u64State = ASMAtomicReadU64(&pThis-> u64State);259 u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 296 260 c = (u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT; Assert(c > 0); 297 261 c--; … … 300 264 u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_WAIT_CNT_RD_MASK); 301 265 u64State |= (c << RTCSRW_CNT_RD_SHIFT) | (cWait << RTCSRW_WAIT_CNT_RD_SHIFT); 302 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))266 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 303 267 break; 304 268 } … … 306 270 } 307 271 308 Assert(pThis-> fNeedReset);309 u64State = ASMAtomicReadU64(&pThis-> u64State);272 Assert(pThis->s.Core.fNeedReset); 273 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 310 274 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT)) 311 275 break; … … 324 288 u64State |= cWait << RTCSRW_WAIT_CNT_RD_SHIFT; 325 289 326 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))290 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 327 291 { 328 292 if (cWait == 0) 329 293 { 330 if (ASMAtomicXchgBool(&pThis-> fNeedReset, false))294 if (ASMAtomicXchgBool(&pThis->s.Core.fNeedReset, false)) 331 295 { 332 int rc = RTSemEventMultiReset(pThis->hEvtRead); 296 int rc = SUPSemEventMultiReset(pThis->s.CTX_SUFF(pVM)->pSession, 297 (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead); 333 298 AssertRCReturn(rc, rc); 334 299 } … … 336 301 break; 337 302 } 338 u64State = ASMAtomicReadU64(&pThis-> u64State);303 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 339 304 } 340 305 341 #ifdef RTCRITSECTRW_STRICT342 RTLockValidatorRecSharedAddOwner(pThis-> pValidatorRead, hThreadSelf, pSrcPos);306 #ifdef PDMCRITSECTRW_STRICT 307 RTLockValidatorRecSharedAddOwner(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos); 343 308 #endif 344 309 break; … … 346 311 } 347 312 348 if (pThis-> u32Magic != RTCRITSECTRW_MAGIC)313 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 349 314 return VERR_SEM_DESTROYED; 350 315 351 316 ASMNopPause(); 352 u64State = ASMAtomicReadU64(&pThis-> u64State);317 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 353 318 u64OldState = u64State; 354 319 } 355 320 356 321 /* got it! */ 357 Assert((ASMAtomicReadU64(&pThis-> u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT));322 Assert((ASMAtomicReadU64(&pThis->s.Core.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT)); 358 323 return VINF_SUCCESS; 359 324 … … 361 326 362 327 363 RTDECL(int) RTCritSectRwEnterShared(PRTCRITSECTRW pThis) 364 { 365 #ifndef RTCRITSECTRW_STRICT 366 return rtCritSectRwEnterShared(pThis, NULL, false /*fTryOnly*/); 328 /** 329 * Enter a critical section with shared (read) access. 330 * 331 * @returns VBox status code. 332 * @retval VINF_SUCCESS on success. 333 * @retval @a rcBusy if in ring-0 or raw-mode context and it is busy. 334 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 335 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 336 * during the operation. 337 * 338 * @param pThis Pointer to the read/write critical section. 339 * @param rcBusy The status code to return when we're in RC or R0 and the 340 * section is busy. Pass VINF_SUCCESS to acquired the 341 * critical section thru a ring-3 call if necessary. 342 * @param uId Where we're entering the section. 343 * @param pszFile The source position - file. 344 * @param iLine The source position - line. 345 * @param pszFunction The source position - function. 346 * @sa PDMCritSectRwEnterSharedDebug, PDMCritSectRwTryEnterShared, 347 * PDMCritSectRwTryEnterSharedDebug, PDMCritSectRwLeaveShared, 348 * RTCritSectRwEnterShared. 349 */ 350 VMMDECL(int) PDMCritSectRwEnterShared(PPDMCRITSECTRW pThis, int rcBusy) 351 { 352 #ifndef PDMCRITSECTRW_STRICT 353 return pdmCritSectRwEnterShared(pThis, rcBusy, NULL, false /*fTryOnly*/); 367 354 #else 368 355 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 369 return rtCritSectRwEnterShared(pThis, &SrcPos, false /*fTryOnly*/); 370 #endif 371 } 372 RT_EXPORT_SYMBOL(RTCritSectRwEnterShared); 373 374 375 RTDECL(int) RTCritSectRwEnterSharedDebug(PRTCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL) 356 return pdmCritSectRwEnterShared(pThis, rcBusy, &SrcPos, false /*fTryOnly*/); 357 #endif 358 } 359 360 361 /** 362 * Enter a critical section with shared (read) access. 363 * 364 * @returns VBox status code. 365 * @retval VINF_SUCCESS on success. 366 * @retval @a rcBusy if in ring-0 or raw-mode context and it is busy. 367 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 368 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 369 * during the operation. 370 * 371 * @param pThis Pointer to the read/write critical section. 372 * @param rcBusy The status code to return when we're in RC or R0 and the 373 * section is busy. Pass VINF_SUCCESS to acquired the 374 * critical section thru a ring-3 call if necessary. 375 * @param uId Where we're entering the section. 376 * @param pszFile The source position - file. 377 * @param iLine The source position - line. 378 * @param pszFunction The source position - function. 379 * @sa PDMCritSectRwEnterShared, PDMCritSectRwTryEnterShared, 380 * PDMCritSectRwTryEnterSharedDebug, PDMCritSectRwLeaveShared, 381 * RTCritSectRwEnterSharedDebug. 382 */ 383 VMMDECL(int) PDMCritSectRwEnterSharedDebug(PPDMCRITSECTRW pThis, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL) 376 384 { 377 385 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 378 return rtCritSectRwEnterShared(pThis, &SrcPos, false /*fTryOnly*/); 379 } 380 RT_EXPORT_SYMBOL(RTCritSectRwEnterSharedDebug); 381 382 383 RTDECL(int) RTCritSectRwTryEnterShared(PRTCRITSECTRW pThis) 384 { 385 #ifndef RTCRITSECTRW_STRICT 386 return rtCritSectRwEnterShared(pThis, NULL, true /*fTryOnly*/); 386 return pdmCritSectRwEnterShared(pThis, rcBusy, &SrcPos, false /*fTryOnly*/); 387 } 388 389 390 /** 391 * Try enter a critical section with shared (read) access. 392 * 393 * @returns VBox status code. 394 * @retval VINF_SUCCESS on success. 395 * @retval VERR_SEM_BUSY if the critsect was owned. 396 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 397 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 398 * during the operation. 399 * 400 * @param pThis Pointer to the read/write critical section. 401 * @param uId Where we're entering the section. 402 * @param pszFile The source position - file. 403 * @param iLine The source position - line. 404 * @param pszFunction The source position - function. 405 * @sa PDMCritSectRwTryEnterSharedDebug, PDMCritSectRwEnterShared, 406 * PDMCritSectRwEnterSharedDebug, PDMCritSectRwLeaveShared, 407 * RTCritSectRwTryEnterShared. 408 */ 409 VMMDECL(int) PDMCritSectRwTryEnterShared(PPDMCRITSECTRW pThis) 410 { 411 #ifndef PDMCRITSECTRW_STRICT 412 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, NULL, true /*fTryOnly*/); 387 413 #else 388 414 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 389 return rtCritSectRwEnterShared(pThis, &SrcPos, true /*fTryOnly*/); 390 #endif 391 } 392 RT_EXPORT_SYMBOL(RTCritSectRwEnterShared); 393 394 395 RTDECL(int) RTCritSectRwTryEnterSharedDebug(PRTCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL) 415 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryOnly*/); 416 #endif 417 } 418 419 420 /** 421 * Try enter a critical section with shared (read) access. 422 * 423 * @returns VBox status code. 424 * @retval VINF_SUCCESS on success. 425 * @retval VERR_SEM_BUSY if the critsect was owned. 426 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 427 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 428 * during the operation. 429 * 430 * @param pThis Pointer to the read/write critical section. 431 * @param uId Where we're entering the section. 432 * @param pszFile The source position - file. 433 * @param iLine The source position - line. 434 * @param pszFunction The source position - function. 435 * @sa PDMCritSectRwTryEnterShared, PDMCritSectRwEnterShared, 436 * PDMCritSectRwEnterSharedDebug, PDMCritSectRwLeaveShared, 437 * RTCritSectRwTryEnterSharedDebug. 438 */ 439 VMMDECL(int) PDMCritSectRwTryEnterSharedDebug(PPDMCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL) 396 440 { 397 441 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 398 return rtCritSectRwEnterShared(pThis, &SrcPos, true /*fTryOnly*/); 399 } 400 RT_EXPORT_SYMBOL(RTCritSectRwEnterSharedDebug); 401 402 403 404 RTDECL(int) RTCritSectRwLeaveShared(PRTCRITSECTRW pThis) 442 return pdmCritSectRwEnterShared(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryOnly*/); 443 } 444 445 446 /** 447 * Leave a critical section held with shared access. 448 * 449 * @returns VBox status code. 450 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 451 * during the operation. 452 * @param pThis Pointer to the read/write critical section. 453 * @sa PDMCritSectRwEnterShared, PDMCritSectRwTryEnterShared, 454 * PDMCritSectRwEnterSharedDebug, PDMCritSectRwTryEnterSharedDebug, 455 * PDMCritSectRwLeaveExcl, RTCritSectRwLeaveShared. 456 */ 457 VMMDECL(int) PDMCritSectRwLeaveShared(PPDMCRITSECTRW pThis) 405 458 { 406 459 /* … … 408 461 */ 409 462 AssertPtr(pThis); 410 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED);463 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED); 411 464 412 465 /* 413 466 * Check the direction and take action accordingly. 414 467 */ 415 uint64_t u64State = ASMAtomicReadU64(&pThis-> u64State);468 uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 416 469 uint64_t u64OldState = u64State; 417 470 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT)) 418 471 { 419 #ifdef RTCRITSECTRW_STRICT420 int rc9 = RTLockValidatorRecSharedCheckAndRelease(pThis-> pValidatorRead, NIL_RTTHREAD);472 #ifdef PDMCRITSECTRW_STRICT 473 int rc9 = RTLockValidatorRecSharedCheckAndRelease(pThis->s.Core.pValidatorRead, NIL_RTTHREAD); 421 474 if (RT_FAILURE(rc9)) 422 475 return rc9; … … 434 487 u64State &= ~RTCSRW_CNT_RD_MASK; 435 488 u64State |= c << RTCSRW_CNT_RD_SHIFT; 436 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))489 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 437 490 break; 438 491 } … … 442 495 u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_DIR_MASK); 443 496 u64State |= RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT; 444 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))497 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 445 498 { 446 int rc = RTSemEventSignal(pThis->hEvtWrite);499 int rc = SUPSemEventSignal(pThis->s.CTX_SUFF(pVM)->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite); 447 500 AssertRC(rc); 448 501 break; … … 451 504 452 505 ASMNopPause(); 453 u64State = ASMAtomicReadU64(&pThis-> u64State);506 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 454 507 u64OldState = u64State; 455 508 } … … 457 510 else 458 511 { 459 RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();512 RTNATIVETHREAD hNativeSelf = pdmCritSectRwGetNativeSelf(pThis); 460 513 RTNATIVETHREAD hNativeWriter; 461 ASMAtomicUoReadHandle(&pThis-> hNativeWriter, &hNativeWriter);514 ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter); 462 515 AssertReturn(hNativeSelf == hNativeWriter, VERR_NOT_OWNER); 463 AssertReturn(pThis-> cWriterReads > 0, VERR_NOT_OWNER);464 #ifdef RTCRITSECTRW_STRICT465 int rc = RTLockValidatorRecExclUnwindMixed(pThis-> pValidatorWrite, &pThis->pValidatorRead->Core);516 AssertReturn(pThis->s.Core.cWriterReads > 0, VERR_NOT_OWNER); 517 #ifdef PDMCRITSECTRW_STRICT 518 int rc = RTLockValidatorRecExclUnwindMixed(pThis->s.Core.pValidatorWrite, &pThis->s.Core.pValidatorRead->Core); 466 519 if (RT_FAILURE(rc)) 467 520 return rc; 468 521 #endif 469 ASMAtomicDecU32(&pThis-> cWriterReads);522 ASMAtomicDecU32(&pThis->s.Core.cWriterReads); 470 523 } 471 524 472 525 return VINF_SUCCESS; 473 526 } 474 RT_EXPORT_SYMBOL(RTCritSectRwLeaveShared); 475 476 477 static int rtCritSectRwEnterExcl(PRTCRITSECTRW pThis, PCRTLOCKVALSRCPOS pSrcPos, bool fTryOnly) 527 528 529 static int pdmCritSectRwEnterExcl(PPDMCRITSECTRW pThis, int rcBusy, PCRTLOCKVALSRCPOS pSrcPos, bool fTryOnly) 478 530 { 479 531 /* … … 481 533 */ 482 534 AssertPtr(pThis); 483 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED);484 485 #ifdef RTCRITSECTRW_STRICT535 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED); 536 537 #ifdef PDMCRITSECTRW_STRICT 486 538 RTTHREAD hThreadSelf = NIL_RTTHREAD; 487 539 if (!fTryOnly) 488 540 { 489 541 hThreadSelf = RTThreadSelfAutoAdopt(); 490 int rc9 = RTLockValidatorRecExclCheckOrder(pThis-> pValidatorWrite, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT);542 int rc9 = RTLockValidatorRecExclCheckOrder(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, RT_INDEFINITE_WAIT); 491 543 if (RT_FAILURE(rc9)) 492 544 return rc9; … … 497 549 * Check if we're already the owner and just recursing. 498 550 */ 499 RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();551 RTNATIVETHREAD hNativeSelf = pdmCritSectRwGetNativeSelf(pThis); 500 552 RTNATIVETHREAD hNativeWriter; 501 ASMAtomicUoReadHandle(&pThis-> hNativeWriter, &hNativeWriter);553 ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter); 502 554 if (hNativeSelf == hNativeWriter) 503 555 { 504 Assert((ASMAtomicReadU64(&pThis-> u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));505 #ifdef RTCRITSECTRW_STRICT506 int rc9 = RTLockValidatorRecExclRecursion(pThis-> pValidatorWrite, pSrcPos);556 Assert((ASMAtomicReadU64(&pThis->s.Core.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)); 557 #ifdef PDMCRITSECTRW_STRICT 558 int rc9 = RTLockValidatorRecExclRecursion(pThis->s.Core.pValidatorWrite, pSrcPos); 507 559 if (RT_FAILURE(rc9)) 508 560 return rc9; 509 561 #endif 510 Assert(pThis-> cWriteRecursions < UINT32_MAX / 2);511 ASMAtomicIncU32(&pThis-> cWriteRecursions);562 Assert(pThis->s.Core.cWriteRecursions < UINT32_MAX / 2); 563 ASMAtomicIncU32(&pThis->s.Core.cWriteRecursions); 512 564 return VINF_SUCCESS; 513 565 } … … 516 568 * Get cracking. 517 569 */ 518 uint64_t u64State = ASMAtomicReadU64(&pThis-> u64State);570 uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 519 571 uint64_t u64OldState = u64State; 520 572 … … 530 582 u64State &= ~RTCSRW_CNT_WR_MASK; 531 583 u64State |= c << RTCSRW_CNT_WR_SHIFT; 532 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))584 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 533 585 break; 534 586 } … … 538 590 u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK); 539 591 u64State |= (UINT64_C(1) << RTCSRW_CNT_WR_SHIFT) | (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT); 540 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))592 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 541 593 break; 542 594 } … … 552 604 u64State &= ~RTCSRW_CNT_WR_MASK; 553 605 u64State |= c << RTCSRW_CNT_WR_SHIFT; 554 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))606 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 555 607 break; 556 608 } 557 609 558 if (pThis-> u32Magic != RTCRITSECTRW_MAGIC)610 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 559 611 return VERR_SEM_DESTROYED; 560 612 561 613 ASMNopPause(); 562 u64State = ASMAtomicReadU64(&pThis-> u64State);614 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 563 615 u64OldState = u64State; 564 616 } … … 572 624 || fTryOnly); 573 625 if (fDone) 574 ASMAtomicCmpXchgHandle(&pThis-> hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);626 ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone); 575 627 if (!fDone) 576 628 { … … 581 633 { 582 634 int rc; 583 #ifdef RTCRITSECTRW_STRICT635 #ifdef PDMCRITSECTRW_STRICT 584 636 if (!fTryOnly) 585 637 { 586 638 if (hThreadSelf == NIL_RTTHREAD) 587 639 hThreadSelf = RTThreadSelfAutoAdopt(); 588 rc = RTLockValidatorRecExclCheckBlocking(pThis-> pValidatorWrite, hThreadSelf, pSrcPos, true,640 rc = RTLockValidatorRecExclCheckBlocking(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, true, 589 641 RT_INDEFINITE_WAIT, RTTHREADSTATE_RW_WRITE, false); 590 642 } … … 597 649 #endif 598 650 { 599 rc = RTSemEventWait(pThis->hEvtWrite, RT_INDEFINITE_WAIT); 651 do 652 rc = SUPSemEventWaitNoResume(pThis->s.CTX_SUFF(pVM)->pSession, 653 (SUPSEMEVENT)pThis->s.Core.hEvtWrite, 654 RT_INDEFINITE_WAIT); 655 while (rc == VERR_INTERRUPTED && pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC); 600 656 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_WRITE); 601 if (pThis-> u32Magic != RTCRITSECTRW_MAGIC)657 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 602 658 return VERR_SEM_DESTROYED; 603 659 } … … 607 663 for (;;) 608 664 { 609 u64OldState = u64State = ASMAtomicReadU64(&pThis-> u64State);665 u64OldState = u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 610 666 uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT; Assert(c > 0); 611 667 c--; 612 668 u64State &= ~RTCSRW_CNT_WR_MASK; 613 669 u64State |= c << RTCSRW_CNT_WR_SHIFT; 614 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))670 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 615 671 break; 616 672 } … … 618 674 } 619 675 620 u64State = ASMAtomicReadU64(&pThis-> u64State);676 u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 621 677 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)) 622 678 { 623 ASMAtomicCmpXchgHandle(&pThis-> hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone);679 ASMAtomicCmpXchgHandle(&pThis->s.Core.hNativeWriter, hNativeSelf, NIL_RTNATIVETHREAD, fDone); 624 680 if (fDone) 625 681 break; … … 632 688 * Got it! 633 689 */ 634 Assert((ASMAtomicReadU64(&pThis-> u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT));635 ASMAtomicWriteU32(&pThis-> cWriteRecursions, 1);636 Assert(pThis-> cWriterReads == 0);637 #ifdef RTCRITSECTRW_STRICT638 RTLockValidatorRecExclSetOwner(pThis-> pValidatorWrite, hThreadSelf, pSrcPos, true);690 Assert((ASMAtomicReadU64(&pThis->s.Core.u64State) & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)); 691 ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 1); 692 Assert(pThis->s.Core.cWriterReads == 0); 693 #ifdef PDMCRITSECTRW_STRICT 694 RTLockValidatorRecExclSetOwner(pThis->s.Core.pValidatorWrite, hThreadSelf, pSrcPos, true); 639 695 #endif 640 696 … … 643 699 644 700 645 RTDECL(int) RTCritSectRwEnterExcl(PRTCRITSECTRW pThis) 646 { 647 #ifndef RTCRITSECTRW_STRICT 648 return rtCritSectRwEnterExcl(pThis, NULL, false /*fTryAgain*/); 701 /** 702 * Try enter a critical section with exclusive (write) access. 703 * 704 * @returns VBox status code. 705 * @retval VINF_SUCCESS on success. 706 * @retval @a rcBusy if in ring-0 or raw-mode context and it is busy. 707 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 708 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 709 * during the operation. 710 * 711 * @param pThis Pointer to the read/write critical section. 712 * @param rcBusy The status code to return when we're in RC or R0 and the 713 * section is busy. Pass VINF_SUCCESS to acquired the 714 * critical section thru a ring-3 call if necessary. 715 * @sa PDMCritSectRwEnterExclDebug, PDMCritSectRwTryEnterExcl, 716 * PDMCritSectRwTryEnterExclDebug, 717 * PDMCritSectEnterDebug, PDMCritSectEnter, 718 * RTCritSectRwEnterExcl. 719 */ 720 VMMDECL(int) PDMCritSectRwEnterExcl(PPDMCRITSECTRW pThis, int rcBusy) 721 { 722 #ifndef PDMCRITSECTRW_STRICT 723 return pdmCritSectRwEnterExcl(pThis, rcBusy, NULL, false /*fTryAgain*/); 649 724 #else 650 725 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 651 return rtCritSectRwEnterExcl(pThis, &SrcPos, false /*fTryAgain*/); 652 #endif 653 } 654 RT_EXPORT_SYMBOL(RTCritSectRwEnterExcl); 655 656 657 RTDECL(int) RTCritSectRwEnterExclDebug(PRTCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL) 726 return pdmCritSectRwEnterExcl(pThis, rcBusy, &SrcPos, false /*fTryAgain*/); 727 #endif 728 } 729 730 731 /** 732 * Try enter a critical section with exclusive (write) access. 733 * 734 * @returns VBox status code. 735 * @retval VINF_SUCCESS on success. 736 * @retval @a rcBusy if in ring-0 or raw-mode context and it is busy. 737 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 738 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 739 * during the operation. 740 * 741 * @param pThis Pointer to the read/write critical section. 742 * @param rcBusy The status code to return when we're in RC or R0 and the 743 * section is busy. Pass VINF_SUCCESS to acquired the 744 * critical section thru a ring-3 call if necessary. 745 * @param uId Where we're entering the section. 746 * @param pszFile The source position - file. 747 * @param iLine The source position - line. 748 * @param pszFunction The source position - function. 749 * @sa PDMCritSectRwEnterExcl, PDMCritSectRwTryEnterExcl, 750 * PDMCritSectRwTryEnterExclDebug, 751 * PDMCritSectEnterDebug, PDMCritSectEnter, 752 * RTCritSectRwEnterExclDebug. 753 */ 754 VMMDECL(int) PDMCritSectRwEnterExclDebug(PPDMCRITSECTRW pThis, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL) 658 755 { 659 756 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 660 return rtCritSectRwEnterExcl(pThis, &SrcPos, false /*fTryAgain*/); 661 } 662 RT_EXPORT_SYMBOL(RTCritSectRwEnterExclDebug); 663 664 665 RTDECL(int) RTCritSectRwTryEnterExcl(PRTCRITSECTRW pThis) 666 { 667 #ifndef RTCRITSECTRW_STRICT 668 return rtCritSectRwEnterExcl(pThis, NULL, true /*fTryAgain*/); 757 return pdmCritSectRwEnterExcl(pThis, rcBusy, &SrcPos, false /*fTryAgain*/); 758 } 759 760 761 /** 762 * Try enter a critical section with exclusive (write) access. 763 * 764 * @retval VINF_SUCCESS on success. 765 * @retval VERR_SEM_BUSY if the critsect was owned. 766 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 767 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 768 * during the operation. 769 * 770 * @param pThis Pointer to the read/write critical section. 771 * @sa PDMCritSectRwEnterExcl, PDMCritSectRwTryEnterExclDebug, 772 * PDMCritSectRwEnterExclDebug, 773 * PDMCritSectTryEnter, PDMCritSectTryEnterDebug, 774 * RTCritSectRwTryEnterExcl. 775 */ 776 VMMDECL(int) PDMCritSectRwTryEnterExcl(PPDMCRITSECTRW pThis) 777 { 778 #ifndef PDMCRITSECTRW_STRICT 779 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, NULL, true /*fTryAgain*/); 669 780 #else 670 781 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API(); 671 return rtCritSectRwEnterExcl(pThis, &SrcPos, true /*fTryAgain*/); 672 #endif 673 } 674 RT_EXPORT_SYMBOL(RTCritSectRwTryEnterExcl); 675 676 677 RTDECL(int) RTCritSectRwTryEnterExclDebug(PRTCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL) 782 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryAgain*/); 783 #endif 784 } 785 786 787 /** 788 * Try enter a critical section with exclusive (write) access. 789 * 790 * @retval VINF_SUCCESS on success. 791 * @retval VERR_SEM_BUSY if the critsect was owned. 792 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.) 793 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 794 * during the operation. 795 * 796 * @param pThis Pointer to the read/write critical section. 797 * @param uId Where we're entering the section. 798 * @param pszFile The source position - file. 799 * @param iLine The source position - line. 800 * @param pszFunction The source position - function. 801 * @sa PDMCritSectRwTryEnterExcl, PDMCritSectRwEnterExcl, 802 * PDMCritSectRwEnterExclDebug, 803 * PDMCritSectTryEnterDebug, PDMCritSectTryEnter, 804 * RTCritSectRwTryEnterExclDebug. 805 */ 806 VMMDECL(int) PDMCritSectRwTryEnterExclDebug(PPDMCRITSECTRW pThis, RTHCUINTPTR uId, RT_SRC_POS_DECL) 678 807 { 679 808 RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API(); 680 return rtCritSectRwEnterExcl(pThis, &SrcPos, true /*fTryAgain*/); 681 } 682 RT_EXPORT_SYMBOL(RTCritSectRwTryEnterExclDebug); 683 684 685 RTDECL(int) RTCritSectRwLeaveExcl(PRTCRITSECTRW pThis) 809 return pdmCritSectRwEnterExcl(pThis, VERR_SEM_BUSY, &SrcPos, true /*fTryAgain*/); 810 } 811 812 813 /** 814 * Leave a critical section held exclusively. 815 * 816 * @returns VBox status code. 817 * @retval VERR_SEM_DESTROYED if the critical section is delete before or 818 * during the operation. 819 * @param pThis Pointer to the read/write critical section. 820 * @sa PDMCritSectRwLeaveShared, RTCritSectRwLeaveExcl. 821 */ 822 VMMDECL(int) PDMCritSectRwLeaveExcl(PPDMCRITSECTRW pThis) 686 823 { 687 824 /* … … 689 826 */ 690 827 AssertPtr(pThis); 691 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED);692 693 RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();828 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED); 829 830 RTNATIVETHREAD hNativeSelf = pdmCritSectRwGetNativeSelf(pThis); 694 831 RTNATIVETHREAD hNativeWriter; 695 ASMAtomicUoReadHandle(&pThis-> hNativeWriter, &hNativeWriter);832 ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter); 696 833 AssertReturn(hNativeSelf == hNativeWriter, VERR_NOT_OWNER); 697 834 … … 699 836 * Unwind a recursion. 700 837 */ 701 if (pThis-> cWriteRecursions == 1)838 if (pThis->s.Core.cWriteRecursions == 1) 702 839 { 703 AssertReturn(pThis-> cWriterReads == 0, VERR_WRONG_ORDER); /* (must release all read recursions before the final write.) */704 #ifdef RTCRITSECTRW_STRICT705 int rc9 = RTLockValidatorRecExclReleaseOwner(pThis-> pValidatorWrite, true);840 AssertReturn(pThis->s.Core.cWriterReads == 0, VERR_WRONG_ORDER); /* (must release all read recursions before the final write.) */ 841 #ifdef PDMCRITSECTRW_STRICT 842 int rc9 = RTLockValidatorRecExclReleaseOwner(pThis->s.Core.pValidatorWrite, true); 706 843 if (RT_FAILURE(rc9)) 707 844 return rc9; … … 710 847 * Update the state. 711 848 */ 712 ASMAtomicWriteU32(&pThis-> cWriteRecursions, 0);713 ASMAtomicWriteHandle(&pThis-> hNativeWriter, NIL_RTNATIVETHREAD);849 ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 0); 850 ASMAtomicWriteHandle(&pThis->s.Core.hNativeWriter, NIL_RTNATIVETHREAD); 714 851 715 852 for (;;) 716 853 { 717 uint64_t u64State = ASMAtomicReadU64(&pThis-> u64State);854 uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 718 855 uint64_t u64OldState = u64State; 719 856 … … 728 865 u64State &= ~RTCSRW_CNT_WR_MASK; 729 866 u64State |= c << RTCSRW_CNT_WR_SHIFT; 730 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))867 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 731 868 { 732 869 if (c > 0) 733 870 { 734 int rc = RTSemEventSignal(pThis->hEvtWrite);871 int rc = SUPSemEventSignal(pThis->s.CTX_SUFF(pVM)->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite); 735 872 AssertRC(rc); 736 873 } … … 743 880 u64State &= ~(RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK); 744 881 u64State |= RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT; 745 if (ASMAtomicCmpXchgU64(&pThis-> u64State, u64State, u64OldState))882 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u64State, u64State, u64OldState)) 746 883 { 747 Assert(!pThis-> fNeedReset);748 ASMAtomicWriteBool(&pThis-> fNeedReset, true);749 int rc = RTSemEventMultiSignal(pThis->hEvtRead);884 Assert(!pThis->s.Core.fNeedReset); 885 ASMAtomicWriteBool(&pThis->s.Core.fNeedReset, true); 886 int rc = SUPSemEventMultiSignal(pThis->s.CTX_SUFF(pVM)->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead); 750 887 AssertRC(rc); 751 888 break; … … 754 891 755 892 ASMNopPause(); 756 if (pThis-> u32Magic != RTCRITSECTRW_MAGIC)893 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 757 894 return VERR_SEM_DESTROYED; 758 895 } … … 760 897 else 761 898 { 762 Assert(pThis-> cWriteRecursions != 0);763 #ifdef RTCRITSECTRW_STRICT764 int rc9 = RTLockValidatorRecExclUnwind(pThis-> pValidatorWrite);899 Assert(pThis->s.Core.cWriteRecursions != 0); 900 #ifdef PDMCRITSECTRW_STRICT 901 int rc9 = RTLockValidatorRecExclUnwind(pThis->s.Core.pValidatorWrite); 765 902 if (RT_FAILURE(rc9)) 766 903 return rc9; 767 904 #endif 768 ASMAtomicDecU32(&pThis-> cWriteRecursions);905 ASMAtomicDecU32(&pThis->s.Core.cWriteRecursions); 769 906 } 770 907 771 908 return VINF_SUCCESS; 772 909 } 773 RT_EXPORT_SYMBOL(RTSemRWReleaseWrite); 774 775 776 RTDECL(bool) RTCritSectRwIsWriteOwner(PRTCRITSECTRW pThis) 910 911 912 /** 913 * Checks the caller is the exclusive (write) owner of the critical section. 914 * 915 * @retval @c true if owner. 916 * @retval @c false if not owner. 917 * @param pThis Pointer to the read/write critical section. 918 * @sa PDMCritSectRwIsReadOwner, PDMCritSectIsOwner, 919 * RTCritSectRwIsWriteOwner. 920 */ 921 VMMDECL(bool) PDMCritSectRwIsWriteOwner(PPDMCRITSECTRW pThis) 777 922 { 778 923 /* … … 780 925 */ 781 926 AssertPtr(pThis); 782 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, false);927 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, false); 783 928 784 929 /* 785 930 * Check ownership. 786 931 */ 787 RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();788 932 RTNATIVETHREAD hNativeWriter; 789 ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hNativeWriter); 790 return hNativeWriter == hNativeSelf; 791 } 792 RT_EXPORT_SYMBOL(RTCritSectRwIsWriteOwner); 793 794 795 RTDECL(bool) RTCritSectRwIsReadOwner(PRTCRITSECTRW pThis, bool fWannaHear) 933 ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hNativeWriter); 934 if (hNativeWriter == NIL_RTNATIVETHREAD) 935 return false; 936 return hNativeWriter == pdmCritSectRwGetNativeSelf(pThis); 937 } 938 939 940 /** 941 * Checks if the caller is one of the read owners of the critical section. 942 * 943 * @note !CAUTION! This API doesn't work reliably if lock validation isn't 944 * enabled. Meaning, the answer is not trustworhty unless 945 * RT_LOCK_STRICT or PDMCRITSECTRW_STRICT was defined at build time. 946 * Also, make sure you do not use RTCRITSECTRW_FLAGS_NO_LOCK_VAL when 947 * creating the semaphore. And finally, if you used a locking class, 948 * don't disable deadlock detection by setting cMsMinDeadlock to 949 * RT_INDEFINITE_WAIT. 950 * 951 * In short, only use this for assertions. 952 * 953 * @returns @c true if reader, @c false if not. 954 * @param pThis Pointer to the read/write critical section. 955 * @param fWannaHear What you'd like to hear when lock validation is not 956 * available. (For avoiding asserting all over the place.) 957 * @sa PDMCritSectRwIsWriteOwner, RTCritSectRwIsReadOwner. 958 */ 959 VMMDECL(bool) PDMCritSectRwIsReadOwner(PPDMCRITSECTRW pThis, bool fWannaHear) 796 960 { 797 961 /* … … 799 963 */ 800 964 AssertPtr(pThis); 801 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, false);965 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, false); 802 966 803 967 /* 804 968 * Inspect the state. 805 969 */ 806 uint64_t u64State = ASMAtomicReadU64(&pThis-> u64State);970 uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 807 971 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_WRITE << RTCSRW_DIR_SHIFT)) 808 972 { … … 811 975 * current writer. 812 976 */ 813 RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();814 977 RTNATIVETHREAD hWriter; 815 ASMAtomicUoReadHandle(&pThis->hNativeWriter, &hWriter); 816 return hWriter == hNativeSelf; 978 ASMAtomicUoReadHandle(&pThis->s.Core.hNativeWriter, &hWriter); 979 if (hWriter == NIL_RTNATIVETHREAD) 980 return false; 981 return hWriter == pdmCritSectRwGetNativeSelf(pThis); 817 982 } 818 983 … … 823 988 return false; 824 989 825 #if def RTCRITSECTRW_STRICT990 #if defined(PDMCRITSECTRW_STRICT) && defined(IN_RING3) 826 991 /* 827 992 * Ask the lock validator. 828 */ 829 return RTLockValidatorRecSharedIsOwner(pThis->pValidatorRead, NIL_RTTHREAD); 993 * Note! It doesn't know everything, let's deal with that if it becomes an issue... 994 */ 995 return RTLockValidatorRecSharedIsOwner(pThis->s.Core.pValidatorRead, NIL_RTTHREAD); 830 996 #else 831 997 /* … … 835 1001 #endif 836 1002 } 837 RT_EXPORT_SYMBOL(RTCritSectRwIsReadOwner); 838 839 840 RTDECL(uint32_t) RTCritSectRwGetWriteRecursion(PRTCRITSECTRW pThis) 1003 1004 1005 /** 1006 * Gets the write recursion count. 1007 * 1008 * @returns The write recursion count (0 if bad critsect). 1009 * @param pThis Pointer to the read/write critical section. 1010 * @sa PDMCritSectRwGetWriterReadRecursion, PDMCritSectRwGetReadCount, 1011 * RTCritSectRwGetWriteRecursion. 1012 */ 1013 VMMDECL(uint32_t) PDMCritSectRwGetWriteRecursion(PPDMCRITSECTRW pThis) 841 1014 { 842 1015 /* … … 844 1017 */ 845 1018 AssertPtr(pThis); 846 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, 0);1019 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, 0); 847 1020 848 1021 /* 849 1022 * Return the requested data. 850 1023 */ 851 return pThis->cWriteRecursions; 852 } 853 RT_EXPORT_SYMBOL(RTCritSectRwGetWriteRecursion); 854 855 856 RTDECL(uint32_t) RTCritSectRwGetWriterReadRecursion(PRTCRITSECTRW pThis) 1024 return pThis->s.Core.cWriteRecursions; 1025 } 1026 1027 1028 /** 1029 * Gets the read recursion count of the current writer. 1030 * 1031 * @returns The read recursion count (0 if bad critsect). 1032 * @param pThis Pointer to the read/write critical section. 1033 * @sa PDMCritSectRwGetWriteRecursion, PDMCritSectRwGetReadCount, 1034 * RTCritSectRwGetWriterReadRecursion. 1035 */ 1036 VMMDECL(uint32_t) PDMCritSectRwGetWriterReadRecursion(PPDMCRITSECTRW pThis) 857 1037 { 858 1038 /* … … 860 1040 */ 861 1041 AssertPtr(pThis); 862 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, 0);1042 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, 0); 863 1043 864 1044 /* 865 1045 * Return the requested data. 866 1046 */ 867 return pThis->cWriterReads; 868 } 869 RT_EXPORT_SYMBOL(RTSemRWGetWriterReadRecursion); 870 871 872 RTDECL(uint32_t) RTSemRWGetReadCount(PRTCRITSECTRW pThis) 1047 return pThis->s.Core.cWriterReads; 1048 } 1049 1050 1051 /** 1052 * Gets the current number of reads. 1053 * 1054 * This includes all read recursions, so it might be higher than the number of 1055 * read owners. It does not include reads done by the current writer. 1056 * 1057 * @returns The read count (0 if bad critsect). 1058 * @param pThis Pointer to the read/write critical section. 1059 * @sa PDMCritSectRwGetWriteRecursion, PDMCritSectRwGetWriterReadRecursion, 1060 * RTCritSectRwGetReadCount. 1061 */ 1062 VMMDECL(uint32_t) PDMCritSectRwGetReadCount(PPDMCRITSECTRW pThis) 873 1063 { 874 1064 /* … … 876 1066 */ 877 1067 AssertPtr(pThis); 878 AssertReturn(pThis-> u32Magic == RTCRITSECTRW_MAGIC, 0);1068 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, 0); 879 1069 880 1070 /* 881 1071 * Return the requested data. 882 1072 */ 883 uint64_t u64State = ASMAtomicReadU64(&pThis-> u64State);1073 uint64_t u64State = ASMAtomicReadU64(&pThis->s.Core.u64State); 884 1074 if ((u64State & RTCSRW_DIR_MASK) != (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT)) 885 1075 return 0; 886 1076 return (u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT; 887 1077 } 888 RT_EXPORT_SYMBOL(RTSemRWGetReadCount); 889 890 891 RTDECL(int) RTCritSectRwDelete(PRTCRITSECTRW pThis) 892 { 893 /* 894 * Assert free waiters and so on. 895 */ 1078 1079 1080 /** 1081 * Checks if the read/write critical section is initialized or not. 1082 * 1083 * @retval @c true if initialized. 1084 * @retval @c false if not initialized. 1085 * @param pThis Pointer to the read/write critical section. 1086 * @sa PDMCritSectIsInitialized, RTCritSectRwIsInitialized. 1087 */ 1088 VMMDECL(bool) PDMCritSectRwIsInitialized(PCPDMCRITSECTRW pThis) 1089 { 896 1090 AssertPtr(pThis); 897 Assert(pThis->u32Magic == RTCRITSECTRW_MAGIC); 898 //Assert(pThis->cNestings == 0); 899 //Assert(pThis->cLockers == -1); 900 Assert(pThis->hNativeWriter == NIL_RTNATIVETHREAD); 901 902 /* 903 * Invalidate the structure and free the semaphores. 904 */ 905 if (!ASMAtomicCmpXchgU32(&pThis->u32Magic, RTCRITSECTRW_MAGIC_DEAD, RTCRITSECTRW_MAGIC)) 906 return VERR_INVALID_PARAMETER; 907 908 pThis->fFlags = 0; 909 pThis->u64State = 0; 910 911 RTSEMEVENT hEvtWrite = pThis->hEvtWrite; 912 pThis->hEvtWrite = NIL_RTSEMEVENT; 913 RTSEMEVENTMULTI hEvtRead = pThis->hEvtRead; 914 pThis->hEvtRead = NIL_RTSEMEVENTMULTI; 915 916 int rc1 = RTSemEventDestroy(hEvtWrite); AssertRC(rc1); 917 int rc2 = RTSemEventMultiDestroy(hEvtRead); AssertRC(rc2); 918 919 RTLockValidatorRecSharedDestroy(&pThis->pValidatorRead); 920 RTLockValidatorRecExclDestroy(&pThis->pValidatorWrite); 921 922 return RT_SUCCESS(rc1) ? rc2 : rc1; 923 } 924 RT_EXPORT_SYMBOL(RTCritSectRwDelete); 925 1091 return pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC; 1092 } 1093 -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r45108 r45152 1409 1409 1410 1410 if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PDM_CRITSECT)) 1411 PDMCritSect FF(pVCpu);1411 PDMCritSectBothFF(pVCpu); 1412 1412 1413 1413 /* Update CR3 (Nested Paging case for HM). */ -
trunk/src/VBox/VMM/VMMR3/PDM.cpp
r45024 r45152 343 343 pUVM->pdm.s.pModules = NULL; 344 344 pUVM->pdm.s.pCritSects = NULL; 345 pUVM->pdm.s.pRwCritSects = NULL; 345 346 return RTCritSectInit(&pUVM->pdm.s.ListCritSect); 346 347 } … … 374 375 * Initialize critical sections first. 375 376 */ 376 int rc = pdmR3CritSect InitStats(pVM);377 int rc = pdmR3CritSectBothInitStats(pVM); 377 378 if (RT_SUCCESS(rc)) 378 379 rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.CritSect, RT_SRC_POS, "PDM"); … … 458 459 * Critical sections. 459 460 */ 460 pdmR3CritSect Relocate(pVM);461 pdmR3CritSectBothRelocate(pVM); 461 462 462 463 /* … … 660 661 TMR3TimerDestroyDevice(pVM, pDevIns); 661 662 SSMR3DeregisterDevice(pVM, pDevIns, NULL, 0); 662 pdmR3CritSect DeleteDevice(pVM, pDevIns);663 pdmR3CritSectBothDeleteDevice(pVM, pDevIns); 663 664 pdmR3ThreadDestroyDevice(pVM, pDevIns); 664 665 PDMR3QueueDestroyDevice(pVM, pDevIns); … … 702 703 */ 703 704 PDMR3CritSectDelete(&pVM->pdm.s.CritSect); 704 /* The MiscCritSect is deleted by PDMR3CritSect Term. */705 /* The MiscCritSect is deleted by PDMR3CritSectBothTerm later. */ 705 706 706 707 LogFlow(("PDMR3Term: returns %Rrc\n", VINF_SUCCESS)); … … 726 727 727 728 Assert(pUVM->pdm.s.pCritSects == NULL); 729 Assert(pUVM->pdm.s.pRwCritSects == NULL); 728 730 RTCritSectDelete(&pUVM->pdm.s.ListCritSect); 729 731 } -
trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp
r44528 r45152 23 23 #include "PDMInternal.h" 24 24 #include <VBox/vmm/pdmcritsect.h> 25 #include <VBox/vmm/pdmcritsectrw.h> 25 26 #include <VBox/vmm/mm.h> 26 27 #include <VBox/vmm/vm.h> … … 41 42 *******************************************************************************/ 42 43 static int pdmR3CritSectDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTINT pCritSect, PPDMCRITSECTINT pPrev, bool fFinal); 44 static int pdmR3CritSectRwDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTRWINT pCritSect, PPDMCRITSECTRWINT pPrev, bool fFinal); 43 45 44 46 … … 50 52 * @param pVM Pointer to the VM. 51 53 */ 52 int pdmR3CritSect InitStats(PVM pVM)54 int pdmR3CritSectBothInitStats(PVM pVM) 53 55 { 54 56 STAM_REG(pVM, &pVM->pdm.s.StatQueuedCritSectLeaves, STAMTYPE_COUNTER, "/PDM/QueuedCritSectLeaves", STAMUNIT_OCCURENCES, … … 63 65 * @param pVM Pointer to the VM. 64 66 */ 65 void pdmR3CritSect Relocate(PVM pVM)67 void pdmR3CritSectBothRelocate(PVM pVM) 66 68 { 67 69 PUVM pUVM = pVM->pUVM; … … 69 71 70 72 for (PPDMCRITSECTINT pCur = pUVM->pdm.s.pCritSects; 73 pCur; 74 pCur = pCur->pNext) 75 pCur->pVMRC = pVM->pVMRC; 76 77 for (PPDMCRITSECTRWINT pCur = pUVM->pdm.s.pRwCritSects; 71 78 pCur; 72 79 pCur = pCur->pNext) … … 91 98 * @remark Don't confuse this with PDMR3CritSectDelete. 92 99 */ 93 VMM DECL(int) PDMR3CritSectTerm(PVM pVM)100 VMMR3_INT_DECL(int) PDMR3CritSectBothTerm(PVM pVM) 94 101 { 95 102 PUVM pUVM = pVM->pUVM; … … 100 107 { 101 108 int rc2 = pdmR3CritSectDeleteOne(pVM, pUVM, pUVM->pdm.s.pCritSects, NULL, true /* final */); 109 AssertRC(rc2); 110 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 111 rc = rc2; 112 } 113 114 while (pUVM->pdm.s.pRwCritSects) 115 { 116 int rc2 = pdmR3CritSectRwDeleteOne(pVM, pUVM, pUVM->pdm.s.pRwCritSects, NULL, true /* final */); 102 117 AssertRC(rc2); 103 118 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) … … 127 142 { 128 143 VM_ASSERT_EMT(pVM); 144 Assert(pCritSect->Core.u32Magic != RTCRITSECT_MAGIC); 129 145 130 146 /* … … 168 184 pCritSect->fUsedByTimerOrSimilar = false; 169 185 pCritSect->EventToSignal = NIL_RTSEMEVENT; 170 pCritSect->pNext = pVM->pUVM->pdm.s.pCritSects;171 186 pCritSect->pszName = pszName; 172 pVM->pUVM->pdm.s.pCritSects = pCritSect; 187 173 188 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZLock, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSects/%s/ContentionRZLock", pCritSect->pszName); 174 189 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZUnlock,STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSects/%s/ContentionRZUnlock", pCritSect->pszName); … … 177 192 STAMR3RegisterF(pVM, &pCritSect->StatLocked, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, NULL, "/PDM/CritSects/%s/Locked", pCritSect->pszName); 178 193 #endif 194 195 PUVM pUVM = pVM->pUVM; 196 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 197 pCritSect->pNext = pUVM->pdm.s.pCritSects; 198 pUVM->pdm.s.pCritSects = pCritSect; 199 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 200 179 201 return VINF_SUCCESS; 180 202 } … … 191 213 192 214 /** 215 * Initializes a read/write critical section and inserts it into the list. 216 * 217 * @returns VBox status code. 218 * @param pVM Pointer to the VM. 219 * @param pCritSect The read/write critical section. 220 * @param pvKey The owner key. 221 * @param RT_SRC_POS_DECL The source position. 222 * @param pszName The name of the critical section (for statistics). 223 * @param pszNameFmt Format string for naming the critical section. For 224 * statistics and lock validation. 225 * @param va Arguments for the format string. 226 */ 227 static int pdmR3CritSectRwInitOne(PVM pVM, PPDMCRITSECTRWINT pCritSect, void *pvKey, RT_SRC_POS_DECL, 228 const char *pszNameFmt, va_list va) 229 { 230 VM_ASSERT_EMT(pVM); 231 Assert(pCritSect->Core.u32Magic != RTCRITSECTRW_MAGIC); 232 233 /* 234 * Allocate the semaphores. 235 */ 236 AssertCompile(sizeof(SUPSEMEVENT) == sizeof(pCritSect->Core.hEvtWrite)); 237 int rc = SUPSemEventCreate(pVM->pSession, (PSUPSEMEVENT)&pCritSect->Core.hEvtWrite); 238 if (RT_SUCCESS(rc)) 239 { 240 AssertCompile(sizeof(SUPSEMEVENTMULTI) == sizeof(pCritSect->Core.hEvtRead)); 241 rc = SUPSemEventMultiCreate(pVM->pSession, (PSUPSEMEVENT)&pCritSect->Core.hEvtRead); 242 if (RT_SUCCESS(rc)) 243 { 244 /* Only format the name once. */ 245 char *pszName = RTStrAPrintf2V(pszNameFmt, va); /** @todo plug the "leak"... */ 246 if (pszName) 247 { 248 pCritSect->Core.pValidatorRead = NULL; 249 pCritSect->Core.pValidatorWrite = NULL; 250 #ifdef PDMCRITSECT_STRICT 251 # ifdef RT_LOCK_STRICT_ORDER 252 RTLOCKVALCLASS hClass = RTLockValidatorClassForSrcPos(RT_SRC_POS_ARGS, "%s", pszName); 253 # else 254 RTLOCKVALCLASS hClass = NIL_RTLOCKVALCLASS; 255 # endif 256 rc = RTLockValidatorRecExclCreate(&pCritSect->Core.pValidatorWrite, hClass, RTLOCKVAL_SUB_CLASS_NONE, 257 pCritSect, true, "%s", pszName); 258 if (RT_SUCCESS(rc)) 259 rc = RTLockValidatorRecSharedCreate(&pCritSect->Core.pValidatorRead, hClass, RTLOCKVAL_SUB_CLASS_NONE, 260 pCritSect, false /*fSignaller*/, true, "%s", pszName); 261 #endif 262 if (RT_SUCCESS(rc)) 263 { 264 /* 265 * Initialize the structure (first bit is c&p from RTCritSectRwInitEx). 266 */ 267 pCritSect->Core.u32Magic = RTCRITSECTRW_MAGIC_DEAD; 268 pCritSect->Core.fNeedReset = false; 269 pCritSect->Core.u64State = 0; 270 pCritSect->Core.hNativeWriter = NIL_RTNATIVETHREAD; 271 pCritSect->Core.cWriterReads = 0; 272 pCritSect->Core.cWriteRecursions = 0; 273 pCritSect->Core.pValidatorWrite = NULL; 274 pCritSect->Core.pValidatorRead = NULL; 275 #if HC_ARCH_BITS == 32 276 pCritSect->Core.HCPtrPadding = NIL_RTHCPTR; 277 #endif 278 pCritSect->pVMR3 = pVM; 279 pCritSect->pVMR0 = pVM->pVMR0; 280 pCritSect->pVMRC = pVM->pVMRC; 281 pCritSect->pvKey = pvKey; 282 pCritSect->pszName = pszName; 283 284 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZEnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZEnterExcl", pCritSect->pszName); 285 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZLeaveExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZLeaveExcl", pCritSect->pszName); 286 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZEnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZEnterShared", pCritSect->pszName); 287 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZLeaveShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZLeaveShared", pCritSect->pszName); 288 STAMR3RegisterF(pVM, &pCritSect->StatContentionR3EnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionR3EnterExcl", pCritSect->pszName); 289 STAMR3RegisterF(pVM, &pCritSect->StatContentionR3EnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionR3EnterShared", pCritSect->pszName); 290 STAMR3RegisterF(pVM, &pCritSect->StatRZEnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/RZEnterExcl", pCritSect->pszName); 291 STAMR3RegisterF(pVM, &pCritSect->StatRZEnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/RZEnterShared", pCritSect->pszName); 292 STAMR3RegisterF(pVM, &pCritSect->StatR3EnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/R3EnterExcl", pCritSect->pszName); 293 STAMR3RegisterF(pVM, &pCritSect->StatR3EnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/R3EnterShared", pCritSect->pszName); 294 #ifdef VBOX_WITH_STATISTICS 295 STAMR3RegisterF(pVM, &pCritSect->StatWriteLocked, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, NULL, "/PDM/CritSectsRw/%s/WriteLocked", pCritSect->pszName); 296 #endif 297 298 PUVM pUVM = pVM->pUVM; 299 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 300 pCritSect->pNext = pUVM->pdm.s.pRwCritSects; 301 pUVM->pdm.s.pRwCritSects = pCritSect; 302 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 303 304 return VINF_SUCCESS; 305 } 306 307 RTStrFree(pszName); 308 } 309 else 310 rc = VERR_NO_STR_MEMORY; 311 SUPSemEventMultiClose(pVM->pSession, (SUPSEMEVENT)pCritSect->Core.hEvtRead); 312 } 313 SUPSemEventClose(pVM->pSession, (SUPSEMEVENT)pCritSect->Core.hEvtWrite); 314 } 315 return rc; 316 } 317 318 319 /** 193 320 * Initializes a PDM critical section for internal use. 194 321 * 195 322 * The PDM critical sections are derived from the IPRT critical sections, but 196 * works in GCas well.323 * works in ring-0 and raw-mode context as well. 197 324 * 198 325 * @returns VBox status code. … … 204 331 * statistics and lock validation. 205 332 * @param ... Arguments for the format string. 206 * @thread EMT (0)333 * @thread EMT 207 334 */ 208 335 VMMR3DECL(int) PDMR3CritSectInit(PVM pVM, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...) … … 221 348 222 349 /** 350 * Initializes a PDM read/write critical section for internal use. 351 * 352 * The PDM read/write critical sections are derived from the IPRT read/write 353 * critical sections, but works in ring-0 and raw-mode context as well. 354 * 355 * @returns VBox status code. 356 * @param pVM Pointer to the VM. 357 * @param pDevIns Device instance. 358 * @param pCritSect Pointer to the read/write critical section. 359 * @param RT_SRC_POS_DECL Use RT_SRC_POS. 360 * @param pszNameFmt Format string for naming the critical section. For 361 * statistics and lock validation. 362 * @param ... Arguments for the format string. 363 * @thread EMT 364 */ 365 VMMR3DECL(int) PDMR3CritSectRwInit(PVM pVM, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...) 366 { 367 #if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32 368 AssertCompile(sizeof(pCritSect->padding) >= sizeof(pCritSect->s)); 369 #endif 370 Assert(RT_ALIGN_P(pCritSect, sizeof(uintptr_t)) == pCritSect); 371 va_list va; 372 va_start(va, pszNameFmt); 373 int rc = pdmR3CritSectRwInitOne(pVM, &pCritSect->s, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va); 374 va_end(va); 375 return rc; 376 } 377 378 379 /** 223 380 * Initializes a PDM critical section for a device. 224 *225 * The PDM critical sections are derived from the IPRT critical sections, but226 * works in GC as well.227 381 * 228 382 * @returns VBox status code. … … 238 392 { 239 393 return pdmR3CritSectInitOne(pVM, &pCritSect->s, pDevIns, RT_SRC_POS_ARGS, pszNameFmt, va); 394 } 395 396 397 /** 398 * Initializes a PDM read/write critical section for a device. 399 * 400 * @returns VBox status code. 401 * @param pVM Pointer to the VM. 402 * @param pDevIns Device instance. 403 * @param pCritSect Pointer to the read/write critical section. 404 * @param pszNameFmt Format string for naming the critical section. For 405 * statistics and lock validation. 406 * @param va Arguments for the format string. 407 */ 408 int pdmR3CritSectRwInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, 409 const char *pszNameFmt, va_list va) 410 { 411 return pdmR3CritSectRwInitOne(pVM, &pCritSect->s, pDevIns, RT_SRC_POS_ARGS, pszNameFmt, va); 240 412 } 241 413 … … 279 451 va_start(va, pszNameFmt); 280 452 int rc = pdmR3CritSectInitOne(pVM, &pCritSect->s, pDrvIns, RT_SRC_POS_ARGS, pszNameFmt, va); 453 va_end(va); 454 return rc; 455 } 456 457 458 /** 459 * Initializes a PDM read/write critical section for a driver. 460 * 461 * @returns VBox status code. 462 * @param pVM Pointer to the VM. 463 * @param pDrvIns Driver instance. 464 * @param pCritSect Pointer to the read/write critical section. 465 * @param pszNameFmt Format string for naming the critical section. For 466 * statistics and lock validation. 467 * @param ... Arguments for the format string. 468 */ 469 int pdmR3CritSectRwInitDriver(PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, 470 const char *pszNameFmt, ...) 471 { 472 va_list va; 473 va_start(va, pszNameFmt); 474 int rc = pdmR3CritSectRwInitOne(pVM, &pCritSect->s, pDrvIns, RT_SRC_POS_ARGS, pszNameFmt, va); 281 475 va_end(va); 282 476 return rc; … … 349 543 350 544 /** 545 * Deletes one read/write critical section. 546 * 547 * @returns VBox status code. 548 * 549 * @param pVM Pointer to the VM. 550 * @param pCritSect The read/write critical section. 551 * @param pPrev The previous critical section in the list. 552 * @param fFinal Set if this is the final call and statistics shouldn't be deregistered. 553 * 554 * @remarks Caller must have entered the ListCritSect. 555 */ 556 static int pdmR3CritSectRwDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTRWINT pCritSect, PPDMCRITSECTRWINT pPrev, bool fFinal) 557 { 558 /* 559 * Assert free waiters and so on (c&p from RTCritSectRwDelete). 560 */ 561 Assert(pCritSect->Core.u32Magic == RTCRITSECTRW_MAGIC); 562 //Assert(pCritSect->Core.cNestings == 0); 563 //Assert(pCritSect->Core.cLockers == -1); 564 Assert(pCritSect->Core.hNativeWriter == NIL_RTNATIVETHREAD); 565 566 /* 567 * Invalidate the structure and free the semaphores. 568 */ 569 if (!ASMAtomicCmpXchgU32(&pCritSect->Core.u32Magic, RTCRITSECTRW_MAGIC_DEAD, RTCRITSECTRW_MAGIC)) 570 AssertFailed(); 571 572 /* 573 * Unlink it. 574 */ 575 if (pPrev) 576 pPrev->pNext = pCritSect->pNext; 577 else 578 pUVM->pdm.s.pRwCritSects = pCritSect->pNext; 579 580 /* 581 * Delete it (parts taken from RTCritSectRwDelete). 582 * In case someone is waiting we'll signal the semaphore cLockers + 1 times. 583 */ 584 pCritSect->Core.fFlags = 0; 585 pCritSect->Core.u64State = 0; 586 587 SUPSEMEVENT hEvtWrite = (SUPSEMEVENT)pCritSect->Core.hEvtWrite; 588 pCritSect->Core.hEvtWrite = NIL_RTSEMEVENT; 589 AssertCompile(sizeof(hEvtWrite) == sizeof(pCritSect->Core.hEvtWrite)); 590 591 SUPSEMEVENTMULTI hEvtRead = (SUPSEMEVENTMULTI)pCritSect->Core.hEvtRead; 592 pCritSect->Core.hEvtRead = NIL_RTSEMEVENTMULTI; 593 AssertCompile(sizeof(hEvtRead) == sizeof(pCritSect->Core.hEvtRead)); 594 595 int rc1 = SUPSemEventClose(pVM->pSession, hEvtWrite); AssertRC(rc1); 596 int rc2 = SUPSemEventMultiClose(pVM->pSession, hEvtRead); AssertRC(rc2); 597 598 RTLockValidatorRecSharedDestroy(&pCritSect->Core.pValidatorRead); 599 RTLockValidatorRecExclDestroy(&pCritSect->Core.pValidatorWrite); 600 601 pCritSect->pNext = NULL; 602 pCritSect->pvKey = NULL; 603 pCritSect->pVMR3 = NULL; 604 pCritSect->pVMR0 = NIL_RTR0PTR; 605 pCritSect->pVMRC = NIL_RTRCPTR; 606 RTStrFree((char *)pCritSect->pszName); 607 pCritSect->pszName = NULL; 608 if (!fFinal) 609 { 610 STAMR3Deregister(pVM, &pCritSect->StatContentionRZEnterExcl); 611 STAMR3Deregister(pVM, &pCritSect->StatContentionRZLeaveExcl); 612 STAMR3Deregister(pVM, &pCritSect->StatContentionRZEnterShared); 613 STAMR3Deregister(pVM, &pCritSect->StatContentionRZLeaveShared); 614 STAMR3Deregister(pVM, &pCritSect->StatRZEnterExcl); 615 STAMR3Deregister(pVM, &pCritSect->StatRZEnterShared); 616 STAMR3Deregister(pVM, &pCritSect->StatContentionR3EnterExcl); 617 STAMR3Deregister(pVM, &pCritSect->StatContentionR3EnterShared); 618 STAMR3Deregister(pVM, &pCritSect->StatR3EnterExcl); 619 STAMR3Deregister(pVM, &pCritSect->StatR3EnterShared); 620 #ifdef VBOX_WITH_STATISTICS 621 STAMR3Deregister(pVM, &pCritSect->StatWriteLocked); 622 #endif 623 } 624 625 return RT_SUCCESS(rc1) ? rc2 : rc1; 626 } 627 628 629 /** 351 630 * Deletes all critical sections with a give initializer key. 352 631 * … … 388 667 389 668 /** 390 * Deletes all undeleted critical sections initialized by a given device. 669 * Deletes all read/write critical sections with a give initializer key. 670 * 671 * @returns VBox status code. 672 * The entire list is processed on failure, so we'll only 673 * return the first error code. This shouldn't be a problem 674 * since errors really shouldn't happen here. 675 * @param pVM Pointer to the VM. 676 * @param pvKey The initializer key. 677 */ 678 static int pdmR3CritSectRwDeleteByKey(PVM pVM, void *pvKey) 679 { 680 /* 681 * Iterate the list and match key. 682 */ 683 PUVM pUVM = pVM->pUVM; 684 int rc = VINF_SUCCESS; 685 PPDMCRITSECTRWINT pPrev = NULL; 686 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 687 PPDMCRITSECTRWINT pCur = pUVM->pdm.s.pRwCritSects; 688 while (pCur) 689 { 690 if (pCur->pvKey == pvKey) 691 { 692 int rc2 = pdmR3CritSectRwDeleteOne(pVM, pUVM, pCur, pPrev, false /* not final */); 693 AssertRC(rc2); 694 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 695 rc = rc2; 696 } 697 698 /* next */ 699 pPrev = pCur; 700 pCur = pCur->pNext; 701 } 702 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 703 return rc; 704 } 705 706 707 /** 708 * Deletes all undeleted critical sections (both types) initialized by a given 709 * device. 391 710 * 392 711 * @returns VBox status code. … … 394 713 * @param pDevIns The device handle. 395 714 */ 396 int pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns) 397 { 398 return pdmR3CritSectDeleteByKey(pVM, pDevIns); 399 } 400 401 402 /** 403 * Deletes all undeleted critical sections initialized by a given driver. 715 int pdmR3CritSectBothDeleteDevice(PVM pVM, PPDMDEVINS pDevIns) 716 { 717 int rc1 = pdmR3CritSectDeleteByKey(pVM, pDevIns); 718 int rc2 = pdmR3CritSectRwDeleteByKey(pVM, pDevIns); 719 return RT_SUCCESS(rc1) ? rc2 : rc1; 720 } 721 722 723 /** 724 * Deletes all undeleted critical sections (both types) initialized by a given 725 * driver. 404 726 * 405 727 * @returns VBox status code. … … 407 729 * @param pDrvIns The driver handle. 408 730 */ 409 int pdmR3CritSectDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns) 410 { 411 return pdmR3CritSectDeleteByKey(pVM, pDrvIns); 731 int pdmR3CritSectBothDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns) 732 { 733 int rc1 = pdmR3CritSectDeleteByKey(pVM, pDrvIns); 734 int rc2 = pdmR3CritSectRwDeleteByKey(pVM, pDrvIns); 735 return RT_SUCCESS(rc1) ? rc2 : rc1; 412 736 } 413 737 … … 453 777 454 778 /** 779 * Deletes the read/write critical section. 780 * 781 * @returns VBox status code. 782 * @param pCritSect The PDM read/write critical section to destroy. 783 */ 784 VMMR3DECL(int) PDMR3CritSectRwDelete(PPDMCRITSECTRW pCritSect) 785 { 786 if (!PDMCritSectRwIsInitialized(pCritSect)) 787 return VINF_SUCCESS; 788 789 /* 790 * Find and unlink it. 791 */ 792 PVM pVM = pCritSect->s.pVMR3; 793 PUVM pUVM = pVM->pUVM; 794 AssertReleaseReturn(pVM, VERR_PDM_CRITSECT_IPE); 795 PPDMCRITSECTRWINT pPrev = NULL; 796 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 797 PPDMCRITSECTRWINT pCur = pUVM->pdm.s.pRwCritSects; 798 while (pCur) 799 { 800 if (pCur == &pCritSect->s) 801 { 802 int rc = pdmR3CritSectRwDeleteOne(pVM, pUVM, pCur, pPrev, false /* not final */); 803 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 804 return rc; 805 } 806 807 /* next */ 808 pPrev = pCur; 809 pCur = pCur->pNext; 810 } 811 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 812 AssertReleaseMsgFailed(("pCritSect=%p wasn't found!\n", pCritSect)); 813 return VERR_PDM_CRITSECT_NOT_FOUND; 814 } 815 816 817 /** 455 818 * Gets the name of the critical section. 456 819 * … … 464 827 AssertPtrReturn(pCritSect, NULL); 465 828 AssertReturn(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC, NULL); 829 return pCritSect->s.pszName; 830 } 831 832 833 /** 834 * Gets the name of the read/write critical section. 835 * 836 * 837 * @returns Pointer to the critical section name (read only) on success, 838 * NULL on failure (invalid critical section). 839 * @param pCritSect The read/write critical section. 840 */ 841 VMMR3DECL(const char *) PDMR3CritSectRwName(PCPDMCRITSECTRW pCritSect) 842 { 843 AssertPtrReturn(pCritSect, NULL); 844 AssertReturn(pCritSect->s.Core.u32Magic == RTCRITSECTRW_MAGIC, NULL); 466 845 return pCritSect->s.pszName; 467 846 } … … 557 936 558 937 /** 559 * Counts the critical sections owned by the calling thread, optionally 560 * returning a comma separated list naming them. 938 * PDMR3CritSectBothCountOwned worker. 939 * 940 * @param pszName The critical section name. 941 * @param ppszNames Pointer to the pszNames variable. 942 * @param pcchLeft Pointer to the cchLeft variable. 943 * @param fFirst Whether this is the first name or not. 944 */ 945 static void pdmR3CritSectAppendNameToList(char const *pszName, char **ppszNames, size_t *pcchLeft, bool fFirst) 946 { 947 size_t cchLeft = *pcchLeft; 948 if (cchLeft) 949 { 950 char *pszNames = *ppszNames; 951 952 /* try add comma. */ 953 if (fFirst) 954 { 955 *pszNames++ = ','; 956 if (--cchLeft) 957 { 958 *pszNames++ = ' '; 959 cchLeft--; 960 } 961 } 962 963 /* try copy the name. */ 964 if (cchLeft) 965 { 966 size_t const cchName = strlen(pszName); 967 if (cchName < cchLeft) 968 { 969 memcpy(pszNames, pszName, cchName); 970 pszNames += cchName; 971 cchLeft -= cchName; 972 } 973 else 974 { 975 if (cchLeft > 2) 976 { 977 memcpy(pszNames, pszName, cchLeft - 2); 978 pszNames += cchLeft - 2; 979 cchLeft = 2; 980 } 981 while (cchLeft-- > 0) 982 *pszNames++ = '+'; 983 } 984 } 985 *pszNames = '\0'; 986 987 *pcchLeft = cchLeft; 988 *ppszNames = pszNames; 989 } 990 } 991 992 993 /** 994 * Counts the critical sections (both type) owned by the calling thread, 995 * optionally returning a comma separated list naming them. 996 * 997 * Read ownerships are not included in non-strict builds. 561 998 * 562 999 * This is for diagnostic purposes only. … … 583 1020 * Iterate the critical sections. 584 1021 */ 1022 uint32_t cCritSects = 0; 1023 RTNATIVETHREAD const hNativeThread = RTThreadNativeSelf(); 585 1024 /* This is unsafe, but wtf. */ 586 RTNATIVETHREAD const hNativeThread = RTThreadNativeSelf();587 uint32_t cCritSects = 0;588 1025 for (PPDMCRITSECTINT pCur = pVM->pUVM->pdm.s.pCritSects; 589 1026 pCur; … … 594 1031 { 595 1032 cCritSects++; 596 597 /* 598 * Copy the name if there is space. Fun stuff. 599 */ 600 if (cchLeft) 601 { 602 /* try add comma. */ 603 if (cCritSects != 1) 604 { 605 *pszNames++ = ','; 606 if (--cchLeft) 607 { 608 *pszNames++ = ' '; 609 cchLeft--; 610 } 611 } 612 613 /* try copy the name. */ 614 if (cchLeft) 615 { 616 size_t const cchName = strlen(pCur->pszName); 617 if (cchName < cchLeft) 618 { 619 memcpy(pszNames, pCur->pszName, cchName); 620 pszNames += cchName; 621 cchLeft -= cchName; 622 } 623 else 624 { 625 if (cchLeft > 2) 626 { 627 memcpy(pszNames, pCur->pszName, cchLeft - 2); 628 pszNames += cchLeft - 2; 629 cchLeft = 2; 630 } 631 while (cchLeft-- > 0) 632 *pszNames++ = '+'; 633 } 634 } 635 *pszNames = '\0'; 636 } 1033 pdmR3CritSectAppendNameToList(pCur->pszName, &pszNames, &cchLeft, cCritSects == 1); 1034 } 1035 } 1036 1037 /* This is unsafe, but wtf. */ 1038 for (PPDMCRITSECTRWINT pCur = pVM->pUVM->pdm.s.pRwCritSects; 1039 pCur; 1040 pCur = pCur->pNext) 1041 { 1042 if ( pCur->Core.hNativeWriter == hNativeThread 1043 || PDMCritSectRwIsReadOwner((PPDMCRITSECTRW)pCur, false /*fWannaHear*/) ) 1044 { 1045 cCritSects++; 1046 pdmR3CritSectAppendNameToList(pCur->pszName, &pszNames, &cchLeft, cCritSects == 1); 637 1047 } 638 1048 } … … 650 1060 * @param pVM Pointer to the VM. 651 1061 */ 652 VMMR3 DECL(void) PDMR3CritSectLeaveAll(PVM pVM)1062 VMMR3_INT_DECL(void) PDMR3CritSectLeaveAll(PVM pVM) 653 1063 { 654 1064 RTNATIVETHREAD const hNativeSelf = RTThreadNativeSelf(); -
trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp
r44358 r45152 962 962 963 963 /* PDM critsects. */ 964 rc = pdmR3CritSect DeleteDriver(pVM, pCur);964 rc = pdmR3CritSectBothDeleteDriver(pVM, pCur); 965 965 AssertRC(rc); 966 966 -
trunk/src/VBox/VMM/VMMR3/VM.cpp
r45024 r45152 781 781 * references to it are still working. 782 782 */ 783 PDMR3CritSect Term(pVM);783 PDMR3CritSectBothTerm(pVM); 784 784 785 785 /* … … 2440 2440 AssertRC(rc); 2441 2441 SSMR3Term(pVM); 2442 rc = PDMR3CritSect Term(pVM);2442 rc = PDMR3CritSectBothTerm(pVM); 2443 2443 AssertRC(rc); 2444 2444 rc = MMR3Term(pVM); -
trunk/src/VBox/VMM/VMMR3/VMM.cpp
r44971 r45152 2098 2098 */ 2099 2099 if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PDM_CRITSECT)) 2100 PDMCritSect FF(pVCpu);2100 PDMCritSectBothFF(pVCpu); 2101 2101 2102 2102 switch (pVCpu->vmm.s.enmCallRing3Operation) -
trunk/src/VBox/VMM/include/PDMInternal.h
r44528 r45152 33 33 #include <VBox/vmm/pdmblkcache.h> 34 34 #include <VBox/vmm/pdmcommon.h> 35 #include <VBox/sup.h> 35 36 #include <iprt/assert.h> 36 37 #include <iprt/critsect.h> … … 56 57 /** @def PDMCRITSECT_STRICT 57 58 * Enables/disables PDM critsect strictness like deadlock detection. */ 58 #if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(IEM_VERIFICATION_MODE)) || defined(DOXYGEN_RUNNING) 59 #if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(IEM_VERIFICATION_MODE) && !defined(PDMCRITSECT_STRICT)) \ 60 || defined(DOXYGEN_RUNNING) 59 61 # define PDMCRITSECT_STRICT 62 #endif 63 64 /** @def PDMCRITSECT_STRICT 65 * Enables/disables PDM read/write critsect strictness like deadlock 66 * detection. */ 67 #if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(IEM_VERIFICATION_MODE) && !defined(PDMCRITSECTRW_STRICT)) \ 68 || defined(DOXYGEN_RUNNING) 69 # define PDMCRITSECTRW_STRICT 60 70 #endif 61 71 … … 263 273 typedef struct PDMCRITSECTINT 264 274 { 265 /** The critical section core which is shared with IPRT. */ 275 /** The critical section core which is shared with IPRT. 276 * @note The semaphore is a SUPSEMEVENT. */ 266 277 RTCRITSECT Core; 267 278 /** Pointer to the next critical section. … … 310 321 311 322 /** 323 * Private critical section data. 324 */ 325 typedef struct PDMCRITSECTRWINT 326 { 327 /** The read/write critical section core which is shared with IPRT. 328 * @note The semaphores are SUPSEMEVENT and SUPSEMEVENTMULTI. */ 329 RTCRITSECTRW Core; 330 331 /** Pointer to the next critical section. 332 * This chain is used for relocating pVMRC and device cleanup. */ 333 R3PTRTYPE(struct PDMCRITSECTRWINT *) pNext; 334 /** Owner identifier. 335 * This is pDevIns if the owner is a device. Similarly for a driver or service. 336 * PDMR3CritSectInit() sets this to point to the critsect itself. */ 337 RTR3PTR pvKey; 338 /** Pointer to the VM - R3Ptr. */ 339 PVMR3 pVMR3; 340 /** Pointer to the VM - R0Ptr. */ 341 PVMR0 pVMR0; 342 /** Pointer to the VM - GCPtr. */ 343 PVMRC pVMRC; 344 #if HC_ARCH_BITS == 64 345 /** Alignment padding. */ 346 RTRCPTR RCPtrPadding; 347 #endif 348 /** The lock name. */ 349 R3PTRTYPE(const char *) pszName; 350 /** R0/RC write lock contention. */ 351 STAMCOUNTER StatContentionRZEnterExcl; 352 /** R0/RC write unlock contention. */ 353 STAMCOUNTER StatContentionRZLeaveExcl; 354 /** R0/RC read lock contention. */ 355 STAMCOUNTER StatContentionRZEnterShared; 356 /** R0/RC read unlock contention. */ 357 STAMCOUNTER StatContentionRZLeaveShared; 358 /** R0/RC writes. */ 359 STAMCOUNTER StatRZEnterExcl; 360 /** R0/RC reads. */ 361 STAMCOUNTER StatRZEnterShared; 362 /** R3 write lock contention. */ 363 STAMCOUNTER StatContentionR3EnterExcl; 364 /** R3 read lock contention. */ 365 STAMCOUNTER StatContentionR3EnterShared; 366 /** R3 writes. */ 367 STAMCOUNTER StatR3EnterExcl; 368 /** R3 reads. */ 369 STAMCOUNTER StatR3EnterShared; 370 /** Profiling the time the section is write locked. */ 371 STAMPROFILEADV StatWriteLocked; 372 } PDMCRITSECTRWINT; 373 AssertCompileMemberAlignment(PDMCRITSECTRWINT, StatContentionRZEnterExcl, 8); 374 AssertCompileMemberAlignment(PDMCRITSECTRWINT, Core.u64State, 8); 375 /** Pointer to private critical section data. */ 376 typedef PDMCRITSECTRWINT *PPDMCRITSECTRWINT; 377 378 379 380 /** 312 381 * The usual device/driver/internal/external stuff. 313 382 */ … … 355 424 #define PDMDRVINSINT_DECLARED 356 425 #define PDMCRITSECTINT_DECLARED 426 #define PDMCRITSECTRWINT_DECLARED 357 427 #define PDMTHREADINT_DECLARED 358 428 #ifdef ___VBox_pdm_h … … 945 1015 /** 946 1016 * PDM VMCPU Instance data. 947 * Changes to this must checked against the padding of the cfgm union in VMCPU!1017 * Changes to this must checked against the padding of the pdm union in VMCPU! 948 1018 */ 949 1019 typedef struct PDMCPU 950 1020 { 951 /** The number of entries in the apQueuedCritSectsLeaves table that's currently in use. */ 1021 /** The number of entries in the apQueuedCritSectsLeaves table that's currently 1022 * in use. */ 952 1023 uint32_t cQueuedCritSectLeaves; 953 1024 uint32_t uPadding0; /**< Alignment padding.*/ 954 /** Critical sections queued in RC/R0 because of contention preventing leave to complete. (R3 Ptrs) 1025 /** Critical sections queued in RC/R0 because of contention preventing leave to 1026 * complete. (R3 Ptrs) 955 1027 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */ 956 R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectsLeaves[8]; 1028 R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectLeaves[8]; 1029 1030 /** The number of entries in the apQueuedCritSectRwExclLeaves table that's 1031 * currently in use. */ 1032 uint32_t cQueuedCritSectRwExclLeaves; 1033 uint32_t uPadding1; /**< Alignment padding.*/ 1034 /** Read/write critical sections queued in RC/R0 because of contention 1035 * preventing exclusive leave to complete. (R3 Ptrs) 1036 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */ 1037 R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwExclLeaves[8]; 1038 1039 /** The number of entries in the apQueuedCritSectsRwShrdLeaves table that's 1040 * currently in use. */ 1041 uint32_t cQueuedCritSectRwShrdLeaves; 1042 uint32_t uPadding2; /**< Alignment padding.*/ 1043 /** Read/write critical sections queued in RC/R0 because of contention 1044 * preventing shared leave to complete. (R3 Ptrs) 1045 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */ 1046 R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwShrdLeaves[8]; 957 1047 } PDMCPU; 958 1048 … … 1073 1163 /** List of initialized critical sections. (LIFO) */ 1074 1164 R3PTRTYPE(PPDMCRITSECTINT) pCritSects; 1165 /** List of initialized read/write critical sections. (LIFO) */ 1166 R3PTRTYPE(PPDMCRITSECTRWINT) pRwCritSects; 1075 1167 /** Head of the PDM Thread list. (singly linked) */ 1076 1168 R3PTRTYPE(PPDMTHREAD) pThreads; … … 1155 1247 bool pdmR3IsValidName(const char *pszName); 1156 1248 1157 int pdmR3CritSectInitStats(PVM pVM); 1158 void pdmR3CritSectRelocate(PVM pVM); 1159 int pdmR3CritSectInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, va_list va); 1160 int pdmR3CritSectInitDeviceAuto(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, 1161 const char *pszNameFmt, ...); 1162 int pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns); 1163 int pdmR3CritSectInitDriver(PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...); 1164 int pdmR3CritSectDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns); 1249 int pdmR3CritSectBothInitStats(PVM pVM); 1250 void pdmR3CritSectBothRelocate(PVM pVM); 1251 int pdmR3CritSectBothDeleteDevice(PVM pVM, PPDMDEVINS pDevIns); 1252 int pdmR3CritSectBothDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns); 1253 int pdmR3CritSectInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, 1254 const char *pszNameFmt, va_list va); 1255 int pdmR3CritSectInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, 1256 const char *pszNameFmt, ...); 1257 int pdmR3CritSectInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, 1258 const char *pszNameFmt, ...); 1259 int pdmR3CritSectRwInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, 1260 const char *pszNameFmt, va_list va); 1261 int pdmR3CritSectRwInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, 1262 const char *pszNameFmt, ...); 1263 int pdmR3CritSectRwInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, 1264 const char *pszNameFmt, ...); 1165 1265 1166 1266 int pdmR3DevInit(PVM pVM); -
trunk/src/VBox/VMM/testcase/tstVMStruct.h
r44528 r45152 463 463 GEN_CHECK_OFF(PDM, pDevHlpQueueRC); 464 464 GEN_CHECK_OFF(PDMCPU, cQueuedCritSectLeaves); 465 GEN_CHECK_OFF(PDMCPU, apQueuedCritSectsLeaves); 465 GEN_CHECK_OFF(PDMCPU, apQueuedCritSectLeaves); 466 GEN_CHECK_OFF(PDMCPU, cQueuedCritSectRwExclLeaves); 467 GEN_CHECK_OFF(PDMCPU, apQueuedCritSectRwExclLeaves); 468 GEN_CHECK_OFF(PDMCPU, cQueuedCritSectRwShrdLeaves); 469 GEN_CHECK_OFF(PDMCPU, apQueuedCritSectRwShrdLeaves); 466 470 GEN_CHECK_OFF(PDM, pQueueFlushR0); 467 471 GEN_CHECK_OFF(PDM, pQueueFlushRC); … … 537 541 GEN_CHECK_OFF(PDMCRITSECTINT, StatContentionR3); 538 542 GEN_CHECK_OFF(PDMCRITSECTINT, StatLocked); 543 GEN_CHECK_SIZE(PDMCRITSECT); 544 GEN_CHECK_SIZE(PDMCRITSECTRWINT); 545 GEN_CHECK_OFF(PDMCRITSECTRWINT, Core); 546 GEN_CHECK_OFF(PDMCRITSECTRWINT, pNext); 547 GEN_CHECK_OFF(PDMCRITSECTRWINT, pvKey); 548 GEN_CHECK_OFF(PDMCRITSECTRWINT, pVMR3); 549 GEN_CHECK_OFF(PDMCRITSECTRWINT, pVMR0); 550 GEN_CHECK_OFF(PDMCRITSECTRWINT, pVMRC); 551 GEN_CHECK_OFF(PDMCRITSECTRWINT, pszName); 552 GEN_CHECK_OFF(PDMCRITSECTRWINT, StatContentionRZEnterExcl); 553 GEN_CHECK_OFF(PDMCRITSECTRWINT, StatWriteLocked); 554 GEN_CHECK_SIZE(PDMCRITSECTRW); 539 555 GEN_CHECK_SIZE(PDMQUEUE); 540 556 GEN_CHECK_OFF(PDMQUEUE, pNext); -
trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
r45094 r45152 348 348 349 349 CHECK_PADDING2(PDMCRITSECT); 350 CHECK_PADDING2(PDMCRITSECTRW); 350 351 351 352 /* pgm */
Note:
See TracChangeset
for help on using the changeset viewer.