TMInternal.h revision cee5f4e7e4f238fc5b3436abdf3c915275017f6e
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/* $Id$ */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** @file
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * TM - Internal header file.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/*
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync *
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.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync *
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.
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync */
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync#ifndef __TMInternal_h__
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync#define __TMInternal_h__
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync
0d12c7f9423f2745f8e282523d0930f91bff03b3vboxsync#include <VBox/cdefs.h>
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#include <VBox/types.h>
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#include <iprt/timer.h>
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#include <VBox/stam.h>
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync__BEGIN_DECLS
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** @defgroup grp_tm_int Internal
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @ingroup grp_tm
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * @internal
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @{
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync */
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** Frequency of the real clock. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#define TMCLOCK_FREQ_REAL UINT32_C(1000)
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** Frequency of the virtual clock. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#define TMCLOCK_FREQ_VIRTUAL UINT32_C(1000000000)
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/**
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Timer type.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsynctypedef enum TMTIMERTYPE
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync{
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Device timer. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERTYPE_DEV = 1,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Driver timer. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERTYPE_DRV,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Internal timer . */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERTYPE_INTERNAL,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** External timer. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERTYPE_EXTERNAL
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync} TMTIMERTYPE;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/**
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Timer state
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsynctypedef enum TMTIMERSTATE
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync{
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is stopped. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_STOPPED = 1,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is active. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync TMTIMERSTATE_ACTIVE,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is expired, is being delivered. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_EXPIRED,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is stopped but still in the active list.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_PENDING_STOP,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is stopped but needs unlinking from the ScheduleTimers list.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_PENDING_STOP_SCHEDULE,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is being modified and will soon be pending scheduling.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_PENDING_SCHEDULE_SET_EXPIRE,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is pending scheduling.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_PENDING_SCHEDULE,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is being modified and will soon be pending rescheduling.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list and the active list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_PENDING_RESCHEDULE_SET_EXPIRE,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is modified and is now pending rescheduling.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list and the active list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_PENDING_RESCHEDULE,
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 TMTIMERSTATE_PENDING_STOP_DESTROY,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is destroyed but needs moving to the free list.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Currently in the ScheduleTimers list. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_PENDING_DESTROY,
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer is free. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERSTATE_FREE
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync} TMTIMERSTATE;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/**
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Internal representation of a timer.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync *
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.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsynctypedef struct TMTIMER
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync{
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Expire time. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync volatile uint64_t u64Expire;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Clock to apply to u64Expire. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMCLOCK enmClock;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Timer callback type. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync TMTIMERTYPE enmType;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Type specific data. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync union
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync {
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMTIMERTYPE_DEV. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync struct
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync {
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Callback. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync R3PTRTYPE(PFNTMTIMERDEV) pfnTimer;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Device instance. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync R3PTRTYPE(PPDMDEVINS) pDevIns;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync } Dev;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMTIMERTYPE_DRV. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync struct
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync {
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Callback. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync R3PTRTYPE(PFNTMTIMERDRV) pfnTimer;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Device instance. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync R3PTRTYPE(PPDMDRVINS) pDrvIns;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync } Drv;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMTIMERTYPE_INTERNAL. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync struct
044af0d1e6474076366759db86f101778c5f20ccvboxsync {
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** Callback. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync R3PTRTYPE(PFNTMTIMERINT) pfnTimer;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** User argument. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync R3PTRTYPE(void *) pvUser;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync } Internal;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** TMTIMERTYPE_EXTERNAL. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync struct
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync {
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Callback. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync R3PTRTYPE(PFNTMTIMEREXT) pfnTimer;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /** User data. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync R3PTRTYPE(void *) pvUser;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync } External;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync } u;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /** Timer state. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync volatile TMTIMERSTATE enmState;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync /** Timer relative offset to the next timer in the schedule list. */
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync int32_t offScheduleNext;
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer relative offset to the next timer in the chain. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync int32_t offNext;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer relative offset to the previous timer in the chain. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync int32_t offPrev;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the next timer in the list of created or free timers. (TM::pTimers or TM::pFree) */
044af0d1e6474076366759db86f101778c5f20ccvboxsync PTMTIMERR3 pBigNext;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the previous timer in the list of all created timers. (TM::pTimers) */
044af0d1e6474076366759db86f101778c5f20ccvboxsync PTMTIMERR3 pBigPrev;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the timer description. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync HCPTRTYPE(const char *) pszDesc;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the VM the timer belongs to - R3 Ptr. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync PVMR3 pVMR3;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the VM the timer belongs to - R0 Ptr. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync PVMR0 pVMR0;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Pointer to the VM the timer belongs to - GC Ptr. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync PVMGC pVMGC;
044af0d1e6474076366759db86f101778c5f20ccvboxsync#if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32
044af0d1e6474076366759db86f101778c5f20ccvboxsync RTGCPTR padding0; /**< pad structure to multiple of 8 bytes. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync#endif
044af0d1e6474076366759db86f101778c5f20ccvboxsync} TMTIMER;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync/**
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Updates a timer state in the correct atomic manner.
044af0d1e6474076366759db86f101778c5f20ccvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync#if 1
044af0d1e6474076366759db86f101778c5f20ccvboxsync# define TM_SET_STATE(pTimer, state) \
044af0d1e6474076366759db86f101778c5f20ccvboxsync ASMAtomicXchgSize(&(pTimer)->enmState, state)
044af0d1e6474076366759db86f101778c5f20ccvboxsync#else
044af0d1e6474076366759db86f101778c5f20ccvboxsync# define TM_SET_STATE(pTimer, state) \
044af0d1e6474076366759db86f101778c5f20ccvboxsync do { Log(("%s: %p: %d -> %d\n", __FUNCTION__, (pTimer), (pTimer)->enmState, state)); \
044af0d1e6474076366759db86f101778c5f20ccvboxsync ASMAtomicXchgSize(&(pTimer)->enmState, state);\
044af0d1e6474076366759db86f101778c5f20ccvboxsync } while (0)
044af0d1e6474076366759db86f101778c5f20ccvboxsync#endif
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync/**
044af0d1e6474076366759db86f101778c5f20ccvboxsync * Tries to updates a timer state in the correct atomic manner.
044af0d1e6474076366759db86f101778c5f20ccvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync#if 1
044af0d1e6474076366759db86f101778c5f20ccvboxsync# define TM_TRY_SET_STATE(pTimer, StateNew, StateOld, fRc) \
044af0d1e6474076366759db86f101778c5f20ccvboxsync ASMAtomicCmpXchgSize(&(pTimer)->enmState, StateNew, StateOld, fRc)
2bb12e589d2c280ad042e4e70635ae7224c7eceevboxsync#else
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)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync#endif
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
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)
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync/**
044af0d1e6474076366759db86f101778c5f20ccvboxsync * A timer queue.
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync *
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * This is allocated on the hyper heap.
044af0d1e6474076366759db86f101778c5f20ccvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsynctypedef struct TMTIMERQUEUE
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
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 uint64_t u64Expire;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Doubly linked list of active timers.
044af0d1e6474076366759db86f101778c5f20ccvboxsync *
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 *
044af0d1e6474076366759db86f101778c5f20ccvboxsync * The offset is relative to the queue structure.
044af0d1e6474076366759db86f101778c5f20ccvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync int32_t offActive;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** List of timers pending scheduling of some kind.
044af0d1e6474076366759db86f101778c5f20ccvboxsync *
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 *
044af0d1e6474076366759db86f101778c5f20ccvboxsync * The offset is relative to the queue structure.
044af0d1e6474076366759db86f101778c5f20ccvboxsync */
044af0d1e6474076366759db86f101778c5f20ccvboxsync int32_t volatile offSchedule;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The clock for this queue. */
a1df400bbe9d64aad400442e56eb637019300a5evboxsync TMCLOCK enmClock;
a1df400bbe9d64aad400442e56eb637019300a5evboxsync /** Pad the structure up to 32 bytes. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint32_t au32Padding[3];
a1df400bbe9d64aad400442e56eb637019300a5evboxsync} TMTIMERQUEUE;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** Pointer to a timer queue. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsynctypedef TMTIMERQUEUE *PTMTIMERQUEUE;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
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)
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/**
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.
a1df400bbe9d64aad400442e56eb637019300a5evboxsync */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#define TM2VM(pTM) ( (PVM)((char*)pTM - pTM->offVM) )
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/**
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * TM VM Instance data.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Changes to this must checked against the padding of the cfgm union in VM!
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsynctypedef struct TM
044af0d1e6474076366759db86f101778c5f20ccvboxsync{
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Offset to the VM structure.
044af0d1e6474076366759db86f101778c5f20ccvboxsync * See TM2VM(). */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync RTUINT offVM;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** CPU timestamp ticking enabled indicator (bool). (RDTSC) */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync bool fTSCTicking;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** The offset between the host TSC and the Guest TSC.
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * Only valid if fTicking is set. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync uint64_t u64TSCOffset;
a1df400bbe9d64aad400442e56eb637019300a5evboxsync /** The guest TSC when fTicking is cleared. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync uint64_t u64TSC;
a1df400bbe9d64aad400442e56eb637019300a5evboxsync /** The number of CPU clock ticks per second (TMCLOCK_TSC).
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * If GIP is available, g_pSUPGlobalInfoPage->u64CpuHz will be used instead. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint64_t cTSCTicksPerSecond;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Padding to ensure that 64-bit values are equaly aligned everywhere. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync uint32_t uReserved;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Virtual time ticking enabled indicator (bool). (TMCLOCK_VIRTUAL) */
044af0d1e6474076366759db86f101778c5f20ccvboxsync bool fVirtualTicking;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Virtual timer synchronous time ticking enabled indicator (bool). (TMCLOCK_VIRTUAL_SYNC) */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync bool fVirtualSyncTicking;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** Virtual timer synchronous time catch-up active. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync bool volatile fVirtualSyncCatchUp;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync /** The offset of the virtual clock relative to it's timesource.
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync * Only valid if fVirtualTicking is set. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint64_t u64VirtualOffset;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The guest virtual time when fVirtualTicking is cleared. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint64_t u64Virtual;
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The offset of the virtual timer synchronous clock (TMCLOCK_VIRTUAL_SYNC) relative
044af0d1e6474076366759db86f101778c5f20ccvboxsync * to the virtual clock. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint64_t volatile u64VirtualSyncOffset;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The TMCLOCK_VIRTUAL at the previous TMVirtualGetSync call when catch-up is active. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint64_t volatile u64VirtualSyncCatchUpPrev;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** The guest virtual timer synchronous time when fVirtualSyncTicking is cleared. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint64_t u64VirtualSync;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** How many precent faster the clock should advance when catch-up is active. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint32_t u32VirtualSyncCatchupPrecentage;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** When to stop catch-up. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint32_t u32VirtualSyncCatchupStopThreashold;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** When to start catch-up. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint64_t u64VirtualSyncCatchupStartTreashold;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** When to give up catch-up. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync uint64_t u64VirtualSyncCatchupGiveUpTreashold;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer queues for the different clock types - R3 Ptr */
044af0d1e6474076366759db86f101778c5f20ccvboxsync R3PTRTYPE(PTMTIMERQUEUE) paTimerQueuesR3;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer queues for the different clock types - R0 Ptr */
044af0d1e6474076366759db86f101778c5f20ccvboxsync R0PTRTYPE(PTMTIMERQUEUE) paTimerQueuesR0;
044af0d1e6474076366759db86f101778c5f20ccvboxsync /** Timer queues for the different clock types - GC Ptr */
044af0d1e6474076366759db86f101778c5f20ccvboxsync GCPTRTYPE(PTMTIMERQUEUE) paTimerQueuesGC;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync /** Pointer to our GC mapping of the GIP. */
044af0d1e6474076366759db86f101778c5f20ccvboxsync GCPTRTYPE(void *) pvGIPGC;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync /** Pointer to our R3 mapping of the GIP. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync R3PTRTYPE(void *) pvGIPR3;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
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. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync PTMTIMERR3 pFree;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
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. */
ca3da10d05961c339b5180fbd40a54587d6bad35vboxsync PTMTIMERR3 pCreated;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
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 */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync HCPTRTYPE(PRTTIMER) pTimer;
df8e6a449f00e1884fbf4a1fc67143614d7d528dvboxsync /** Interval in milliseconds of the pTimer timer. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync uint32_t u32TimerMillies;
044af0d1e6474076366759db86f101778c5f20ccvboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** Alignment padding to ensure that the statistics are 64-bit aligned when using GCC. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync uint32_t u32Padding;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMR3TimerQueuesDo
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @{ */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMPROFILE StatDoQueues;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMPROFILEADV StatDoQueuesSchedule;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMPROFILEADV StatDoQueuesRun;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** @} */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** tmSchedule
4a1654dd5b9f0ae4e149d909843a3ab07b8bec33vboxsync * @{ */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMPROFILE StatScheduleOneGC;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMPROFILE StatScheduleOneR0;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMPROFILE StatScheduleOneR3;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMCOUNTER StatScheduleSetFF;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** @} */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMCOUNTER StatVirtualGet;
ae83ea510012552d3286d67b41abddf158ca6654vboxsync STAMCOUNTER StatVirtualGetSync;
ae83ea510012552d3286d67b41abddf158ca6654vboxsync STAMCOUNTER StatVirtualPause;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMCOUNTER StatVirtualResume;
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync /** TMTimerPoll
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @{ */
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync STAMCOUNTER StatPollAlreadySet;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMCOUNTER StatPollVirtual;
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync STAMCOUNTER StatPollVirtualSync;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMCOUNTER StatPollMiss;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** @} */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** TMTimerSet
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @{ */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMPROFILE StatTimerSetGC;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMPROFILE StatTimerSetR0;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMPROFILE StatTimerSetR3;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync /** @} */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** TMTimerStop
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync * @{ */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMPROFILE StatTimerStopGC;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMPROFILE StatTimerStopR0;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMPROFILE StatTimerStopR3;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /** @} */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync /**
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync * @{ */
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMCOUNTER StatPostponedR3;
172ae196da38208e5f1e3485715a89f2d53c6880vboxsync STAMCOUNTER StatPostponedR0;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync STAMCOUNTER StatPostponedGC;
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync /** @} */
72a6fe3989272cb2d409b50caca25e1edbca9398vboxsync /** The timer callback. */
7af218a7441de38fc9e814919db04bae3e917664vboxsync STAMCOUNTER StatTimerCallbackSetFF;
c0e27f622f9bd6d9e77d2d959aab71d69dabf0d3vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync} TM;
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync/** Pointer to TM VM instance data. */
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsynctypedef TM *PTM;
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsyncconst char *tmTimerState(TMTIMERSTATE enmState);
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsyncvoid tmTimerQueueSchedule(PVM pVM, PTMTIMERQUEUE pQueue);
3a4a6501d0ccd629d9951b644d380c7bb2d46086vboxsync#ifdef VBOX_STRICT
void tmTimerQueuesSanityChecks(PVM pVM, const char *pszWhere);
#endif
/** @} */
__END_DECLS
#endif