Changeset 92712 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Dec 2, 2021 5:34:24 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/TM.cpp
r92709 r92712 152 152 #include <iprt/file.h> 153 153 #include <iprt/getopt.h> 154 #include <iprt/mem.h> 154 155 #include <iprt/rand.h> 155 156 #include <iprt/semaphore.h> … … 1524 1525 1525 1526 /** 1527 * Grows a timer queue. 1528 * 1529 * @returns VBox status code (errors are LogRel'ed already). 1530 * @param pVM The cross context VM structure. 1531 * @param pQueue The timer queue to grow. 1532 * @note Caller owns the queue's allocation lock. 1533 */ 1534 static int tmR3TimerQueueGrow(PVM pVM, PTMTIMERQUEUE pQueue) 1535 { 1536 /* 1537 * Validate input and state. 1538 */ 1539 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT); 1540 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE); /** @todo must do better than this! */ 1541 AssertReturn(!pQueue->fCannotGrow, VERR_TM_TIMER_QUEUE_CANNOT_GROW); 1542 1543 /* 1544 * Do the growing. 1545 */ 1546 int rc; 1547 uint32_t const cOldEntries = pQueue->cTimersAlloc; 1548 uint32_t cNewTimers = cOldEntries + 64; 1549 Assert(cNewTimers < _32K); 1550 if (!SUPR3IsDriverless()) 1551 { 1552 rc = VMMR3CallR0Emt(pVM, VMMGetCpu(pVM), VMMR0_DO_TM_GROW_TIMER_QUEUE, 1553 RT_MAKE_U64(cNewTimers, (uint64_t)(pQueue - &pVM->tm.s.aTimerQueues[0])), NULL); 1554 AssertLogRelRCReturn(rc, rc); 1555 AssertReturn(pQueue->cTimersAlloc >= cNewTimers, VERR_TM_IPE_3); 1556 } 1557 else 1558 { 1559 AssertReturn(cNewTimers <= _32K && cOldEntries <= _32K, VERR_TM_TOO_MANY_TIMERS); 1560 ASMCompilerBarrier(); 1561 1562 /* 1563 * Round up the request to the nearest page and do the allocation. 1564 */ 1565 size_t cbNew = sizeof(TMTIMER) * cNewTimers; 1566 cbNew = RT_ALIGN_Z(cbNew, PAGE_SIZE); 1567 cNewTimers = (uint32_t)(cbNew / sizeof(TMTIMER)); 1568 1569 PTMTIMER paTimers = (PTMTIMER)RTMemPageAllocZ(cbNew); 1570 if (paTimers) 1571 { 1572 /* 1573 * Copy over the old timer, init the new free ones, then switch over 1574 * and free the old ones. 1575 */ 1576 PTMTIMER const paOldTimers = pQueue->paTimers; 1577 tmHCTimerQueueGrowInit(paTimers, paOldTimers, cNewTimers, cOldEntries); 1578 1579 pQueue->paTimers = paTimers; 1580 pQueue->cTimersAlloc = cNewTimers; 1581 pQueue->cTimersFree += cNewTimers - (cOldEntries ? cOldEntries : 1); 1582 1583 RTMemPageFree(paOldTimers, RT_ALIGN_Z(sizeof(TMTIMER) * cOldEntries, PAGE_SIZE)); 1584 rc = VINF_SUCCESS; 1585 } 1586 else 1587 rc = VERR_NO_PAGE_MEMORY; 1588 } 1589 return rc; 1590 } 1591 1592 1593 /** 1526 1594 * Internal TMR3TimerCreate worker. 1527 1595 * … … 1570 1638 if (!pQueue->cTimersFree) 1571 1639 { 1572 AssertReturn(!pQueue->fCannotGrow, VERR_TM_TIMER_QUEUE_CANNOT_GROW); 1573 uint32_t cTimersAlloc = pQueue->cTimersAlloc + 64; 1574 Assert(cTimersAlloc < _32K); 1575 rc = VMMR3CallR0Emt(pVM, VMMGetCpu(pVM), VMMR0_DO_TM_GROW_TIMER_QUEUE, 1576 RT_MAKE_U64(cTimersAlloc, (uint64_t)(pQueue - &pVM->tm.s.aTimerQueues[0])), NULL); 1577 AssertLogRelRCReturnStmt(rc, PDMCritSectRwLeaveExcl(pVM, &pQueue->AllocLock), rc); 1578 AssertReturnStmt(pQueue->cTimersAlloc >= cTimersAlloc, PDMCritSectRwLeaveExcl(pVM, &pQueue->AllocLock), VERR_TM_IPE_3); 1640 rc = tmR3TimerQueueGrow(pVM, pQueue); 1641 AssertRCReturnStmt(rc, PDMCritSectRwLeaveExcl(pVM, &pQueue->AllocLock), rc); 1579 1642 } 1580 1643
Note:
See TracChangeset
for help on using the changeset viewer.