/* $Id$ */
/** @file
* PDM - Pluggable Device Manager, Async I/O Completion internal header.
*/
/*
* Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* 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 ___PDMAsyncCompletionInternal_h
#define ___PDMAsyncCompletionInternal_h
#include <iprt/critsect.h>
#include <iprt/memcache.h>
#include <iprt/sg.h>
#include <VBox/types.h>
#include <VBox/vmm/cfgm.h>
#include <VBox/vmm/stam.h>
#include <VBox/vmm/pdmasynccompletion.h>
#include "PDMInternal.h"
RT_C_DECLS_BEGIN
/**
* PDM Async completion endpoint operations.
*/
typedef struct PDMASYNCCOMPLETIONEPCLASSOPS
{
/** Version identifier. */
uint32_t u32Version;
/** Name of the endpoint class. */
const char *pszName;
/** Class type. */
PDMASYNCCOMPLETIONEPCLASSTYPE enmClassType;
/** Size of the global endpoint class data in bytes. */
size_t cbEndpointClassGlobal;
/** Size of an endpoint in bytes. */
size_t cbEndpoint;
/** size of a task in bytes. */
size_t cbTask;
/**
* Initializes the global data for a endpoint class.
*
* @returns VBox status code.
* @param pClassGlobals Pointer to the uninitialized globals data.
* @param pCfgNode Node for querying configuration data.
*/
DECLR3CALLBACKMEMBER(int, pfnInitialize, (PPDMASYNCCOMPLETIONEPCLASS pClassGlobals, PCFGMNODE pCfgNode));
/**
* Frees all allocated resources which were allocated during init.
*
* @returns VBox status code.
* @param pClassGlobals Pointer to the globals data.
*/
DECLR3CALLBACKMEMBER(void, pfnTerminate, (PPDMASYNCCOMPLETIONEPCLASS pClassGlobals));
/**
* Initializes a given endpoint.
*
* @returns VBox status code.
* @param pEndpoint Pointer to the uninitialized endpoint.
* @param pszUri Pointer to the string containing the endpoint
* destination (filename, IP address, ...)
* @param fFlags Creation flags.
*/
DECLR3CALLBACKMEMBER(int, pfnEpInitialize, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
const char *pszUri, uint32_t fFlags));
/**
* Closes a endpoint finishing all tasks.
*
* @returns VBox status code.
* @param pEndpoint Pointer to the endpoint to be closed.
*/
DECLR3CALLBACKMEMBER(int, pfnEpClose, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint));
/**
* Initiates a read request from the given endpoint.
*
* @returns VBox status code.
* @param pTask Pointer to the task object associated with the request.
* @param pEndpoint Endpoint the request is for.
* @param off Where to start reading from.
* @param paSegments Scatter gather list to store the data in.
* @param cSegments Number of segments in the list.
* @param cbRead The overall number of bytes to read.
*/
DECLR3CALLBACKMEMBER(int, pfnEpRead, (PPDMASYNCCOMPLETIONTASK pTask,
PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
PCRTSGSEG paSegments, size_t cSegments,
size_t cbRead));
/**
* Initiates a write request to the given endpoint.
*
* @returns VBox status code.
* @param pTask Pointer to the task object associated with the request.
* @param pEndpoint Endpoint the request is for.
* @param off Where to start writing to.
* @param paSegments Scatter gather list to store the data in.
* @param cSegments Number of segments in the list.
* @param cbRead The overall number of bytes to write.
*/
DECLR3CALLBACKMEMBER(int, pfnEpWrite, (PPDMASYNCCOMPLETIONTASK pTask,
PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
PCRTSGSEG paSegments, size_t cSegments,
size_t cbWrite));
/**
* Initiates a flush request on the given endpoint.
*
* @returns VBox status code.
* @param pTask Pointer to the task object associated with the request.
* @param pEndpoint Endpoint the request is for.
*/
DECLR3CALLBACKMEMBER(int, pfnEpFlush, (PPDMASYNCCOMPLETIONTASK pTask,
PPDMASYNCCOMPLETIONENDPOINT pEndpoint));
/**
* Queries the size of the endpoint. Optional.
*
* @returns VBox status code.
* @param pEndpoint Endpoint the request is for.
* @param pcbSize Where to store the size of the endpoint.
*/
DECLR3CALLBACKMEMBER(int, pfnEpGetSize, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
uint64_t *pcbSize));
/**
* Sets the size of the endpoint. Optional.
* This is a synchronous operation.
*
*
* @returns VBox status code.
* @param pEndpoint Endpoint the request is for.
* @param cbSize New size for the endpoint.
*/
DECLR3CALLBACKMEMBER(int, pfnEpSetSize, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
uint64_t cbSize));
/** Initialization safety marker. */
uint32_t u32VersionEnd;
} PDMASYNCCOMPLETIONEPCLASSOPS;
/** Pointer to a async completion endpoint class operation table. */
typedef PDMASYNCCOMPLETIONEPCLASSOPS *PPDMASYNCCOMPLETIONEPCLASSOPS;
/** Const pointer to a async completion endpoint class operation table. */
typedef const PDMASYNCCOMPLETIONEPCLASSOPS *PCPDMASYNCCOMPLETIONEPCLASSOPS;
/** Version for the endpoint class operations structure. */
#define PDMAC_EPCLASS_OPS_VERSION 0x00000001
/** Pointer to a bandwidth control manager. */
typedef struct PDMACBWMGR *PPDMACBWMGR;
/**
* PDM Async completion endpoint class.
* Common data.
*/
typedef struct PDMASYNCCOMPLETIONEPCLASS
{
/** Pointer to the VM. */
PVM pVM;
/** Critical section protecting the lists below. */
RTCRITSECT CritSect;
/** Number of endpoints in the list. */
volatile unsigned cEndpoints;
/** Head of endpoints with this class. */
R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINT) pEndpointsHead;
/** Head of the bandwidth managers for this class. */
R3PTRTYPE(PPDMACBWMGR) pBwMgrsHead;
/** Pointer to the callback table. */
R3PTRTYPE(PCPDMASYNCCOMPLETIONEPCLASSOPS) pEndpointOps;
/** Task cache. */
RTMEMCACHE hMemCacheTasks;
/** Flag whether to gather advanced statistics about requests. */
bool fGatherAdvancedStatistics;
} PDMASYNCCOMPLETIONEPCLASS;
/** Pointer to the PDM async completion endpoint class data. */
typedef PDMASYNCCOMPLETIONEPCLASS *PPDMASYNCCOMPLETIONEPCLASS;
/**
* A PDM Async completion endpoint.
* Common data.
*/
typedef struct PDMASYNCCOMPLETIONENDPOINT
{
/** Next endpoint in the list. */
R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINT) pNext;
/** Previous endpoint in the list. */
R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINT) pPrev;
/** Pointer to the class this endpoint belongs to. */
R3PTRTYPE(PPDMASYNCCOMPLETIONEPCLASS) pEpClass;
/** Template associated with this endpoint. */
PPDMASYNCCOMPLETIONTEMPLATE pTemplate;
/** Reference count. */
unsigned cUsers;
/** URI describing the endpoint */
char *pszUri;
/** Pointer to the assigned bandwidth manager. */
volatile PPDMACBWMGR pBwMgr;
/** Aligns following statistic counters on a 8 byte boundary. */
uint32_t u32Alignment;
/** @name Request size statistics.
* @{ */
STAMCOUNTER StatReqSizeSmaller512;
STAMCOUNTER StatReqSize512To1K;
STAMCOUNTER StatReqSize1KTo2K;
STAMCOUNTER StatReqSize2KTo4K;
STAMCOUNTER StatReqSize4KTo8K;
STAMCOUNTER StatReqSize8KTo16K;
STAMCOUNTER StatReqSize16KTo32K;
STAMCOUNTER StatReqSize32KTo64K;
STAMCOUNTER StatReqSize64KTo128K;
STAMCOUNTER StatReqSize128KTo256K;
STAMCOUNTER StatReqSize256KTo512K;
STAMCOUNTER StatReqSizeOver512K;
STAMCOUNTER StatReqsUnaligned512;
STAMCOUNTER StatReqsUnaligned4K;
STAMCOUNTER StatReqsUnaligned8K;
/** @} */
/** @name Request completion time statistics.
* @{ */
STAMCOUNTER StatTaskRunTimesNs[10];
STAMCOUNTER StatTaskRunTimesUs[10];
STAMCOUNTER StatTaskRunTimesMs[10];
STAMCOUNTER StatTaskRunTimesSec[10];
STAMCOUNTER StatTaskRunOver100Sec;
STAMCOUNTER StatIoOpsPerSec;
STAMCOUNTER StatIoOpsStarted;
STAMCOUNTER StatIoOpsCompleted;
uint64_t tsIntervalStartMs;
uint64_t cIoOpsCompleted;
/** @} */
} PDMASYNCCOMPLETIONENDPOINT;
AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINT, StatReqSizeSmaller512, sizeof(uint64_t));
AssertCompileMemberAlignment(PDMASYNCCOMPLETIONENDPOINT, StatTaskRunTimesNs, sizeof(uint64_t));
/**
* A PDM async completion task handle.
* Common data.
*/
typedef struct PDMASYNCCOMPLETIONTASK
{
/** Next task in the list
* (for free and assigned tasks). */
R3PTRTYPE(PPDMASYNCCOMPLETIONTASK) pNext;
/** Previous task in the list
* (for free and assigned tasks). */
R3PTRTYPE(PPDMASYNCCOMPLETIONTASK) pPrev;
/** Endpoint this task is assigned to. */
R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINT) pEndpoint;
/** Opaque user data for this task. */
void *pvUser;
/** Start timestamp. */
uint64_t tsNsStart;
} PDMASYNCCOMPLETIONTASK;
void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, int rc, bool fCallCompletionHandler);
bool pdmacEpIsTransferAllowed(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint32_t cbTransfer, RTMSINTERVAL *pmsWhenNext);
RT_C_DECLS_END
extern const PDMASYNCCOMPLETIONEPCLASSOPS g_PDMAsyncCompletionEndpointClassFile;
#endif /* !___PDMAsyncCompletionInternal_h */