VirtualBox

Changeset 20087 in vbox


Ignore:
Timestamp:
May 27, 2009 2:31:18 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
47833
Message:

TM,*: Proper timer callback locking and pvUser for devices.

Location:
trunk
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/iom.h

    r19993 r20087  
    269269
    270270VMMR3DECL(void) IOMR3ReleaseOwnedLocks(PVM pVM);
     271VMMR3DECL(PPDMCRITSECT) IOMR3GetCritSect(PVM pVM);
    271272
    272273/** @} */
  • trunk/include/VBox/pdmcritsect.h

    r20008 r20087  
    5454#endif
    5555} PDMCRITSECT;
    56 /** Pointer to a PDM critical section. */
    57 typedef PDMCRITSECT *PPDMCRITSECT;
    58 /** Pointer to a const PDM critical section. */
    59 typedef const PDMCRITSECT *PCPDMCRITSECT;
    6056
    6157VMMR3DECL(int)      PDMR3CritSectInit(PVM pVM, PPDMCRITSECT pCritSect, const char *pszName);
     
    6965VMMDECL(bool)       PDMCritSectIsInitialized(PCPDMCRITSECT pCritSect);
    7066VMMDECL(uint32_t)   PDMCritSectGetRecursion(PCPDMCRITSECT pCritSect);
     67VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect);
    7168VMMR3DECL(int)      PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal);
    7269VMMR3DECL(int)      PDMR3CritSectDelete(PPDMCRITSECT pCritSect);
  • trunk/include/VBox/pdmdev.h

    r20056 r20087  
    13031303     */
    13041304    DECLR3CALLBACKMEMBER(void,    pfnSendSipi,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t uVector));
    1305    
    1306     /**
    1307      * Sends init IPI to given virtual CPU, should result in reset and 
     1305
     1306    /**
     1307     * Sends init IPI to given virtual CPU, should result in reset and
    13081308     * halting till SIPI.
    13091309     *
     
    19511951     * @param   enmClock            The clock to use on this timer.
    19521952     * @param   pfnCallback         Callback function.
     1953     * @param   pvUser              User argument for the callback.
     1954     * @param   fFlags              Flags, see TMTIMER_FLAGS_*.
    19531955     * @param   pszDesc             Pointer to description string which must stay around
    19541956     *                              until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
    19551957     * @param   ppTimer             Where to store the timer on success.
    19561958     */
    1957     DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer));
     1959    DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
    19581960
    19591961    /**
     
    34633465 * @copydoc PDMDEVHLPR3::pfnTMTimerCreate
    34643466 */
    3465 DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer)
    3466 {
    3467     return pDevIns->pDevHlpR3->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pszDesc, ppTimer);
     3467DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags,
     3468                                       const char *pszDesc, PPTMTIMERR3 ppTimer)
     3469{
     3470    return pDevIns->pDevHlpR3->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
    34683471}
    34693472
  • trunk/include/VBox/tm.h

    r19821 r20087  
    7373
    7474
     75/** @defgroup grp_tm_timer_flags Timer flags.
     76 * @{ */
     77/** Use the default critical section for the class of timers.
     78 * Only devices have one at the moment. */
     79#define TMTIMER_FLAGS_DEFAULT_CRIT_SECT 0
     80/** No critical section needed or a custom one is set using
     81 *  TMR3TimerSetCritSect(). */
     82#define TMTIMER_FLAGS_NO_CRIT_SECT      RT_BIT_32(0)
     83/** @} */
     84
     85
    7586VMMDECL(void)     TMNotifyStartOfExecution(PVMCPU pVCpu);
    7687VMMDECL(void)     TMNotifyEndOfExecution(PVMCPU pVCpu);
     
    132143 * @param   pDevIns         Device instance of the device which registered the timer.
    133144 * @param   pTimer          The timer handle.
    134  */
    135 typedef DECLCALLBACK(void) FNTMTIMERDEV(PPDMDEVINS pDevIns, PTMTIMER pTimer);
     145 * @param   pvUser          User argument specified upon timer creation.
     146 */
     147typedef DECLCALLBACK(void) FNTMTIMERDEV(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
    136148/** Pointer to a device timer callback function. */
    137149typedef FNTMTIMERDEV *PFNTMTIMERDEV;
     
    218230VMMR3DECL(void)   TMR3Reset(PVM pVM);
    219231VMMR3DECL(int)    TMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
    220 VMMR3DECL(int)    TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer);
     232VMMR3DECL(int)    TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer);
    221233VMMR3DECL(int)    TMR3TimerCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer);
    222234VMMR3DECL(int)    TMR3TimerCreateInternal(PVM pVM, TMCLOCK enmClock, PFNTMTIMERINT pfnCallback, void *pvUser, const char *pszDesc, PPTMTIMERR3 ppTimer);
     
    227239VMMR3DECL(int)    TMR3TimerSave(PTMTIMERR3 pTimer, PSSMHANDLE pSSM);
    228240VMMR3DECL(int)    TMR3TimerLoad(PTMTIMERR3 pTimer, PSSMHANDLE pSSM);
     241VMMR3DECL(int)    TMR3TimerSetCritSect(PTMTIMERR3 pTimer, PPDMCRITSECT pCritSect);
    229242VMMR3DECL(void)   TMR3TimerQueuesDo(PVM pVM);
    230243VMMR3DECL(void)   TMR3VirtualSyncFF(PVM pVM, PVMCPU pVCpu);
  • trunk/include/VBox/types.h

    r19405 r20087  
    203203/** Pointer to a pointer to a PDM Service Instance. */
    204204typedef PPDMSRVINS *PPPDMSRVINS;
     205
     206/** Pointer to a PDM critical section. */
     207typedef union PDMCRITSECT *PPDMCRITSECT;
     208/** Pointer to a const PDM critical section. */
     209typedef const union PDMCRITSECT *PCPDMCRITSECT;
    205210
    206211/** R3 pointer to a timer. */
  • trunk/include/VBox/vusb.h

    r15076 r20087  
    779779/**
    780780 * USB Timer Interface.
     781 * @todo r=bird: why is this code still here?
    781782 */
    782783typedef struct VUSBITIMER
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r18645 r20087  
    280280}
    281281#else  /* VBOX */
    282 static DECLCALLBACK(void) sb16Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    283 {
    284     SB16State *s = PDMINS_2_DATA(pDevIns, SB16State *);
     282static DECLCALLBACK(void) sb16Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvThis)
     283{
     284    SB16State *s = (SB16State *)pvThis;
    285285    s->can_write = 1;
    286286    PDMDevHlpISASetIrq(s->pDevIns, s->irq, 1);
     
    17951795     * Create timer, register & attach stuff.
    17961796     */
    1797     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16Timer, "SB16 timer", &s->pTimer);
     1797    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16Timer, s,
     1798                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 timer", &s->pTimer);
    17981799    if (RT_FAILURE(rc))
    17991800        AssertMsgFailedReturn(("pfnTMTimerCreate -> %Rrc\n", rc), rc);
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r19844 r20087  
    50715071
    50725072
    5073 static DECLCALLBACK(void) vgaTimerRefresh(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    5074 {
    5075     PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
     5073static DECLCALLBACK(void) vgaTimerRefresh(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     5074{
     5075    PVGASTATE pThis = (PVGASTATE)pvUser;
    50765076
    50775077    if (pThis->pDrv)
     
    57835783     * Create the refresh timer.
    57845784     */
    5785     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_REAL, vgaTimerRefresh, "VGA Refresh Timer", &pThis->RefreshTimer);
     5785    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_REAL, vgaTimerRefresh,
     5786                                pThis, TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo This needs to be fixed! We cannot take the I/O lock at this point! */
     5787                                "VGA Refresh Timer", &pThis->RefreshTimer);
    57865788    if (RT_FAILURE(rc))
    57875789        return rc;
  • trunk/src/VBox/Devices/Network/DevE1000.cpp

    r19840 r20087  
    24662466 * @param   pDevIns     Pointer to device instance structure.
    24672467 * @param   pTimer      Pointer to the timer.
    2468  * @thread  EMT
    2469  */
    2470 static DECLCALLBACK(void) e1kTxIntDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    2471 {
    2472     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
     2468 * @param   pvUser      NULL.
     2469 * @thread  EMT
     2470 */
     2471static DECLCALLBACK(void) e1kTxIntDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     2472{
     2473    E1KSTATE *pState = (E1KSTATE *)pvUser;
    24732474
    24742475    if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
     
    24912492 * @param   pDevIns     Pointer to device instance structure.
    24922493 * @param   pTimer      Pointer to the timer.
    2493  * @thread  EMT
    2494  */
    2495 static DECLCALLBACK(void) e1kTxAbsDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    2496 {
    2497     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
     2494 * @param   pvUser      NULL.
     2495 * @thread  EMT
     2496 */
     2497static DECLCALLBACK(void) e1kTxAbsDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     2498{
     2499    E1KSTATE *pState = (E1KSTATE *)pvUser;
    24982500
    24992501    if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
     
    25162518 * @param   pDevIns     Pointer to device instance structure.
    25172519 * @param   pTimer      Pointer to the timer.
    2518  * @thread  EMT
    2519  */
    2520 static DECLCALLBACK(void) e1kRxIntDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    2521 {
    2522     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
     2520 * @param   pvUser      NULL.
     2521 * @thread  EMT
     2522 */
     2523static DECLCALLBACK(void) e1kRxIntDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     2524{
     2525    E1KSTATE *pState = (E1KSTATE *)pvUser;
    25232526
    25242527    if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
     
    25392542 * @param   pDevIns     Pointer to device instance structure.
    25402543 * @param   pTimer      Pointer to the timer.
    2541  * @thread  EMT
    2542  */
    2543 static DECLCALLBACK(void) e1kRxAbsDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    2544 {
    2545     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
     2544 * @param   pvUser      NULL.
     2545 * @thread  EMT
     2546 */
     2547static DECLCALLBACK(void) e1kRxAbsDelayTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     2548{
     2549    E1KSTATE *pState = (E1KSTATE *)pvUser;
    25462550
    25472551    if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
     
    25612565 * @param   pDevIns     Pointer to device instance structure.
    25622566 * @param   pTimer      Pointer to the timer.
    2563  * @thread  EMT
    2564  */
    2565 static DECLCALLBACK(void) e1kLateIntTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    2566 {
    2567     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
     2567 * @param   pvUser      NULL.
     2568 * @thread  EMT
     2569 */
     2570static DECLCALLBACK(void) e1kLateIntTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     2571{
     2572    E1KSTATE *pState = (E1KSTATE *)pvUser;
    25682573
    25692574    STAM_PROFILE_ADV_START(&pState->StatLateIntTimer, a);
     
    25872592 * @param   pDevIns     Pointer to device instance structure.
    25882593 * @param   pTimer      Pointer to the timer.
    2589  * @thread  EMT
    2590  */
    2591 static DECLCALLBACK(void) e1kLinkUpTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    2592 {
    2593     E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE *);
     2594 * @param   pvUser      NULL.
     2595 * @thread  EMT
     2596 */
     2597static DECLCALLBACK(void) e1kLinkUpTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     2598{
     2599    E1KSTATE *pState = (E1KSTATE *)pvUser;
    25942600
    25952601    if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
     
    48124818#ifdef E1K_USE_TX_TIMERS
    48134819    /* Create Transmit Interrupt Delay Timer */
    4814     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kTxIntDelayTimer,
     4820    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kTxIntDelayTimer, pState,
     4821                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    48154822                                "E1000 Transmit Interrupt Delay Timer", &pState->pTIDTimerR3);
    48164823    if (RT_FAILURE(rc))
     
    48214828# ifndef E1K_NO_TAD
    48224829    /* Create Transmit Absolute Delay Timer */
    4823     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kTxAbsDelayTimer,
     4830    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kTxAbsDelayTimer, pState,
     4831                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    48244832                                "E1000 Transmit Absolute Delay Timer", &pState->pTADTimerR3);
    48254833    if (RT_FAILURE(rc))
     
    48324840#ifdef E1K_USE_RX_TIMERS
    48334841    /* Create Receive Interrupt Delay Timer */
    4834     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kRxIntDelayTimer,
     4842    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kRxIntDelayTimer, pState,
     4843                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    48354844                                "E1000 Receive Interrupt Delay Timer", &pState->pRIDTimerR3);
    48364845    if (RT_FAILURE(rc))
     
    48404849
    48414850    /* Create Receive Absolute Delay Timer */
    4842     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kRxAbsDelayTimer,
     4851    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kRxAbsDelayTimer, pState,
     4852                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    48434853                                "E1000 Receive Absolute Delay Timer", &pState->pRADTimerR3);
    48444854    if (RT_FAILURE(rc))
     
    48494859
    48504860    /* Create Late Interrupt Timer */
    4851     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kLateIntTimer,
     4861    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kLateIntTimer, pState,
     4862                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    48524863                                "E1000 Late Interrupt Timer", &pState->pIntTimerR3);
    48534864    if (RT_FAILURE(rc))
     
    48574868
    48584869    /* Create Link Up Timer */
    4859     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kLinkUpTimer,
     4870    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, e1kLinkUpTimer, pState,
     4871                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
    48604872                                "E1000 Link Up Timer", &pState->pLUTimer);
    48614873    if (RT_FAILURE(rc))
  • trunk/src/VBox/Devices/Network/DevINIP.cpp

    r17802 r20087  
    146146 * @param   pTimer      Pointer to timer.
    147147 */
    148 static DECLCALLBACK(void) devINIPARPTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    149 {
    150     PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
     148static DECLCALLBACK(void) devINIPARPTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     149{
     150    PDEVINTNETIP pThis = (PDEVINTNETIP)pvUser;
    151151    LogFlow(("%s: pDevIns=%p pTimer=%p\n", __FUNCTION__, pDevIns, pTimer));
    152152    lwip_etharp_tmr();
     
    161161 * @param   pTimer      Pointer to timer.
    162162 */
    163 static DECLCALLBACK(void) devINIPTCPFastTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    164 {
    165     PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
     163static DECLCALLBACK(void) devINIPTCPFastTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     164{
     165    PDEVINTNETIP pThis = (PDEVINTNETIP)pvUser;
    166166    LogFlow(("%s: pDevIns=%p pTimer=%p\n", __FUNCTION__, pDevIns, pTimer));
    167167    lwip_tcp_fasttmr();
     
    176176 * @param   pTimer      Pointer to timer.
    177177 */
    178 static DECLCALLBACK(void) devINIPTCPSlowTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    179 {
    180     PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
     178static DECLCALLBACK(void) devINIPTCPSlowTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     179{
     180    PDEVINTNETIP pThis = (PDEVINTNETIP)pvUser;
    181181    LogFlow(("%s: pDevIns=%p pTimer=%p\n", __FUNCTION__, pDevIns, pTimer));
    182182    lwip_tcp_slowtmr();
     
    590590    lwip_pbuf_init();
    591591    lwip_netif_init();
    592     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPARPTimer, "lwIP ARP", &pThis->ARPTimer);
    593     if (RT_FAILURE(rc))
    594         goto out;
    595     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPTCPFastTimer, "lwIP fast TCP", &pThis->TCPFastTimer);
     592    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPARPTimer, pThis,
     593                                TMTIMER_FLAGS_NO_CRIT_SECT, "lwIP ARP", &pThis->ARPTimer);
     594    if (RT_FAILURE(rc))
     595        goto out;
     596    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPTCPFastTimer, pThis,
     597                                TMTIMER_FLAGS_NO_CRIT_SECT, "lwIP fast TCP", &pThis->TCPFastTimer);
    596598    if (RT_FAILURE(rc))
    597599        goto out;
    598600    TMTimerSetMillies(pThis->TCPFastTimer, TCP_FAST_INTERVAL);
    599     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPTCPSlowTimer, "lwIP slow TCP", &pThis->TCPSlowTimer);
     601    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, devINIPTCPSlowTimer, pThis,
     602                                TMTIMER_FLAGS_NO_CRIT_SECT, "lwIP slow TCP", &pThis->TCPSlowTimer);
    600603    if (RT_FAILURE(rc))
    601604        goto out;
  • trunk/src/VBox/Devices/Network/DevPCNet.cpp

    r19113 r20087  
    38023802 * @thread  EMT
    38033803 */
    3804 static DECLCALLBACK(void) pcnetTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    3805 {
    3806     PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
    3807     int         rc;
    3808 
     3804static DECLCALLBACK(void) pcnetTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     3805{
     3806    PCNetState *pThis = (PCNetState *)pvUser;
    38093807    STAM_PROFILE_ADV_START(&pThis->StatTimer, a);
    3810     rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
    3811     AssertReleaseRC(rc);
    3812 
    38133808    pcnetPollTimer(pThis);
    3814 
    3815     PDMCritSectLeave(&pThis->CritSect);
    38163809    STAM_PROFILE_ADV_STOP(&pThis->StatTimer, a);
    38173810}
     
    38253818 * @thread  EMT
    38263819 */
    3827 static DECLCALLBACK(void) pcnetTimerSoftInt(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    3828 {
    3829     PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
    3830 
     3820static DECLCALLBACK(void) pcnetTimerSoftInt(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     3821{
     3822    PCNetState *pThis = (PCNetState *)pvUser;
     3823
     3824/** @todo why aren't we taking any critsect here?!? */
    38313825    pThis->aCSR[7] |= 0x0800; /* STINT */
    38323826    pcnetUpdateIrq(pThis);
     
    38453839 * @param   pTimer          The timer handle.
    38463840 */
    3847 static DECLCALLBACK(void) pcnetTimerRestore(PPDMDEVINS pDevIns, PTMTIMER pTimer)
     3841static DECLCALLBACK(void) pcnetTimerRestore(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    38483842{
    38493843    PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
    3850     int         rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
    3851     AssertReleaseRC(rc);
    3852 
    3853     rc = VERR_GENERAL_FAILURE;
     3844
     3845    int rc = VERR_GENERAL_FAILURE;
    38543846    if (pThis->cLinkDownReported <= PCNET_MAX_LINKDOWN_REPORTED)
    38553847        rc = TMTimerSetMillies(pThis->pTimerRestore, 1500);
     
    38703862        Log(("#%d pcnetTimerRestore: cLinkDownReported=%d, wait another 1500ms...\n",
    38713863             pDevIns->iInstance, pThis->cLinkDownReported));
    3872 
    3873     PDMCritSectLeave(&pThis->CritSect);
    38743864}
    38753865
     
    46784668        pThis->cLinkDownReported = 0x10000;
    46794669        TMTimerStop(pThis->pTimerRestore);
    4680         pcnetTimerRestore(pDevIns, pThis->pTimerRestore);
     4670        pcnetTimerRestore(pDevIns, pThis->pTimerRestore, pThis);
    46814671    }
    46824672    if (pThis->pSharedMMIOR3)
     
    49194909    }
    49204910
     4911    /*
     4912     * Initialize critical section.
     4913     * This must be done before register the critsect with the timer code, and also before
     4914     * attaching drivers or anything else that may call us back.
     4915     */
     4916    char szName[24];
     4917    RTStrPrintf(szName, sizeof(szName), "PCNet#%d", iInstance);
     4918    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, szName);
     4919    if (RT_FAILURE(rc))
     4920        return rc;
     4921
     4922    rc = RTSemEventCreate(&pThis->hEventOutOfRxSpace);
     4923    AssertRC(rc);
     4924
    49214925#ifdef PCNET_NO_POLLING
    49224926    /*
     
    49284932    AssertLogRelMsgRCReturn(rc, ("PDMR3LdrGetSymbolRCLazy(EMInterpretInstruction) -> %Rrc\n", rc), rc);
    49294933#else
    4930     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimer,
    4931                                 "PCNet Poll Timer", &pThis->pTimerPollR3);
     4934    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimer, pThis,
     4935                                TMTIMER_FLAGS_NO_CRIT_SECT, "PCNet Poll Timer", &pThis->pTimerPollR3);
    49324936    if (RT_FAILURE(rc))
    49334937        return rc;
    49344938    pThis->pTimerPollR0 = TMTimerR0Ptr(pThis->pTimerPollR3);
    49354939    pThis->pTimerPollRC = TMTimerRCPtr(pThis->pTimerPollR3);
     4940    TMR3TimerSetCritSect(pThis->pTimerPollR3, &pThis->CritSect);
    49364941#endif
    49374942    if (pThis->fAm79C973)
    49384943    {
    49394944        /* Software Interrupt timer */
    4940         rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerSoftInt,
    4941                                     "PCNet SoftInt Timer", &pThis->pTimerSoftIntR3);
     4945        rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerSoftInt, pThis, /** @todo r=bird: the locking here looks bogus now with SMP... */
     4946                                    TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PCNet SoftInt Timer", &pThis->pTimerSoftIntR3);
    49424947        if (RT_FAILURE(rc))
    49434948            return rc;
     
    49454950        pThis->pTimerSoftIntRC = TMTimerRCPtr(pThis->pTimerSoftIntR3);
    49464951    }
    4947     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerRestore,
    4948                                 "PCNet Restore Timer", &pThis->pTimerRestore);
     4952    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerRestore, pThis,
     4953                                TMTIMER_FLAGS_NO_CRIT_SECT, "PCNet Restore Timer", &pThis->pTimerRestore);
    49494954    if (RT_FAILURE(rc))
    49504955        return rc;
     4956    TMR3TimerSetCritSect(pThis->pTimerRestore, &pThis->CritSect);
    49514957
    49524958    rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance,
     
    49564962    if (RT_FAILURE(rc))
    49574963        return rc;
    4958 
    4959     /*
    4960      * Initialize critical section.
    4961      * This must of course be done before attaching drivers or anything else which can call us back.
    4962      */
    4963     char szName[24];
    4964     RTStrPrintf(szName, sizeof(szName), "PCNet#%d", iInstance);
    4965     rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, szName);
    4966     if (RT_FAILURE(rc))
    4967         return rc;
    4968 
    4969     rc = RTSemEventCreate(&pThis->hEventOutOfRxSpace);
    4970     AssertRC(rc);
    49714964
    49724965    /*
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r19646 r20087  
    10681068}
    10691069
    1070 static DECLCALLBACK(void) acpiTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    1071 {
    1072     ACPIState *s = PDMINS_2_DATA(pDevIns, ACPIState *);
     1070static DECLCALLBACK(void) acpiTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     1071{
     1072    ACPIState *s = (ACPIState *)pvUser;
    10731073
    10741074    Log(("acpi: pm timer sts %#x (%d), en %#x (%d)\n",
     
    13201320                            : 0;
    13211321                    break;
    1322                
     1322
    13231323                case SYSTEM_INFO_INDEX_CPU0_STATUS:
    13241324                case SYSTEM_INFO_INDEX_CPU1_STATUS:
     
    19331933    }
    19341934
    1935     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, acpiTimer, "ACPI Timer", &s->tsR3);
     1935    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, acpiTimer, dev,
     1936                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "ACPI Timer", &s->tsR3);
    19361937    if (RT_FAILURE(rc))
    19371938    {
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r20056 r20087  
    12961296
    12971297#ifdef IN_RING3
    1298 #ifndef VBOX
     1298# ifndef VBOX
    12991299static void apic_timer(void *opaque)
    13001300{
    13011301    APICState *s = opaque;
    1302 #else /* VBOX */
    1303 static DECLCALLBACK(void) apicTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
     1302# else /* VBOX */
     1303static DECLCALLBACK(void) apicTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    13041304{
    13051305    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    1306     APICState *s = getLapic(dev);
    1307     if (s->pTimerR3 != pTimer)
    1308     {
    1309         for (uint32_t iCpu = 0; iCpu < dev->cCpus; iCpu++)
    1310         {
    1311             s = getLapicById(dev, iCpu);
    1312             if (s->pTimerR3 == pTimer)
    1313                 break;
    1314         }
    1315         Assert(s->pTimerR3 == pTimer);
    1316     }
     1306    APICState *s = (APICState *)pvUser;
     1307    Assert(s->pTimerR3 == pTimer);
    13171308
    13181309    APIC_LOCK_VOID(dev, VERR_INTERNAL_ERROR);
    1319 #endif /* VBOX */
     1310# endif /* VBOX */
    13201311
    13211312    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
     
    13251316    apic_timer_update(dev, s, s->next_time);
    13261317
    1327 #ifdef VBOX
     1318# ifdef VBOX
    13281319    APIC_UNLOCK(dev);
    1329 #endif
     1320# endif
    13301321}
    13311322#endif /* IN_RING3 */
     
    24072398    for (i = 0, apic = LAPIC_BASE(pThis); i < cCpus; i++)
    24082399    {
    2409         rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicTimer,
    2410                                     "APIC Timer", &apic->pTimerR3);
     2400        rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicTimer, apic,
     2401                                    TMTIMER_FLAGS_NO_CRIT_SECT, "APIC Timer", &apic->pTimerR3);
    24112402        if (RT_FAILURE(rc))
    24122403            return rc;
    24132404        apic->pTimerR0 = TMTimerR0Ptr(apic->pTimerR3);
    24142405        apic->pTimerRC = TMTimerRCPtr(apic->pTimerR3);
     2406        /// @todo TMTimerSetCritSect(apic->pTimerR3, pThis->pApicHlpR3->pfnGetCritSect(..));
    24152407        apic++;
    24162408    }
  • trunk/src/VBox/Devices/PC/DevPit-i8254.cpp

    r20049 r20087  
    809809 * @param   pDevIns         Device instance of the device which registered the timer.
    810810 * @param   pTimer          The timer handle.
    811  */
    812 static DECLCALLBACK(void) pitTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    813 {
    814     PITState *pThis = PDMINS_2_DATA(pDevIns, PITState *);
    815     PITChannelState *s = &pThis->channels[0];
     811 * @param   pvUser          Pointer to the PIT channel state.
     812 */
     813static DECLCALLBACK(void) pitTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     814{
     815    PITChannelState *s = (PITChannelState *)pvUser;
    816816    STAM_PROFILE_ADV_START(&s->CTX_SUFF(pPit)->StatPITHandler, a);
    817817    Log(("pitTimer\n"));
     
    994994     * Create timer, register I/O Ports and save state.
    995995     */
    996     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, pitTimer, "i8254 Programmable Interval Timer",
     996    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, pitTimer, &pThis->channels[0],
     997                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "i8254 Programmable Interval Timer",
    997998                                &pThis->channels[0].pTimerR3);
    998999    if (RT_FAILURE(rc))
  • trunk/src/VBox/Devices/PC/DevRTC.cpp

    r19706 r20087  
    7373PDMBOTHCBDECL(int) rtcIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
    7474PDMBOTHCBDECL(int) rtcIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
    75 PDMBOTHCBDECL(void) rtcTimerPeriodic(PPDMDEVINS pDevIns, PTMTIMER pTimer);
    76 PDMBOTHCBDECL(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer);
    77 PDMBOTHCBDECL(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer);
     75PDMBOTHCBDECL(void) rtcTimerPeriodic(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
     76PDMBOTHCBDECL(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
     77PDMBOTHCBDECL(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
    7878__END_DECLS
    7979#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
     
    553553 * @param   pDevIns         Device instance of the device which registered the timer.
    554554 * @param   pTimer          The timer handle.
    555  */
    556 PDMBOTHCBDECL(void) rtcTimerPeriodic(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    557 {
    558     rtc_periodic_timer(PDMINS_2_DATA(pDevIns, RTCState *));
     555 * @param   pvUser          Pointer to the RTC state.
     556 */
     557PDMBOTHCBDECL(void) rtcTimerPeriodic(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     558{
     559    rtc_periodic_timer((RTCState *)pvUser);
    559560}
    560561
     
    565566 * @param   pDevIns         Device instance of the device which registered the timer.
    566567 * @param   pTimer          The timer handle.
    567  */
    568 PDMBOTHCBDECL(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    569 {
    570     rtc_update_second(PDMINS_2_DATA(pDevIns, RTCState *));
     568 * @param   pvUser          Pointer to the RTC state.
     569 */
     570PDMBOTHCBDECL(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     571{
     572    rtc_update_second((RTCState *)pvUser);
    571573}
    572574
     
    577579 * @param   pDevIns         Device instance of the device which registered the timer.
    578580 * @param   pTimer          The timer handle.
    579  */
    580 PDMBOTHCBDECL(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    581 {
    582     rtc_update_second2(PDMINS_2_DATA(pDevIns, RTCState *));
     581 * @param   pvUser          Pointer to the RTC state.
     582 */
     583PDMBOTHCBDECL(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     584{
     585    rtc_update_second2((RTCState *)pvUser);
    583586}
    584587
     
    869872     * Create timers, arm them, register I/O Ports and save state.
    870873     */
    871     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerPeriodic, "MC146818 RTC/CMOS - Periodic", &pThis->pPeriodicTimerR3);
     874    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerPeriodic, pThis,
     875                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Periodic",
     876                                &pThis->pPeriodicTimerR3);
    872877    if (RT_FAILURE(rc))
    873878        return rc;
     
    875880    pThis->pPeriodicTimerRC = TMTimerRCPtr(pThis->pPeriodicTimerR3);
    876881
    877     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond,   "MC146818 RTC/CMOS - Second", &pThis->pSecondTimerR3);
     882    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond, pThis,
     883                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Second",
     884                                &pThis->pSecondTimerR3);
    878885    if (RT_FAILURE(rc))
    879886        return rc;
     
    881888    pThis->pSecondTimerRC = TMTimerRCPtr(pThis->pSecondTimerR3);
    882889
    883     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond2,  "MC146818 RTC/CMOS - Second2", &pThis->pSecondTimer2R3);
     890    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond2, pThis,
     891                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Second2",
     892                                &pThis->pSecondTimer2R3);
    884893    if (RT_FAILURE(rc))
    885894        return rc;
  • trunk/src/VBox/Devices/Storage/fdc.c

    r13080 r20087  
    23432343
    23442344#ifdef VBOX
    2345 static DECLCALLBACK(void) fdc_timer (PPDMDEVINS pDevIns, PTMTIMER pTimer)
    2346 {
    2347     fdctrl_t *fdctrl = PDMINS_2_DATA (pDevIns, fdctrl_t *);
     2345static DECLCALLBACK(void) fdc_timer (PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     2346{
     2347    fdctrl_t *fdctrl = (fdctrl_t *)pvUser;
    23482348    fdctrl_result_timer (fdctrl);
    23492349}
     
    28492849     * Create the FDC timer.
    28502850     */
    2851     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, fdc_timer, "FDC Timer", &fdctrl->result_timer);
     2851    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, fdc_timer, fdctrl,
     2852                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "FDC Timer", &fdctrl->result_timer);
    28522853    if (RT_FAILURE (rc))
    28532854        return rc;
  • trunk/src/VBox/VMM/IOM.cpp

    r19793 r20087  
    16541654    while (PDMCritSectIsOwner(&pVM->iom.s.EmtLock))
    16551655        PDMCritSectLeave(&pVM->iom.s.EmtLock);
     1656}
     1657
     1658
     1659/**
     1660 * For TM only!
     1661 *
     1662 * @returns Pointer to the critical section.
     1663 * @param   pVM                 The VM handle.
     1664 */
     1665VMMR3DECL(PPDMCRITSECT) IOMR3GetCritSect(PVM pVM)
     1666{
     1667    return &pVM->iom.s.EmtLock;
    16561668}
    16571669
  • trunk/src/VBox/VMM/PDMCritSect.cpp

    r20008 r20087  
    351351
    352352/**
     353 * Gets the name of the critical section.
     354 *
     355 *
     356 * @returns Pointer to the critical section name (read only) on success,
     357 *          NULL on failure (invalid critical section).
     358 * @param   pCritSect           The critical section.
     359 */
     360VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect)
     361{
     362    AssertPtrReturn(pCritSect, NULL);
     363    AssertReturn(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC, NULL);
     364    return pCritSect->s.pszName;
     365}
     366
     367
     368/**
    353369 * Schedule a event semaphore for signalling upon critsect exit.
    354370 *
  • trunk/src/VBox/VMM/PDMDevHlp.cpp

    r19400 r20087  
    381381
    382382/** @copydoc PDMDEVHLPR3::pfnTMTimerCreate */
    383 static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer)
     383static DECLCALLBACK(int) pdmR3DevHlp_TMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
    384384{
    385385    PDMDEV_ASSERT_DEVINS(pDevIns);
    386386    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    387     LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pszDesc=%p:{%s} ppTimer=%p\n",
    388              pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, enmClock, pfnCallback, pszDesc, pszDesc, ppTimer));
    389 
    390     int rc = TMR3TimerCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, enmClock, pfnCallback, pszDesc, ppTimer);
     387    LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} ppTimer=%p\n",
     388             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, ppTimer));
     389
     390
     391    int rc = TMR3TimerCreateDevice(pDevIns->Internal.s.pVMR3, pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
    391392
    392393    LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
  • trunk/src/VBox/VMM/TM.cpp

    r20050 r20087  
    12061206    pTimer->offNext         = 0;
    12071207    pTimer->offPrev         = 0;
     1208    pTimer->pvUser          = NULL;
     1209    pTimer->pCritSect       = NULL;
    12081210    pTimer->pszDesc         = pszDesc;
    12091211
     
    12331235 * @param   enmClock        The clock to use on this timer.
    12341236 * @param   pfnCallback     Callback function.
     1237 * @param   pvUser          The user argument to the callback.
     1238 * @param   fFlags          Timer creation flags, see grp_tm_timer_flags.
    12351239 * @param   pszDesc         Pointer to description string which must stay around
    12361240 *                          until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
    12371241 * @param   ppTimer         Where to store the timer on success.
    12381242 */
    1239 VMMR3DECL(int) TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer)
    1240 {
     1243VMMR3DECL(int) TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
     1244{
     1245    AssertReturn(!(fFlags & ~(TMTIMER_FLAGS_NO_CRIT_SECT)), VERR_INVALID_PARAMETER);
     1246
    12411247    /*
    12421248     * Allocate and init stuff.
     
    12481254        (*ppTimer)->u.Dev.pfnTimer  = pfnCallback;
    12491255        (*ppTimer)->u.Dev.pDevIns   = pDevIns;
     1256        (*ppTimer)->pvUser          = pvUser;
     1257        if (fFlags & TMTIMER_FLAGS_DEFAULT_CRIT_SECT)
     1258            (*ppTimer)->pCritSect   = IOMR3GetCritSect(pVM);
    12501259        Log(("TM: Created device timer %p clock %d callback %p '%s'\n", (*ppTimer), enmClock, pfnCallback, pszDesc));
    12511260    }
     
    13081317        pTimer->enmType             = TMTIMERTYPE_INTERNAL;
    13091318        pTimer->u.Internal.pfnTimer = pfnCallback;
    1310         pTimer->u.Internal.pvUser   = pvUser;
     1319        pTimer->pvUser              = pvUser;
    13111320        *ppTimer = pTimer;
    13121321        Log(("TM: Created internal timer %p clock %d callback %p '%s'\n", pTimer, enmClock, pfnCallback, pszDesc));
     
    13391348        pTimer->enmType             = TMTIMERTYPE_EXTERNAL;
    13401349        pTimer->u.External.pfnTimer = pfnCallback;
    1341         pTimer->u.External.pvUser   = pvUser;
     1350        pTimer->pvUser              = pvUser;
    13421351        Log(("TM: Created external timer %p clock %d callback %p '%s'\n", pTimer, enmClock, pfnCallback, pszDesc));
    13431352        return pTimer;
     
    17991808    while (pNext && pNext->u64Expire <= u64Now)
    18001809    {
    1801         PTMTIMER pTimer = pNext;
     1810        PTMTIMER        pTimer    = pNext;
    18021811        pNext = TMTIMER_GET_NEXT(pTimer);
     1812        PPDMCRITSECT    pCritSect = pTimer->pCritSect;
     1813        if (pCritSect)
     1814            PDMCritSectEnter(pCritSect, VERR_INTERNAL_ERROR);
    18031815        Log2(("tmR3TimerQueueRun: %p:{.enmState=%s, .enmClock=%d, .enmType=%d, u64Expire=%llx (now=%llx) .pszDesc=%s}\n",
    18041816              pTimer, tmTimerState(pTimer->enmState), pTimer->enmClock, pTimer->enmType, pTimer->u64Expire, u64Now, pTimer->pszDesc));
     
    18251837            /* fire */
    18261838            TM_SET_STATE(pTimer, TMTIMERSTATE_EXPIRED_DELIVER);
    1827 //            tmUnlock(pVM);
    18281839            switch (pTimer->enmType)
    18291840            {
    1830                 case TMTIMERTYPE_DEV:
    1831 //                    iomLock(pVM);
    1832                     pTimer->u.Dev.pfnTimer(pTimer->u.Dev.pDevIns, pTimer);
    1833 //                    iomUnlock(pVM);
    1834                     break;
    1835 
    1836                 case TMTIMERTYPE_DRV:       pTimer->u.Drv.pfnTimer(pTimer->u.Drv.pDrvIns, pTimer); break;
    1837                 case TMTIMERTYPE_INTERNAL:  pTimer->u.Internal.pfnTimer(pVM, pTimer, pTimer->u.Internal.pvUser); break;
    1838                 case TMTIMERTYPE_EXTERNAL:  pTimer->u.External.pfnTimer(pTimer->u.External.pvUser); break;
     1841                case TMTIMERTYPE_DEV:       pTimer->u.Dev.pfnTimer(pTimer->u.Dev.pDevIns, pTimer, pTimer->pvUser); break;
     1842                case TMTIMERTYPE_DRV:       pTimer->u.Drv.pfnTimer(pTimer->u.Drv.pDrvIns, pTimer /*, pTimer->pvUser*/); break;
     1843                case TMTIMERTYPE_INTERNAL:  pTimer->u.Internal.pfnTimer(pVM, pTimer, pTimer->pvUser); break;
     1844                case TMTIMERTYPE_EXTERNAL:  pTimer->u.External.pfnTimer(pTimer->pvUser); break;
    18391845                default:
    18401846                    AssertMsgFailed(("Invalid timer type %d (%s)\n", pTimer->enmType, pTimer->pszDesc));
    18411847                    break;
    18421848            }
    1843 //            tmLock(pVM);
    18441849
    18451850            /* change the state if it wasn't changed already in the handler. */
     
    18471852            Log2(("tmR3TimerQueueRun: new state %s\n", tmTimerState(pTimer->enmState)));
    18481853        }
     1854        if (pCritSect)
     1855            PDMCritSectLeave(pCritSect);
    18491856    } /* run loop */
    18501857}
     
    20022009            switch (pTimer->enmType)
    20032010            {
    2004                 case TMTIMERTYPE_DEV:       pTimer->u.Dev.pfnTimer(pTimer->u.Dev.pDevIns, pTimer); break;
    2005                 case TMTIMERTYPE_DRV:       pTimer->u.Drv.pfnTimer(pTimer->u.Drv.pDrvIns, pTimer); break;
    2006                 case TMTIMERTYPE_INTERNAL:  pTimer->u.Internal.pfnTimer(pVM, pTimer, pTimer->u.Internal.pvUser); break;
    2007                 case TMTIMERTYPE_EXTERNAL:  pTimer->u.External.pfnTimer(pTimer->u.External.pvUser); break;
     2011                case TMTIMERTYPE_DEV:       pTimer->u.Dev.pfnTimer(pTimer->u.Dev.pDevIns, pTimer, pTimer->pvUser); break;
     2012                case TMTIMERTYPE_DRV:       pTimer->u.Drv.pfnTimer(pTimer->u.Drv.pDrvIns, pTimer /*, pTimer->pvUser*/); break;
     2013                case TMTIMERTYPE_INTERNAL:  pTimer->u.Internal.pfnTimer(pVM, pTimer, pTimer->pvUser); break;
     2014                case TMTIMERTYPE_EXTERNAL:  pTimer->u.External.pfnTimer(pTimer->pvUser); break;
    20082015                default:
    20092016                    AssertMsgFailed(("Invalid timer type %d (%s)\n", pTimer->enmType, pTimer->pszDesc));
     
    23112318
    23122319/**
     2320 * Associates a critical section with a timer.
     2321 *
     2322 * The critical section will be entered prior to doing the timer call back, thus
     2323 * avoiding potential races between the timer thread and other threads trying to
     2324 * stop or adjust the timer expiration while it's being delivered. The timer
     2325 * thread will leave the critical section when the timer callback returns.
     2326 *
     2327 * In strict builds, ownership of the critical section will be asserted by
     2328 * TMTimerSet and TMTimerStop.
     2329 *
     2330 * @retval  VINF_SUCCESS on success.
     2331 * @retval  VERR_INVALID_HANDLE if the timer handle is NULL or invalid
     2332 *          (asserted).
     2333 * @retval  VERR_INVALID_PARAMETER if pCritSect is NULL or has an invalid magic
     2334 *          (asserted).
     2335 * @retval  VERR_ALREADY_EXISTS if a critical section was already associated
     2336 *          with the timer (asserted).
     2337 * @retval  VERR_INVALID_STATE if the timer isn't stopped.
     2338 *
     2339 * @param   pTimer          The timer handle.
     2340 * @param   pCritSect       The critical section. The caller must make sure this
     2341 *                          is around for the life time of the timer.
     2342 *
     2343 * @thread  Any, but the caller is responsible for making sure the timer is not
     2344 *          active.
     2345 */
     2346VMMR3DECL(int) TMR3TimerSetCritSect(PTMTIMERR3 pTimer, PPDMCRITSECT pCritSect)
     2347{
     2348    AssertPtrReturn(pTimer, VERR_INVALID_HANDLE);
     2349    AssertPtrReturn(pCritSect, VERR_INVALID_PARAMETER);
     2350    const char *pszName = PDMR3CritSectName(pCritSect); /* exploited for validation */
     2351    AssertReturn(pszName, VERR_INVALID_PARAMETER);
     2352    AssertReturn(!pTimer->pCritSect, VERR_ALREADY_EXISTS);
     2353    AssertReturn(pTimer->enmState == TMTIMERSTATE_STOPPED, VERR_INVALID_STATE);
     2354    LogFlow(("pTimer=%p (%s) pCritSect=%p (%s)\n", pTimer, pTimer->pszDesc, pCritSect, pszName));
     2355
     2356    pTimer->pCritSect = pCritSect;
     2357    return VINF_SUCCESS;
     2358}
     2359
     2360
     2361/**
    23132362 * Get the real world UTC time adjusted for VM lag.
    23142363 *
  • trunk/src/VBox/VMM/TMInternal.h

    r20050 r20087  
    153153            /** Callback. */
    154154            R3PTRTYPE(PFNTMTIMERINT)    pfnTimer;
    155             /** User argument. */
    156             RTR3PTR                     pvUser;
    157155        } Internal;
    158156
     
    162160            /** Callback. */
    163161            R3PTRTYPE(PFNTMTIMEREXT)    pfnTimer;
    164             /** User data. */
    165             RTR3PTR                     pvUser;
    166162        } External;
    167163    } u;
     
    176172    /** Timer relative offset to the previous timer in the chain. */
    177173    int32_t                 offPrev;
     174
     175    /** User argument. */
     176    RTR3PTR                 pvUser;
     177    /** The critical section associated with the lock. */
     178    R3PTRTYPE(PPDMCRITSECT) pCritSect;
    178179
    179180    /** Pointer to the next timer in the list of created or free timers. (TM::pTimers or TM::pFree) */
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r20060 r20087  
    839839    GEN_CHECK_OFF(TMTIMER, u.Drv.pDrvIns);
    840840    GEN_CHECK_OFF(TMTIMER, u.Internal.pfnTimer);
    841     GEN_CHECK_OFF(TMTIMER, u.Internal.pvUser);
    842841    GEN_CHECK_OFF(TMTIMER, u.External.pfnTimer);
    843     GEN_CHECK_OFF(TMTIMER, u.External.pvUser);
    844842    GEN_CHECK_OFF(TMTIMER, enmState);
    845843    GEN_CHECK_OFF(TMTIMER, offScheduleNext);
    846844    GEN_CHECK_OFF(TMTIMER, offNext);
    847845    GEN_CHECK_OFF(TMTIMER, offPrev);
     846    GEN_CHECK_OFF(TMTIMER, pvUser);
     847    GEN_CHECK_OFF(TMTIMER, pCritSect);
    848848    GEN_CHECK_OFF(TMTIMER, pBigNext);
    849849    GEN_CHECK_OFF(TMTIMER, pBigPrev);
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