VirtualBox

Ignore:
Timestamp:
May 14, 2009 5:59:34 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
47324
Message:

TM,EM: More TM/SMP work, still stuff in progress.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/TMAll.cpp

    r19660 r19709  
    8080
    8181/**
    82  * Release EMT/TM lock.
     82 * Release the EMT/TM lock.
    8383 *
    8484 * @param   pVM         The VM handle.
     
    8787{
    8888    PDMCritSectLeave(&pVM->tm.s.EmtLock);
     89}
     90
     91
     92/**
     93 * Try take the VirtualSync lock, wait in ring-3 return VERR_SEM_BUSY in R0/RC.
     94 *
     95 * @retval  VINF_SUCCESS on success (always in ring-3).
     96 * @retval  VERR_SEM_BUSY in RC and R0 if the semaphore is busy.
     97 *
     98 * @param   pVM         The VM handle.
     99 */
     100int tmVirtualSyncLock(PVM pVM)
     101{
     102    VM_ASSERT_EMT(pVM);
     103    int rc = PDMCritSectEnter(&pVM->tm.s.VirtualSyncLock, VERR_SEM_BUSY);
     104    return rc;
     105}
     106
     107
     108/**
     109 * Try take the VirtualSync lock, no waiting.
     110 *
     111 * @retval  VINF_SUCCESS on success.
     112 * @retval  VERR_SEM_BUSY if busy.
     113 *
     114 * @param   pVM         The VM handle.
     115 */
     116int tmVirtualSyncTryLock(PVM pVM)
     117{
     118    VM_ASSERT_EMT(pVM);
     119    int rc = PDMCritSectTryEnter(&pVM->tm.s.VirtualSyncLock);
     120    return rc;
     121}
     122
     123
     124/**
     125 * Release the VirtualSync lock.
     126 *
     127 * @param   pVM         The VM handle.
     128 */
     129void tmVirtualSyncUnlock(PVM pVM)
     130{
     131    PDMCritSectLeave(&pVM->tm.s.VirtualSyncLock);
    89132}
    90133
     
    170213
    171214/**
     215 * Raise the timer force action flag and notify the dedicated timer EMT.
     216 *
     217 * @param   pVM         The VM handle.
     218 */
     219DECLINLINE(void) tmScheduleNotify(PVM pVM)
     220{
     221    PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
     222    if (!VMCPU_FF_ISSET(pVCpuDst, VMCPU_FF_TIMER))
     223    {
     224        Log5(("TMAll(%u): FF: 0 -> 1\n", __LINE__));
     225        VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
     226#ifdef IN_RING3
     227        REMR3NotifyTimerPending(pVM, pVCpuDst);
     228        VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM);
     229#endif
     230        STAM_COUNTER_INC(&pVM->tm.s.StatScheduleSetFF);
     231    }
     232}
     233
     234
     235/**
    172236 * Schedule the queue which was changed.
    173237 */
     
    178242        &&  RT_SUCCESS(tmTryLock(pVM)))
    179243    {
    180         STAM_PROFILE_START(&pVM->tm.s.CTXALLSUFF(StatScheduleOne), a);
    181         PTMTIMERQUEUE pQueue = &pVM->tm.s.CTX_SUFF(paTimerQueues)[pTimer->enmClock];
     244        STAM_PROFILE_START(&pVM->tm.s.CTX_SUFF_Z(StatScheduleOne), a);
    182245        Log3(("tmSchedule: tmTimerQueueSchedule\n"));
    183         tmTimerQueueSchedule(pVM, pQueue);
     246        tmTimerQueueSchedule(pVM, &pVM->tm.s.CTX_SUFF(paTimerQueues)[pTimer->enmClock]);
    184247#ifdef VBOX_STRICT
    185248        tmTimerQueuesSanityChecks(pVM, "tmSchedule");
     
    190253    else
    191254    {
    192         /** @todo FIXME: don't use FF for scheduling! */
    193         PVMCPU pVCpuDst = &pVM->aCpus[pVM->tm.s.idTimerCpu];
    194         if (!VMCPU_FF_ISSET(pVCpuDst, VMCPU_FF_TIMER))  /**@todo only do this when arming the timer. */
    195         {
    196             Log5(("TMAll(%u): FF: 0 -> 1\n", __LINE__));
    197             VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
    198 #ifdef IN_RING3
    199             REMR3NotifyTimerPending(pVM, pVCpuDst);
    200             VMR3NotifyCpuFFU(pVCpuDst->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM);
    201 #endif
    202             STAM_COUNTER_INC(&pVM->tm.s.StatScheduleSetFF);
    203         }
     255        TMTIMERSTATE enmState = pTimer->enmState;
     256        if (TMTIMERSTATE_IS_PENDING_SCHEDULING(enmState))
     257            tmScheduleNotify(pVM);
    204258    }
    205259}
     
    231285 * @param   pQueue  The timer queue the timer belongs to.
    232286 * @param   pTimer  The timer.
     287 *
     288 * @todo    FIXME: Look into potential race with the thread running the queues
     289 *          and stuff.
    233290 */
    234291DECLINLINE(void) tmTimerLink(PTMTIMERQUEUE pQueue, PTMTIMER pTimer)
     
    307364     * Get current time and check the expire times of the two relevant queues.
    308365     */
    309     int             rc     = tmLock(pVM); /** @todo FIXME: Stop playing safe here... */
    310366    const uint64_t  u64Now = TMVirtualGetNoCheck(pVM);
    311367
     
    319375        STAM_COUNTER_INC(&pVM->tm.s.StatPollVirtual);
    320376        LogFlow(("TMTimerPoll: expire1=%RU64 <= now=%RU64\n", u64Expire1, u64Now));
    321 #ifndef IN_RING3
    322         if (RT_SUCCESS(rc))
    323 #endif
    324             tmUnlock(pVM);
    325377        Log5(("TMAll(%u): FF: %d -> 1\n", __LINE__, VMCPU_FF_ISPENDING(pVCpuDst, VMCPU_FF_TIMER)));
    326378        VMCPU_FF_SET(pVCpuDst, VMCPU_FF_TIMER);
     
    336388     * we have to adjust the 'now' but when have to adjust the delta as well.
    337389     */
     390    int            rc         = tmVirtualSyncLock(pVM); /** @todo FIXME: Stop playing safe here... */
    338391    const uint64_t u64Expire2 = pVM->tm.s.CTX_SUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC].u64Expire;
    339392    uint64_t u64VirtualSyncNow;
     
    375428        if (RT_SUCCESS(rc))
    376429#endif
    377             tmUnlock(pVM);
     430            tmVirtualSyncUnlock(pVM);
    378431        LogFlow(("TMTimerPoll: expire2=%RU64 <= now=%RU64\n", u64Expire2, u64Now));
    379432        return pVCpu == pVCpuDst ? 0 : s_u64OtherRet;
     
    389442    if (RT_SUCCESS(rc))
    390443#endif
    391         tmUnlock(pVM);
     444        tmVirtualSyncUnlock(pVM);
    392445    return RT_MIN(i64Delta1, i64Delta2);
    393446}
     
    438491    }
    439492
    440     int rc = tmLock(pVM); /** @todo FIXME: Stop playin safe... */
    441 
    442493    /*
    443494     * Check for TMCLOCK_VIRTUAL expiration.
     
    453504        REMR3NotifyTimerPending(pVM, pVCpuDst);
    454505#endif
    455 #ifndef IN_RING3
    456         if (RT_SUCCESS(rc))
    457 #endif
    458             tmUnlock(pVM);
    459506        LogFlow(("TMTimerPoll: expire1=%RU64 <= now=%RU64\n", u64Expire1, u64Now));
    460507        if (pVCpuDst == pVCpu)
     
    472519     * we have to adjust the 'now' but when have to adjust the delta as well.
    473520     */
     521    int rc = tmVirtualSyncLock(pVM); /** @todo FIXME: Stop playin safe... */
     522
    474523    const uint64_t  u64Expire2 = pVM->tm.s.CTX_SUFF(paTimerQueues)[TMCLOCK_VIRTUAL_SYNC].u64Expire;
    475524    uint64_t        u64VirtualSyncNow;
     
    512561        if (RT_SUCCESS(rc))
    513562#endif
    514             tmUnlock(pVM);
     563            tmVirtualSyncUnlock(pVM);
    515564        LogFlow(("TMTimerPoll: expire2=%RU64 <= now=%RU64\n", u64Expire2, u64Now));
    516565        if (pVCpuDst == pVCpu)
     
    552601    if (RT_SUCCESS(rc))
    553602#endif
    554         tmUnlock(pVM);
     603        tmVirtualSyncUnlock(pVM);
    555604    return u64GipTime;
    556605}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette