PDMBlkCacheInternal.h revision 35a373500556c4c2ac6acfd9a272e47d9a50dcac
/* $Id$ */
/** @file
* PDM Block Cache.
*/
/*
* Copyright (C) 2006-2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#ifndef ___PDMBlkCacheInternal_h
#define ___PDMBlkCacheInternal_h
#include <iprt/semaphore.h>
#include <iprt/critsect.h>
#include <iprt/spinlock.h>
#include <iprt/memcache.h>
/**
* A few forward declarations.
*/
/** Pointer to a cache LRU list. */
typedef struct PDMBLKLRULIST *PPDMBLKLRULIST;
/** Pointer to the global cache structure. */
typedef struct PDMBLKCACHEGLOBAL *PPDMBLKCACHEGLOBAL;
/** Pointer to a cache entry waiter structure. */
typedef struct PDMBLKCACHEWAITER *PPDMBLKCACHEWAITER;
/**
* A cache entry
*/
typedef struct PDMBLKCACHEENTRY
{
/** The AVL entry data. */
/** Pointer to the previous element. Used in one of the LRU lists.*/
struct PDMBLKCACHEENTRY *pPrev;
/** Pointer to the next element. Used in one of the LRU lists.*/
struct PDMBLKCACHEENTRY *pNext;
/** Pointer to the list the entry is in. */
/** Cache the entry belongs to. */
/** Flags for this entry. Combinations of PDMACFILECACHE_* #defines */
/** Reference counter. Prevents eviction of the entry if > 0. */
/** Size of the entry. */
/** Pointer to the memory containing the data. */
/** Head of list of tasks waiting for this one to finish. */
/** Tail of list of tasks waiting for this one to finish. */
/** Node for dirty but not yet committed entries list per endpoint. */
/** I/O is still in progress for this entry. This entry is not evictable. */
#define PDMBLKCACHE_ENTRY_IO_IN_PROGRESS RT_BIT(0)
/** Entry is locked and thus not evictable. */
/** Entry is dirty */
/** Entry is not evictable. */
#define PDMBLKCACHE_NOT_EVICTABLE (PDMBLKCACHE_ENTRY_LOCKED | PDMBLKCACHE_ENTRY_IO_IN_PROGRESS | PDMBLKCACHE_ENTRY_IS_DIRTY)
/**
* LRU list data
*/
typedef struct PDMBLKLRULIST
{
/** Head of the list. */
/** Tail of the list. */
/** Number of bytes cached in the list. */
/**
* Global cache data.
*/
typedef struct PDMBLKCACHEGLOBAL
{
/** Pointer to the owning VM instance. */
/** Maximum size of the cache in bytes. */
/** Current size of the cache in bytes. */
/** Critical section protecting the cache. */
/** Maximum number of bytes cached. */
/** Maximum number of bytes in the paged out list .*/
/** Recently used cache entries list */
/** Scorecard cache entry list. */
/** List of frequently used cache entries */
/** Commit timeout in milli seconds */
/** Number of dirty bytes needed to start a commit of the data to the disk. */
/** Current number of dirty bytes in the cache. */
/** Flag whether a commit is currently in progress. */
volatile bool fCommitInProgress;
/** Commit interval timer */
/** Number of endpoints using the cache. */
/** List of all users of this cache. */
#ifdef VBOX_WITH_STATISTICS
/** Hit counter. */
/** Partial hit counter. */
/** Miss counter. */
/** Bytes read from cache. */
/** Bytes written to the cache. */
/** Time spend to get an entry in the AVL tree. */
/** Time spend to insert an entry in the AVL tree. */
/** Time spend to remove an entry in the AVL tree. */
/** Number of times a buffer could be reused. */
#endif
/** Flag whether the VM was suspended becaus of an I/O error. */
volatile bool fIoErrorVmSuspended;
#ifdef VBOX_WITH_STATISTICS
#endif
/**
* Block cache type.
*/
typedef enum PDMBLKCACHETYPE
{
/** Device . */
PDMBLKCACHETYPE_DEV = 1,
/** Driver consumer. */
/** Internal consumer. */
/** Usb consumer. */
/**
* Per user cache data.
*/
typedef struct PDMBLKCACHE
{
/** Pointer to the id for the cache. */
char *pszId;
/** AVL tree managing cache entries. */
/** R/W semaphore protecting cached entries for this endpoint. */
/** Pointer to the gobal cache data */
/** Lock protecting the dirty entries list. */
/** List of dirty but not committed entries for this endpoint. */
/** Node of the cache user list. */
/** Block cache type. */
/** Type specific data. */
union
{
/** PDMASYNCCOMPLETIONTEMPLATETYPE_DEV */
struct
{
/** Pointer to the device instance owning the block cache. */
/** Complete callback to the user. */
/** I/O enqueue callback. */
} Dev;
/** PDMASYNCCOMPLETIONTEMPLATETYPE_DRV */
struct
{
/** Pointer to the driver instance owning the block cache. */
/** Complete callback to the user. */
/** I/O enqueue callback. */
} Drv;
/** PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL */
struct
{
/** Pointer to user data. */
/** Complete callback to the user. */
/** I/O enqueue callback. */
} Int;
/** PDMASYNCCOMPLETIONTEMPLATETYPE_USB */
struct
{
/** Pointer to the usb instance owning the template. */
/** Complete callback to the user. */
/** I/O enqueue callback. */
} Usb;
} u;
#ifdef VBOX_WITH_STATISTICS
/** Number of times a write was deferred because the cache entry was still in progress */
#endif
/** Flag whether the cache was suspended. */
volatile bool fSuspended;
} PDMBLKCACHE, *PPDMBLKCACHE;
#ifdef VBOX_WITH_STATISTICS
#endif
/**
* I/O task.
*/
typedef struct PDMBLKCACHEREQ
{
/** Opaque user data returned on completion. */
void *pvUser;
/** Number of pending transfers (waiting for a cache entry and passed through). */
volatile uint32_t cXfersPending;
/** Status code. */
volatile int rcReq;
/**
* I/O transfer from the cache to the underlying medium.
*/
typedef struct PDMBLKCACHEIOXFER
{
/** Flag whether the I/O xfer updates a cache entry or updates the request directl. */
bool fIoCache;
/** Type dependent data. */
union
{
/** Pointer to the entry the transfer updates. */
/** Pointer to the request the ztransfer updates. */
};
/** Segment used if a cache entry is updated. */
/** S/G buffer. */
/** Transfer direction. */
/**
* Cache waiter
*/
typedef struct PDMBLKCACHEWAITER
{
/* Next waiter in the list. */
struct PDMBLKCACHEWAITER *pNext;
/** S/G buffer holding or receiving data. */
/** Offset into the cache entry to start the transfer. */
/** How many bytes to transfer. */
/** Flag whether the task wants to read or write into the entry. */
bool fWrite;
/** Task the waiter is for. */
#endif