- Timestamp:
- Aug 12, 2021 9:27:26 PM (3 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
-
VMMAll/PDMAllCritSectRw.cpp (modified) (5 diffs)
-
VMMR3/PDMCritSect.cpp (modified) (1 diff)
-
include/PDMInternal.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp
r90671 r90672 208 208 209 209 /** 210 * Worker for pdmCritSectRwEnterSharedContended that decrements both read counts 211 * and returns @a rc. 212 */ 213 DECL_FORCE_INLINE(int) pdmCritSectRwEnterSharedBailOut(PPDMCRITSECTRW pThis, int rc) 214 { 215 for (;;) 216 { 217 uint64_t u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State); 218 uint64_t const u64OldState = u64State; 219 uint64_t c = (u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT; 220 AssertReturn(c > 0, pdmCritSectRwCorrupted(pThis, "Invalid read count on bailout")); 221 c--; 222 uint64_t cWait = (u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT; 223 AssertReturn(cWait > 0, pdmCritSectRwCorrupted(pThis, "Invalid waiting read count on bailout")); 224 cWait--; 225 u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_WAIT_CNT_RD_MASK); 226 u64State |= (c << RTCSRW_CNT_RD_SHIFT) | (cWait << RTCSRW_WAIT_CNT_RD_SHIFT); 227 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState)) 228 return rc; 229 230 ASMNopPause(); 231 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED); 232 } 233 } 234 235 236 /** 210 237 * Worker for pdmCritSectRwEnterShared returning with read-ownership of the CS. 211 238 */ … … 240 267 # endif 241 268 242 uint64_t u64State; 243 uint64_t u64OldState; 269 /* 270 * Wait for the direction to switch. 271 */ 244 272 for (uint32_t iLoop = 0; ; iLoop++) 245 273 { … … 249 277 rc = RTLockValidatorRecSharedCheckBlocking(pThis->s.Core.pValidatorRead, hThreadSelf, pSrcPos, true, 250 278 RT_INDEFINITE_WAIT, RTTHREADSTATE_RW_READ, false); 251 if (RT_SUCCESS(rc)) 279 if (RT_FAILURE(rc)) 280 return pdmCritSectRwEnterSharedBailOut(pThis, rc); 252 281 # else 253 282 RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_READ, false); 254 283 # endif 255 284 # endif 285 for (;;) 256 286 { 287 rc = SUPSemEventMultiWaitNoResume(pVM->pSession, 288 (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead, 289 RT_INDEFINITE_WAIT); 290 if ( rc != VERR_INTERRUPTED 291 || pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 292 break; 293 # ifdef IN_RING0 294 pdmR0CritSectRwYieldToRing3(pVM); 295 # endif 296 } 297 # ifdef IN_RING3 298 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_READ); 299 # endif 300 if (RT_LIKELY(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC)) 301 { /* likely */ } 302 else 303 return VERR_SEM_DESTROYED; 304 if (RT_SUCCESS(rc)) 305 { /* likely */ } 306 else 307 return pdmCritSectRwEnterSharedBailOut(pThis, rc); 308 309 /* 310 * Check the direction. 311 */ 312 Assert(pThis->s.Core.fNeedReset); 313 uint64_t u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State); 314 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT)) 315 { 316 /* 317 * Decrement the wait count and maybe reset the semaphore (if we're last). 318 */ 257 319 for (;;) 258 320 { 259 rc = SUPSemEventMultiWaitNoResume(pVM->pSession, 260 (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead, 261 RT_INDEFINITE_WAIT); 262 if ( rc != VERR_INTERRUPTED 263 || pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 264 break; 265 # ifdef IN_RING0 266 pdmR0CritSectRwYieldToRing3(pVM); 267 # endif 268 } 269 # ifdef IN_RING3 270 RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_RW_READ); 271 # endif 272 if (pThis->s.Core.u32Magic != RTCRITSECTRW_MAGIC) 273 return VERR_SEM_DESTROYED; 274 } 275 if (RT_FAILURE(rc)) 276 { 277 /* Decrement the counts and return the error. */ 278 for (;;) 279 { 280 u64OldState = u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State); 281 uint64_t c = (u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT; 282 AssertReturn(c > 0, pdmCritSectRwCorrupted(pThis, "Invalid read count on bailout")); 283 c--; 284 uint64_t cWait = (u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT; 285 AssertReturn(cWait > 0, pdmCritSectRwCorrupted(pThis, "Invalid waiting read count on bailout")); 321 uint64_t const u64OldState = u64State; 322 uint64_t cWait = (u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT; 323 AssertReturn(cWait > 0, pdmCritSectRwCorrupted(pThis, "Invalid waiting read count")); 324 AssertReturn((u64State & RTCSRW_CNT_RD_MASK) >> RTCSRW_CNT_RD_SHIFT > 0, 325 pdmCritSectRwCorrupted(pThis, "Invalid read count")); 286 326 cWait--; 287 u64State &= ~(RTCSRW_CNT_RD_MASK | RTCSRW_WAIT_CNT_RD_MASK); 288 u64State |= (c << RTCSRW_CNT_RD_SHIFT) | (cWait << RTCSRW_WAIT_CNT_RD_SHIFT); 327 u64State &= ~RTCSRW_WAIT_CNT_RD_MASK; 328 u64State |= cWait << RTCSRW_WAIT_CNT_RD_SHIFT; 329 289 330 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState)) 290 break; 331 { 332 if (cWait == 0) 333 { 334 if (ASMAtomicXchgBool(&pThis->s.Core.fNeedReset, false)) 335 { 336 rc = SUPSemEventMultiReset(pVM->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead); 337 AssertRCReturn(rc, rc); 338 } 339 } 340 return pdmCritSectRwEnterSharedGotIt(pThis, pSrcPos, fNoVal, hThreadSelf); 341 } 291 342 292 343 ASMNopPause(); 293 344 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED); 345 ASMNopPause(); 346 347 u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State); 294 348 } 295 return rc;349 /* not reached */ 296 350 } 297 351 298 Assert(pThis->s.Core.fNeedReset);299 u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);300 if ((u64State & RTCSRW_DIR_MASK) == (RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT))301 break;302 352 AssertMsg(iLoop < 1, ("%u\n", iLoop)); 303 } 304 305 /* Decrement the wait count and maybe reset the semaphore (if we're last). */ 306 for (;;) 307 { 308 u64OldState = u64State; 309 310 uint64_t cWait = (u64State & RTCSRW_WAIT_CNT_RD_MASK) >> RTCSRW_WAIT_CNT_RD_SHIFT; 311 AssertReturn(cWait > 0, pdmCritSectRwCorrupted(pThis, "Invalid waiting read count")); 312 cWait--; 313 u64State &= ~RTCSRW_WAIT_CNT_RD_MASK; 314 u64State |= cWait << RTCSRW_WAIT_CNT_RD_SHIFT; 315 316 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState)) 317 { 318 if (cWait == 0) 319 { 320 if (ASMAtomicXchgBool(&pThis->s.Core.fNeedReset, false)) 321 { 322 int rc = SUPSemEventMultiReset(pVM->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead); 323 AssertRCReturn(rc, rc); 324 } 325 } 326 return pdmCritSectRwEnterSharedGotIt(pThis, pSrcPos, fNoVal, hThreadSelf); 327 } 328 329 ASMNopPause(); 330 AssertReturn(pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC, VERR_SEM_DESTROYED); 331 ASMNopPause(); 332 333 u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State); 353 RTThreadYield(); 334 354 } 335 355 … … 1591 1611 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState)) 1592 1612 { 1613 STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,LeaveExcl)); 1593 1614 int rc; 1594 1615 if (c == 0) … … 1623 1644 Assert(!pThis->s.Core.fNeedReset); 1624 1645 ASMAtomicWriteBool(&pThis->s.Core.fNeedReset, true); 1646 STAM_REL_COUNTER_INC(&pThis->s.CTX_MID_Z(StatContention,LeaveExcl)); 1625 1647 1626 1648 int rc; -
trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp
r90639 r90672 310 310 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZLeaveShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZLeaveShared", pCritSect->pszName); 311 311 STAMR3RegisterF(pVM, &pCritSect->StatContentionR3EnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionR3EnterExcl", pCritSect->pszName); 312 STAMR3RegisterF(pVM, &pCritSect->StatContentionR3LeaveExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionR3LeaveExcl", pCritSect->pszName); 312 313 STAMR3RegisterF(pVM, &pCritSect->StatContentionR3EnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionR3EnterShared", pCritSect->pszName); 313 314 STAMR3RegisterF(pVM, &pCritSect->StatRZEnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/RZEnterExcl", pCritSect->pszName); -
trunk/src/VBox/VMM/include/PDMInternal.h
r90637 r90672 503 503 /** R3 write lock contention. */ 504 504 STAMCOUNTER StatContentionR3EnterExcl; 505 /** R3 write unlock contention. */ 506 STAMCOUNTER StatContentionR3LeaveExcl; 505 507 /** R3 read lock contention. */ 506 508 STAMCOUNTER StatContentionR3EnterShared;
Note:
See TracChangeset
for help on using the changeset viewer.

