VirtualBox

Changeset 37513 in vbox


Ignore:
Timestamp:
Jun 16, 2011 6:12:18 PM (14 years ago)
Author:
vboxsync
Message:

DevRTC: Locking adjustments.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevRTC.cpp

    r37512 r37513  
    211211    uint32_t freq;
    212212
     213    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
     214    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
     215
    213216    period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
    214217    if (   period_code != 0
     
    379382             pThis->cmos_index[bank], u32, pThis->cmos_data[pThis->cmos_index[bank]]));
    380383
    381         switch (pThis->cmos_index[bank])
     384        int const idx = pThis->cmos_index[bank];
     385        switch (idx)
    382386        {
    383387            case RTC_SECONDS_ALARM:
     
    401405
    402406            case RTC_REG_A:
    403                 /* UIP bit is read only */
    404                 pThis->cmos_data[RTC_REG_A] = (u32                        & ~REG_A_UIP)
    405                                             | (pThis->cmos_data[RTC_REG_A] & REG_A_UIP);
    406                 rtc_timer_update(pThis, TMTimerGet(pThis->CTX_SUFF(pPeriodicTimer)));
    407                 break;
    408 
    409407            case RTC_REG_B:
    410                 if (u32 & REG_B_SET)
     408            {
     409                /* We need to acquire the clock lock, because of lock ordering
     410                   issues this means having to release the device lock.  Since
     411                   we're letting IOM do the locking, we must not return without
     412                   holding the device lock.*/
     413                PDMCritSectLeave(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo));
     414                int rc1 = TMTimerLock(pThis->CTX_SUFF(pPeriodicTimer), VINF_SUCCESS /* must get it */);
     415                int rc2 = PDMCritSectEnter(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS /* must get it */);
     416                AssertRCReturn(rc1, rc1);
     417                AssertRCReturnStmt(rc2, TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer)), rc2);
     418
     419                if (idx == RTC_REG_A)
    411420                {
    412                     /* set mode: reset UIP mode */
    413                     pThis->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
    414 #if 0 /* This is probably wrong as it breaks changing the time/date in OS/2. */
    415                     u32 &= ~REG_B_UIE;
    416 #endif
     421                    /* UIP bit is read only */
     422                    pThis->cmos_data[RTC_REG_A] = (u32                        & ~REG_A_UIP)
     423                                                | (pThis->cmos_data[RTC_REG_A] & REG_A_UIP);
    417424                }
    418425                else
    419426                {
    420                     /* if disabling set mode, update the time */
    421                     if (pThis->cmos_data[RTC_REG_B] & REG_B_SET)
    422                         rtc_set_time(pThis);
     427                    if (u32 & REG_B_SET)
     428                    {
     429                        /* set mode: reset UIP mode */
     430                        pThis->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
     431#if 0 /* This is probably wrong as it breaks changing the time/date in OS/2. */
     432                        u32 &= ~REG_B_UIE;
     433#endif
     434                    }
     435                    else
     436                    {
     437                        /* if disabling set mode, update the time */
     438                        if (pThis->cmos_data[RTC_REG_B] & REG_B_SET)
     439                            rtc_set_time(pThis);
     440                    }
     441                    pThis->cmos_data[RTC_REG_B] = u32;
    423442                }
    424                 pThis->cmos_data[RTC_REG_B] = u32;
     443
    425444                rtc_timer_update(pThis, TMTimerGet(pThis->CTX_SUFF(pPeriodicTimer)));
     445
     446                TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer));
     447                /* the caller leaves the other lock. */
    426448                break;
     449            }
    427450
    428451            case RTC_REG_C:
     
    455478{
    456479    RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
     480    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
     481    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
    457482
    458483    rtc_timer_update(pThis, pThis->next_periodic_time);
     
    537562{
    538563    RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
     564    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
     565    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
    539566
    540567    /* if the oscillator is not in normal operation, we do not update */
     
    598625{
    599626    RTCState *pThis = PDMINS_2_DATA(pDevIns, RTCState *);
     627    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
     628    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
    600629
    601630    if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
Note: See TracChangeset for help on using the changeset viewer.

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