TMInternal.h revision cee5f4e7e4f238fc5b3436abdf3c915275017f6e
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * TM - Internal header file.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * available from http://www.virtualbox.org. This file is free software;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * you can redistribute it and/or modify it under the terms of the GNU
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * General Public License as published by the Free Software Foundation,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync * If you received this file as part of a commercial VirtualBox
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync * distribution, then only the terms of your commercial VirtualBox
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync * license agreement apply instead of the previous paragraph.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** @defgroup grp_tm_int Internal
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @ingroup grp_tm
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * @internal
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** Frequency of the real clock. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** Frequency of the virtual clock. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Timer type.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Device timer. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Driver timer. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Internal timer . */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** External timer. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Timer state
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is stopped. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is active. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is expired, is being delivered. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is stopped but still in the active list.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is stopped but needs unlinking from the ScheduleTimers list.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is being modified and will soon be pending scheduling.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is pending scheduling.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is being modified and will soon be pending rescheduling.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list and the active list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is modified and is now pending rescheduling.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list and the active list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is destroyed but needs to be replaced from the
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * active to the free list.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list and the active list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is destroyed but needs moving to the free list.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is free. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Internal representation of a timer.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * For correct serialization (without the use of semaphores and
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * other blocking/slow constructs) certain rules applies to updating
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * this structure:
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * - For thread other than EMT only u64Expire, enmState and pScheduleNext*
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * are changeable. Everything else is out of bounds.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * - Updating of u64Expire timer can only happen in the TMTIMERSTATE_STOPPED
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * and TMTIMERSTATE_PENDING_RESCHEDULING_SET_EXPIRE states.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * - Timers in the TMTIMERSTATE_EXPIRED state are only accessible from EMT.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * - Actual destruction of a timer can only be done at scheduling time.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsynctypedef struct TMTIMER
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Expire time. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Clock to apply to u64Expire. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer callback type. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Type specific data. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMTIMERTYPE_DEV. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Callback. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Device instance. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMTIMERTYPE_DRV. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Callback. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Device instance. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMTIMERTYPE_INTERNAL. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** Callback. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** User argument. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** TMTIMERTYPE_EXTERNAL. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Callback. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /** User data. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /** Timer state. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /** Timer relative offset to the next timer in the schedule list. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer relative offset to the next timer in the chain. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer relative offset to the previous timer in the chain. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the next timer in the list of created or free timers. (TM::pTimers or TM::pFree) */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the previous timer in the list of all created timers. (TM::pTimers) */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the timer description. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the VM the timer belongs to - R3 Ptr. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the VM the timer belongs to - R0 Ptr. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the VM the timer belongs to - GC Ptr. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync RTGCPTR padding0; /**< pad structure to multiple of 8 bytes. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Updates a timer state in the correct atomic manner.
044af0d1e6474076366759db86f101778c5f20ccvboxsync do { Log(("%s: %p: %d -> %d\n", __FUNCTION__, (pTimer), (pTimer)->enmState, state)); \
044af0d1e6474076366759db86f101778c5f20ccvboxsync } while (0)
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Tries to updates a timer state in the correct atomic manner.
044af0d1e6474076366759db86f101778c5f20ccvboxsync# define TM_TRY_SET_STATE(pTimer, StateNew, StateOld, fRc) \
044af0d1e6474076366759db86f101778c5f20ccvboxsync ASMAtomicCmpXchgSize(&(pTimer)->enmState, StateNew, StateOld, fRc)
044af0d1e6474076366759db86f101778c5f20ccvboxsync# define TM_TRY_SET_STATE(pTimer, StateNew, StateOld, fRc) \
044af0d1e6474076366759db86f101778c5f20ccvboxsync do { ASMAtomicCmpXchgSize(&(pTimer)->enmState, StateNew, StateOld, fRc); \
044af0d1e6474076366759db86f101778c5f20ccvboxsync Log(("%s: %p: %d -> %d %RTbool\n", __FUNCTION__, (pTimer), StateOld, StateNew, fRc)); \
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync } while (0)
044af0d1e6474076366759db86f101778c5f20ccvboxsync/** Get the previous timer. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync#define TMTIMER_GET_PREV(pTimer) ((PTMTIMER)((pTimer)->offPrev ? (intptr_t)(pTimer) + (pTimer)->offPrev : 0))
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Get the next timer. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync#define TMTIMER_GET_NEXT(pTimer) ((PTMTIMER)((pTimer)->offNext ? (intptr_t)(pTimer) + (pTimer)->offNext : 0))
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Set the previous timer link. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#define TMTIMER_SET_PREV(pTimer, pPrev) ((pTimer)->offPrev = (pPrev) ? (intptr_t)(pPrev) - (intptr_t)(pTimer) : 0)
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync/** Set the next timer link. */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync#define TMTIMER_SET_NEXT(pTimer, pNext) ((pTimer)->offNext = (pNext) ? (intptr_t)(pNext) - (intptr_t)(pTimer) : 0)
044af0d1e6474076366759db86f101778c5f20ccvboxsync * A timer queue.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * This is allocated on the hyper heap.
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef struct TMTIMERQUEUE
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The cached expire time for this queue.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Updated by EMT when scheduling the queue or modifying the head timer.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Assigned UINT64_MAX when there is no head timer. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Doubly linked list of active timers.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * When no scheduling is pending, this list is will be ordered by expire time (ascending).
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Access is serialized by only letting the emulation thread (EMT) do changes.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * The offset is relative to the queue structure.
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** List of timers pending scheduling of some kind.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Timer stats allowed in the list are TMTIMERSTATE_PENDING_STOPPING,
044af0d1e6474076366759db86f101778c5f20ccvboxsync * TMTIMERSTATE_PENDING_DESTRUCTION, TMTIMERSTATE_PENDING_STOPPING_DESTRUCTION,
044af0d1e6474076366759db86f101778c5f20ccvboxsync * TMTIMERSTATE_PENDING_RESCHEDULING and TMTIMERSTATE_PENDING_SCHEDULE.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * The offset is relative to the queue structure.
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The clock for this queue. */
a1df400bbe9d64aad400442e56eb637019300a5evboxsync /** Pad the structure up to 32 bytes. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** Pointer to a timer queue. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync/** Get the head of the active timer list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#define TMTIMER_GET_HEAD(pQueue) ((PTMTIMER)((pQueue)->offActive ? (intptr_t)(pQueue) + (pQueue)->offActive : 0))
044af0d1e6474076366759db86f101778c5f20ccvboxsync/** Set the head of the active timer list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#define TMTIMER_SET_HEAD(pQueue, pHead) ((pQueue)->offActive = pHead ? (intptr_t)pHead - (intptr_t)(pQueue) : 0)
a1df400bbe9d64aad400442e56eb637019300a5evboxsync * Converts a TM pointer into a VM pointer.
a1df400bbe9d64aad400442e56eb637019300a5evboxsync * @returns Pointer to the VM structure the TM is part of.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @param pTM Pointer to TM instance data.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#define TM2VM(pTM) ( (PVM)((char*)pTM - pTM->offVM) )
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * TM VM Instance data.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Changes to this must checked against the padding of the cfgm union in VM!
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsynctypedef struct TM
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Offset to the VM structure.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * See TM2VM(). */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** CPU timestamp ticking enabled indicator (bool). (RDTSC) */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** The offset between the host TSC and the Guest TSC.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Only valid if fTicking is set. */
a1df400bbe9d64aad400442e56eb637019300a5evboxsync /** The guest TSC when fTicking is cleared. */
a1df400bbe9d64aad400442e56eb637019300a5evboxsync /** The number of CPU clock ticks per second (TMCLOCK_TSC).
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * If GIP is available, g_pSUPGlobalInfoPage->u64CpuHz will be used instead. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Padding to ensure that 64-bit values are equaly aligned everywhere. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Virtual time ticking enabled indicator (bool). (TMCLOCK_VIRTUAL) */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Virtual timer synchronous time ticking enabled indicator (bool). (TMCLOCK_VIRTUAL_SYNC) */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Virtual timer synchronous time catch-up active. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** The offset of the virtual clock relative to it's timesource.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Only valid if fVirtualTicking is set. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The guest virtual time when fVirtualTicking is cleared. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The offset of the virtual timer synchronous clock (TMCLOCK_VIRTUAL_SYNC) relative
044af0d1e6474076366759db86f101778c5f20ccvboxsync * to the virtual clock. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The TMCLOCK_VIRTUAL at the previous TMVirtualGetSync call when catch-up is active. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The guest virtual timer synchronous time when fVirtualSyncTicking is cleared. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** How many precent faster the clock should advance when catch-up is active. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** When to stop catch-up. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** When to start catch-up. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** When to give up catch-up. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer queues for the different clock types - R3 Ptr */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer queues for the different clock types - R0 Ptr */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer queues for the different clock types - GC Ptr */
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync /** Pointer to our GC mapping of the GIP. */
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync /** Pointer to our R3 mapping of the GIP. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Pointer to a singly linked list of free timers.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * This chain is using the TMTIMER::pBigNext members.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Only accessible from the emulation thread. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to a doubly linked list of created timers.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * This chain is using the TMTIMER::pBigNext and TMTIMER::pBigPrev members.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Only accessible from the emulation thread. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** The schedulation timer timer handle (runtime timer).
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * This timer will do freqent check on pending queue schedulations and
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync * raise VM_FF_TIMER to pull EMTs attention to them.
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync /** Interval in milliseconds of the pTimer timer. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Alignment padding to ensure that the statistics are 64-bit aligned when using GCC. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMR3TimerQueuesDo
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** tmSchedule
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync /** TMTimerPoll
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** TMTimerSet
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMTimerStop
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync /** The timer callback. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** Pointer to TM VM instance data. */