Changeset 90660 in vbox
- Timestamp:
- Aug 12, 2021 12:27:29 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp
r90659 r90660 1458 1458 #endif 1459 1459 1460 #if defined(IN_RING3) 1460 #if defined(IN_RING3) || defined(IN_RING0) 1461 1461 /* 1462 1462 * Ring-3: Straight forward, just update the state and if necessary signal waiters. 1463 */1464 # ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF1465 pThis->s.Core.cWriteRecursions = 0;1466 # else1467 ASMAtomicWriteU32(&pThis->s.Core.cWriteRecursions, 0);1468 # endif1469 STAM_PROFILE_ADV_STOP(&pThis->s.StatWriteLocked, swl);1470 ASMAtomicWriteHandle(&pThis->s.Core.u.s.hNativeWriter, NIL_RTNATIVETHREAD);1471 1472 for (;;)1473 {1474 uint64_t u64State = PDMCRITSECTRW_READ_STATE(&pThis->s.Core.u.s.u64State);1475 uint64_t u64OldState = u64State;1476 1477 uint64_t c = (u64State & RTCSRW_CNT_WR_MASK) >> RTCSRW_CNT_WR_SHIFT;1478 AssertReturn(c > 0, pdmCritSectRwCorrupted(pThis, "Invalid write count on leave"));1479 c--;1480 1481 if ( c > 01482 || (u64State & RTCSRW_CNT_RD_MASK) == 0)1483 {1484 /* Don't change the direction, wake up the next writer if any. */1485 u64State &= ~RTCSRW_CNT_WR_MASK;1486 u64State |= c << RTCSRW_CNT_WR_SHIFT;1487 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))1488 {1489 if (c > 0)1490 {1491 int rc = SUPSemEventSignal(pVM->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite);1492 AssertRC(rc);1493 }1494 return VINF_SUCCESS;1495 }1496 }1497 else1498 {1499 /* Reverse the direction and signal the reader threads. */1500 u64State &= ~(RTCSRW_CNT_WR_MASK | RTCSRW_DIR_MASK);1501 u64State |= RTCSRW_DIR_READ << RTCSRW_DIR_SHIFT;1502 if (ASMAtomicCmpXchgU64(&pThis->s.Core.u.s.u64State, u64State, u64OldState))1503 {1504 Assert(!pThis->s.Core.fNeedReset);1505 ASMAtomicWriteBool(&pThis->s.Core.fNeedReset, true);1506 int rc = SUPSemEventMultiSignal(pVM->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead);1507 AssertRC(rc);1508 return VINF_SUCCESS;1509 }1510 }1511 1512 ASMNopPause();1513 if (pThis->s.Core.u32Magic == RTCRITSECTRW_MAGIC)1514 { /*likely*/ }1515 else1516 return VERR_SEM_DESTROYED;1517 ASMNopPause();1518 }1519 1520 1521 #elif defined(IN_RING0)1522 /*1523 1463 * Ring-0: Try leave for real, depends on host and context. 1524 1464 */ 1465 # ifdef IN_RING0 1525 1466 Assert(RTSemEventIsSignalSafe() == RTSemEventMultiIsSignalSafe()); 1526 1467 PVMCPUCC pVCpu = VMMGetCpu(pVM); … … 1532 1473 && ASMIntAreEnabled()) /* ... and interrupts hasn't yet been disabled. Special pre-GC HM env. */ 1533 1474 ) 1475 # endif 1534 1476 { 1535 1477 # ifdef PDMCRITSECTRW_WITH_LESS_ATOMIC_STUFF … … 1563 1505 if (c == 0) 1564 1506 rc = VINF_SUCCESS; 1565 else if (RTSemEventIsSignalSafe() || pVCpu == NULL) 1566 rc = SUPSemEventSignal(pVM->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite); 1567 else 1507 # ifdef IN_RING0 1508 else if (!RTSemEventIsSignalSafe() && pVCpu != NULL) 1568 1509 { 1569 1510 VMMR0EMTBLOCKCTX Ctx; … … 1575 1516 VMMR0EmtResumeAfterBlocking(pVCpu, &Ctx); 1576 1517 } 1518 # endif 1519 else 1520 rc = SUPSemEventSignal(pVM->pSession, (SUPSEMEVENT)pThis->s.Core.hEvtWrite); 1577 1521 AssertRC(rc); 1578 1522 return rc; … … 1592 1536 1593 1537 int rc; 1594 if (RTSemEventMultiIsSignalSafe() || pVCpu == NULL) 1595 rc = SUPSemEventMultiSignal(pVM->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead); 1596 else 1538 # ifdef IN_RING0 1539 if (!RTSemEventMultiIsSignalSafe() && pVCpu != NULL) 1597 1540 { 1598 1541 VMMR0EMTBLOCKCTX Ctx; … … 1604 1547 VMMR0EmtResumeAfterBlocking(pVCpu, &Ctx); 1605 1548 } 1549 else 1550 # endif 1551 rc = SUPSemEventMultiSignal(pVM->pSession, (SUPSEMEVENTMULTI)pThis->s.Core.hEvtRead); 1606 1552 AssertRC(rc); 1607 1553 return rc; … … 1618 1564 /* not reached! */ 1619 1565 } 1620 #endif /* IN_RING 0 */1566 #endif /* IN_RING3 || IN_RING0 */ 1621 1567 1622 1568 #ifndef IN_RING3
Note:
See TracChangeset
for help on using the changeset viewer.