PDMAsyncCompletion.cpp revision 70aa086e9e9d2f85d2e997d0e69169018a001e54
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * PDM Async I/O - Transport data asynchronous in R3 using EMT.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync * Copyright (C) 2006-2011 Oracle Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Header Files *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include "PDMInternal.h"
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/pdm.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/mm.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/rem.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/vm.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/vmm/uvm.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <VBox/err.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync
e41f0459369a6d814aa36bf4def225482fc56026vboxsync#include <VBox/log.h>
e41f0459369a6d814aa36bf4def225482fc56026vboxsync#include <iprt/asm.h>
e41f0459369a6d814aa36bf4def225482fc56026vboxsync#include <iprt/assert.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/thread.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <iprt/mem.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <iprt/critsect.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <iprt/tcp.h>
0b5a8573f70560f0fd30c01151fcdc0e71984276vboxsync#include <iprt/path.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/string.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/vmm/pdmasynccompletion.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include "PDMAsyncCompletionInternal.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Structures and Typedefs *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Async I/O type.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef enum PDMASYNCCOMPLETIONTEMPLATETYPE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Device . */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDMASYNCCOMPLETIONTEMPLATETYPE_DEV = 1,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Driver consumer. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDMASYNCCOMPLETIONTEMPLATETYPE_DRV,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Internal consumer. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Usb consumer. */
d03c6bcd3d78cef8ac4d76186e7c0e72f63ce80fvboxsync PDMASYNCCOMPLETIONTEMPLATETYPE_USB
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync} PDMASYNCTEMPLATETYPE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d03c6bcd3d78cef8ac4d76186e7c0e72f63ce80fvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * PDM Async I/O template.
d03c6bcd3d78cef8ac4d76186e7c0e72f63ce80fvboxsync */
d03c6bcd3d78cef8ac4d76186e7c0e72f63ce80fvboxsynctypedef struct PDMASYNCCOMPLETIONTEMPLATE
d03c6bcd3d78cef8ac4d76186e7c0e72f63ce80fvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to the next template in the list. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to the previous template in the list. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pPrev;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Type specific data. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync union
cfb3a8ae5e9668de4506cf5c053b8009bcc89dafvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** PDMASYNCCOMPLETIONTEMPLATETYPE_DEV */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync struct
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to consumer function. */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync R3PTRTYPE(PFNPDMASYNCCOMPLETEDEV) pfnCompleted;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to the device instance owning the template. */
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync R3PTRTYPE(PPDMDEVINS) pDevIns;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } Dev;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** PDMASYNCCOMPLETIONTEMPLATETYPE_DRV */
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync struct
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to consumer function. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync R3PTRTYPE(PFNPDMASYNCCOMPLETEDRV) pfnCompleted;
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync /** Pointer to the driver instance owning the template. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync R3PTRTYPE(PPDMDRVINS) pDrvIns;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /** User argument given during template creation.
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync * This is only here to make things much easier
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync * for DrVVD. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync void *pvTemplateUser;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync } Drv;
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync /** PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL */
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync struct
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to consumer function. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync R3PTRTYPE(PFNPDMASYNCCOMPLETEINT) pfnCompleted;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /** Pointer to user data. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync R3PTRTYPE(void *) pvUser;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } Int;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** PDMASYNCCOMPLETIONTEMPLATETYPE_USB */
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync struct
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to consumer function. */
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync R3PTRTYPE(PFNPDMASYNCCOMPLETEUSB) pfnCompleted;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /** Pointer to the usb instance owning the template. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync R3PTRTYPE(PPDMUSBINS) pUsbIns;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } Usb;
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync } u;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /** Template type. */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync PDMASYNCCOMPLETIONTEMPLATETYPE enmType;
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync /** Pointer to the VM. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync R3PTRTYPE(PVM) pVM;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync /** Use count of the template. */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync volatile uint32_t cUsed;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync} PDMASYNCCOMPLETIONTEMPLATE;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync/**
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync * Bandwidth control manager instance data
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsynctypedef struct PDMACBWMGR
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync{
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync /** Pointer to the next manager in the list. */
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync struct PDMACBWMGR *pNext;
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync /** Pointer to the shared UVM structure. */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync PPDMASYNCCOMPLETIONEPCLASS pEpClass;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync /** Identifier of the manager. */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync char *pszId;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync /** Maximum number of bytes the endpoints are allowed to transfer (Max is 4GB/s currently) */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync volatile uint32_t cbTransferPerSecMax;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync /** Number of bytes we start with */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync volatile uint32_t cbTransferPerSecStart;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync /** Step after each update */
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync volatile uint32_t cbTransferPerSecStep;
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync /** Number of bytes we are allowed to transfer till the next update.
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync * Reset by the refresh timer. */
05406988cc320ac1b0971de976b6cf0c986044a9vboxsync volatile uint32_t cbTransferAllowed;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync /** Timestamp of the last update */
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync volatile uint64_t tsUpdatedLast;
1db6afc370c2fa84144478dffa9c1ed3c28c7158vboxsync /** Reference counter - How many endpoints are associated with this manager. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync volatile uint32_t cRefs;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync} PDMACBWMGR;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Pointer to a bandwidth control manager pointer. */
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsynctypedef PPDMACBWMGR *PPPDMACBWMGR;
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Internal Functions *
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync*******************************************************************************/
323b78bf4831666c95416edf3b6e54657a769e5dvboxsyncstatic void pdmR3AsyncCompletionPutTask(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, PPDMASYNCCOMPLETIONTASK pTask);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Internal worker for the creation apis
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ppTemplate Where to store the template handle.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int pdmR3AsyncCompletionTemplateCreate(PVM pVM, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDMASYNCCOMPLETIONTEMPLATETYPE enmType)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PUVM pUVM = pVM->pUVM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync AssertPtrReturn(ppTemplate, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
23de3d76e5d27015e334e6ff763ab08de5969363vboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_ASYNC_COMPLETION, sizeof(PDMASYNCCOMPLETIONTEMPLATE), (void **)&pTemplate);
23de3d76e5d27015e334e6ff763ab08de5969363vboxsync if (RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initialize fields.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->pVM = pVM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->cUsed = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->enmType = enmType;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Add template to the global VM template list.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTCritSectEnter(&pUVM->pdm.s.ListCritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->pNext = pUVM->pdm.s.pAsyncCompletionTemplates;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pUVM->pdm.s.pAsyncCompletionTemplates)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pUVM->pdm.s.pAsyncCompletionTemplates->pPrev = pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pUVM->pdm.s.pAsyncCompletionTemplates = pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppTemplate = pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * Creates a async completion template for a device instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * The template is used when creating new completion tasks.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDevIns The device instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ppTemplate Where to store the template pointer on success.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @param pfnCompleted The completion callback routine.
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync * @param pszDesc Description.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc)
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("%s: pDevIns=%p ppTemplate=%p pfnCompleted=%p pszDesc=%s\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync __FUNCTION__, pDevIns, ppTemplate, pfnCompleted, pszDesc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Validate input.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VM_ASSERT_EMT(pVM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pfnCompleted, VERR_INVALID_POINTER);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AssertPtrReturn(ppTemplate, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync * Create the template.
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = pdmR3AsyncCompletionTemplateCreate(pVM, &pTemplate, PDMASYNCCOMPLETIONTEMPLATETYPE_DEV);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync pTemplate->u.Dev.pDevIns = pDevIns;
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync pTemplate->u.Dev.pfnCompleted = pfnCompleted;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppTemplate = pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("PDM: Created device template %p: pfnCompleted=%p pDevIns=%p\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate, pfnCompleted, pDevIns));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61e80138f3c5ea5213990bde94a973c8e64d1dadvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Creates a async completion template for a driver instance.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The template is used when creating new completion tasks.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDrvIns The driver instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ppTemplate Where to store the template pointer on success.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pfnCompleted The completion callback routine.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pvTemplateUser Template user argument
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pszDesc Description.
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("%s: pDrvIns=%p ppTemplate=%p pfnCompleted=%p pszDesc=%s\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync __FUNCTION__, pDrvIns, ppTemplate, pfnCompleted, pszDesc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Validate input.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pfnCompleted, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(ppTemplate, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Create the template.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync */
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate;
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync int rc = pdmR3AsyncCompletionTemplateCreate(pVM, &pTemplate, PDMASYNCCOMPLETIONTEMPLATETYPE_DRV);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync pTemplate->u.Drv.pDrvIns = pDrvIns;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->u.Drv.pfnCompleted = pfnCompleted;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync pTemplate->u.Drv.pvTemplateUser = pvTemplateUser;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppTemplate = pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("PDM: Created driver template %p: pfnCompleted=%p pDrvIns=%p\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate, pfnCompleted, pDrvIns));
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync }
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
090f6abdd6282f48527b83162b8b441425f05e36vboxsync}
090f6abdd6282f48527b83162b8b441425f05e36vboxsync
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync/**
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsync * Creates a async completion template for a USB device instance.
698f914c9d8da3932ce1e1f8f170e19bd151560evboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The template is used when creating new completion tasks.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pUsbIns The USB device instance.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @param ppTemplate Where to store the template pointer on success.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @param pfnCompleted The completion callback routine.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync * @param pszDesc Description.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
090f6abdd6282f48527b83162b8b441425f05e36vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc)
090f6abdd6282f48527b83162b8b441425f05e36vboxsync{
090f6abdd6282f48527b83162b8b441425f05e36vboxsync LogFlow(("%s: pUsbIns=%p ppTemplate=%p pfnCompleted=%p pszDesc=%s\n",
090f6abdd6282f48527b83162b8b441425f05e36vboxsync __FUNCTION__, pUsbIns, ppTemplate, pfnCompleted, pszDesc));
118e1c3f853f78b4aec64afdcb8379981f41314fvboxsync
118e1c3f853f78b4aec64afdcb8379981f41314fvboxsync /*
118e1c3f853f78b4aec64afdcb8379981f41314fvboxsync * Validate input.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VM_ASSERT_EMT(pVM);
090f6abdd6282f48527b83162b8b441425f05e36vboxsync AssertPtrReturn(pfnCompleted, VERR_INVALID_POINTER);
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync AssertPtrReturn(ppTemplate, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Create the template.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync */
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = pdmR3AsyncCompletionTemplateCreate(pVM, &pTemplate, PDMASYNCCOMPLETIONTEMPLATETYPE_USB);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->u.Usb.pUsbIns = pUsbIns;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->u.Usb.pfnCompleted = pfnCompleted;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppTemplate = pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("PDM: Created usb template %p: pfnCompleted=%p pDevIns=%p\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate, pfnCompleted, pUsbIns));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Creates a async completion template for internally by the VMM.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The template is used when creating new completion tasks.
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync *
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ppTemplate Where to store the template pointer on success.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pfnCompleted The completion callback routine.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pvUser2 The 2nd user argument for the callback.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pszDesc Description.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateInternal(PVM pVM, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEINT pfnCompleted, void *pvUser2, const char *pszDesc)
0b65654be767b9fb7677181ddb434d8467f608e3vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("%s: ppTemplate=%p pfnCompleted=%p pvUser2=%p pszDesc=%s\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync __FUNCTION__, ppTemplate, pfnCompleted, pvUser2, pszDesc));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Validate input.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VM_ASSERT_EMT(pVM);
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync AssertPtrReturn(pfnCompleted, VERR_INVALID_POINTER);
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync AssertPtrReturn(ppTemplate, VERR_INVALID_POINTER);
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync /*
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync * Create the template.
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate;
f5395a2af3050ddd694b0ad505975f7b717ab4f1vboxsync int rc = pdmR3AsyncCompletionTemplateCreate(pVM, &pTemplate, PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL);
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync if (RT_SUCCESS(rc))
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->u.Int.pvUser = pvUser2;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->u.Int.pfnCompleted = pfnCompleted;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *ppTemplate = pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("PDM: Created internal template %p: pfnCompleted=%p pvUser2=%p\n",
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync pTemplate, pfnCompleted, pvUser2));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
332ccb6ac6feb4b50ec24d63ff029119164182ffvboxsync/**
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * Destroys the specified async completion template.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status codes:
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @retval VINF_SUCCESS on success.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if the template is still in use.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pTemplate The template in question.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroy(PPDMASYNCCOMPLETIONTEMPLATE pTemplate)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("%s: pTemplate=%p\n", __FUNCTION__, pTemplate));
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pTemplate)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("pTemplate is NULL!\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_INVALID_PARAMETER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Check if the template is still used.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pTemplate->cUsed > 0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("Template is still in use\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_PDM_ASYNC_TEMPLATE_BUSY;
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync /*
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * Unlink the template from the list.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PUVM pUVM = pTemplate->pVM->pUVM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTCritSectEnter(&pUVM->pdm.s.ListCritSect);
d45f7f7fe0c28b500b45b2dc88d7a04f4c0be6b8vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pPrev = pTemplate->pPrev;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pNext = pTemplate->pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pPrev)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPrev->pNext = pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync pUVM->pdm.s.pAsyncCompletionTemplates = pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pNext)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pNext->pPrev = pPrev;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync * Free the template.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MMR3HeapFree(pTemplate);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Destroys all the specified async completion templates for the given device instance.
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync *
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync * @returns VBox status codes:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @retval VINF_SUCCESS on success.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDevIns The device instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDevIns));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Validate input.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pDevIns)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_INVALID_PARAMETER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VM_ASSERT_EMT(pVM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * Unlink it.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PUVM pUVM = pVM->pUVM;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync RTCritSectEnter(&pUVM->pdm.s.ListCritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate = pUVM->pdm.s.pAsyncCompletionTemplates;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (pTemplate)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( pTemplate->enmType == PDMASYNCCOMPLETIONTEMPLATETYPE_DEV
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync && pTemplate->u.Dev.pDevIns == pDevIns)
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync {
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplateDestroy = pTemplate;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pTemplate = pTemplate->pNext;
04a471b98d492ee51b1f40424c7f90ddf44a90f0vboxsync int rc = PDMR3AsyncCompletionTemplateDestroy(pTemplateDestroy);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
bee1a7d4b183cab9654f247b3ea8cf680842bed5vboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync }
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync else
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync pTemplate = pTemplate->pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
96dce0123cc032388e78766d08f9ee5a66b80facvboxsync
96dce0123cc032388e78766d08f9ee5a66b80facvboxsync RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
96dce0123cc032388e78766d08f9ee5a66b80facvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * Destroys all the specified async completion templates for the given driver instance.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync *
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync * @returns VBox status codes:
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync * @retval VINF_SUCCESS on success.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pDrvIns The driver instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDrvIns));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * Validate input.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pDrvIns)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_INVALID_PARAMETER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VM_ASSERT_EMT(pVM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync /*
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync * Unlink it.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PUVM pUVM = pVM->pUVM;
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync RTCritSectEnter(&pUVM->pdm.s.ListCritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate = pUVM->pdm.s.pAsyncCompletionTemplates;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (pTemplate)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( pTemplate->enmType == PDMASYNCCOMPLETIONTEMPLATETYPE_DRV
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && pTemplate->u.Drv.pDrvIns == pDrvIns)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplateDestroy = pTemplate;
d45f7f7fe0c28b500b45b2dc88d7a04f4c0be6b8vboxsync pTemplate = pTemplate->pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = PDMR3AsyncCompletionTemplateDestroy(pTemplateDestroy);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_FAILURE(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate = pTemplate->pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync * Destroys all the specified async completion templates for the given USB device instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status codes:
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @retval VINF_SUCCESS on success.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pUsbIns The USB device instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns)
13d75a5db336ccb682d7ab28b397a4f0b8982ea3vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("%s: pUsbIns=%p\n", __FUNCTION__, pUsbIns));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Validate input.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pUsbIns)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_INVALID_PARAMETER;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VM_ASSERT_EMT(pVM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Unlink it.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PUVM pUVM = pVM->pUVM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTCritSectEnter(&pUVM->pdm.s.ListCritSect);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate = pUVM->pdm.s.pAsyncCompletionTemplates;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync while (pTemplate)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( pTemplate->enmType == PDMASYNCCOMPLETIONTEMPLATETYPE_USB
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync && pTemplate->u.Usb.pUsbIns == pUsbIns)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplateDestroy = pTemplate;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync pTemplate = pTemplate->pNext;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync int rc = PDMR3AsyncCompletionTemplateDestroy(pTemplateDestroy);
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync if (RT_FAILURE(rc))
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync {
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync return rc;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync }
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync }
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync else
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync pTemplate = pTemplate->pNext;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync }
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync return VINF_SUCCESS;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync}
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsyncstatic PPDMACBWMGR pdmacBwMgrFindById(PPDMASYNCCOMPLETIONEPCLASS pEpClass, const char *pcszId)
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMACBWMGR pBwMgr = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_VALID_PTR(pcszId))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = RTCritSectEnter(&pEpClass->CritSect); AssertRC(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBwMgr = pEpClass->pBwMgrsHead;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while ( pBwMgr
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && RTStrCmp(pBwMgr->pszId, pcszId))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBwMgr = pBwMgr->pNext;
ebe05ec36d1fcd24d62e7066dedcb4eb2e691358vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTCritSectLeave(&pEpClass->CritSect); AssertRC(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return pBwMgr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void pdmacBwMgrLink(PPDMACBWMGR pBwMgr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONEPCLASS pEpClass = pBwMgr->pEpClass;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = RTCritSectEnter(&pEpClass->CritSect); AssertRC(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pBwMgr->pNext = pEpClass->pBwMgrsHead;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEpClass->pBwMgrsHead = pBwMgr;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync rc = RTCritSectLeave(&pEpClass->CritSect); AssertRC(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync#ifdef SOME_UNUSED_FUNCTION
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void pdmacBwMgrUnlink(PPDMACBWMGR pBwMgr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync PPDMASYNCCOMPLETIONEPCLASS pEpClass = pBwMgr->pEpClass;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync int rc = RTCritSectEnter(&pEpClass->CritSect); AssertRC(rc);
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync if (pBwMgr == pEpClass->pBwMgrsHead)
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync pEpClass->pBwMgrsHead = pBwMgr->pNext;
0ebb1ef53864eb9cc97580f722288c9b29bc5d03vboxsync else
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMACBWMGR pPrev = pEpClass->pBwMgrsHead;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while ( pPrev
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && pPrev->pNext != pBwMgr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPrev = pPrev->pNext;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync AssertPtr(pPrev);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pPrev->pNext = pBwMgr->pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync rc = RTCritSectLeave(&pEpClass->CritSect); AssertRC(rc);
332ccb6ac6feb4b50ec24d63ff029119164182ffvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync#endif /* SOME_UNUSED_FUNCTION */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic int pdmacAsyncCompletionBwMgrCreate(PPDMASYNCCOMPLETIONEPCLASS pEpClass, const char *pcszBwMgr, uint32_t cbTransferPerSecMax,
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync uint32_t cbTransferPerSecStart, uint32_t cbTransferPerSecStep)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc(("pEpClass=%#p pcszBwMgr=%#p{%s} cbTransferPerSecMax=%u cbTransferPerSecStart=%u cbTransferPerSecStep=%u\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEpClass, pcszBwMgr, cbTransferPerSecMax, cbTransferPerSecStart, cbTransferPerSecStep));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pEpClass, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pcszBwMgr, VERR_INVALID_POINTER);
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync AssertReturn(*pcszBwMgr != '\0', VERR_INVALID_PARAMETER);
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMACBWMGR pBwMgr = pdmacBwMgrFindById(pEpClass, pcszBwMgr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pBwMgr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = MMR3HeapAllocZEx(pEpClass->pVM, MM_TAG_PDM_ASYNC_COMPLETION,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync sizeof(PDMACBWMGR),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (void **)&pBwMgr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync {
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync pBwMgr->pszId = RTStrDup(pcszBwMgr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pBwMgr->pszId)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBwMgr->pEpClass = pEpClass;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync pBwMgr->cRefs = 0;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Init I/O flow control. */
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync pBwMgr->cbTransferPerSecMax = cbTransferPerSecMax;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBwMgr->cbTransferPerSecStart = cbTransferPerSecStart;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBwMgr->cbTransferPerSecStep = cbTransferPerSecStep;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBwMgr->cbTransferAllowed = pBwMgr->cbTransferPerSecStart;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBwMgr->tsUpdatedLast = RTTimeSystemNanoTS();
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync pdmacBwMgrLink(pBwMgr);
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync rc = VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync rc = VERR_NO_MEMORY;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync MMR3HeapFree(pBwMgr);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VERR_ALREADY_EXISTS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc(("returns rc=%Rrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsyncDECLINLINE(void) pdmacBwMgrRef(PPDMACBWMGR pBwMgr)
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ASMAtomicIncU32(&pBwMgr->cRefs);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDECLINLINE(void) pdmacBwMgrUnref(PPDMACBWMGR pBwMgr)
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pBwMgr->cRefs > 0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ASMAtomicDecU32(&pBwMgr->cRefs);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsyncbool pdmacEpIsTransferAllowed(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint32_t cbTransfer, RTMSINTERVAL *pmsWhenNext)
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool fAllowed = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMACBWMGR pBwMgr = ASMAtomicReadPtrT(&pEndpoint->pBwMgr, PPDMACBWMGR);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync LogFlowFunc(("pEndpoint=%p pBwMgr=%p cbTransfer=%u\n", pEndpoint, pBwMgr, cbTransfer));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync if (pBwMgr)
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t cbOld = ASMAtomicSubU32(&pBwMgr->cbTransferAllowed, cbTransfer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_LIKELY(cbOld >= cbTransfer))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fAllowed = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fAllowed = false;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* We are out of resources Check if we can update again. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t tsNow = RTTimeSystemNanoTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t tsUpdatedLast = ASMAtomicUoReadU64(&pBwMgr->tsUpdatedLast);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (tsNow - tsUpdatedLast >= (1000*1000*1000))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (ASMAtomicCmpXchgU64(&pBwMgr->tsUpdatedLast, tsNow, tsUpdatedLast))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pBwMgr->cbTransferPerSecStart < pBwMgr->cbTransferPerSecMax)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pBwMgr->cbTransferPerSecStart = RT_MIN(pBwMgr->cbTransferPerSecMax, pBwMgr->cbTransferPerSecStart + pBwMgr->cbTransferPerSecStep);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("AIOMgr: Increasing maximum bandwidth to %u bytes/sec\n", pBwMgr->cbTransferPerSecStart));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync /* Update */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ASMAtomicWriteU32(&pBwMgr->cbTransferAllowed, pBwMgr->cbTransferPerSecStart - cbTransfer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fAllowed = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("AIOMgr: Refreshed bandwidth\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ASMAtomicAddU32(&pBwMgr->cbTransferAllowed, cbTransfer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *pmsWhenNext = ((1000*1000*1000) - (tsNow - tsUpdatedLast)) / (1000*1000);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync LogFlowFunc(("fAllowed=%RTbool\n", fAllowed));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return fAllowed;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, int rc, bool fCallCompletionHandler)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
1df4b0cdc5ec23d817014f9347ef28222b51e3fbvboxsync LogFlow(("%s: pTask=%#p fCallCompletionHandler=%RTbool\n", __FUNCTION__, pTask, fCallCompletionHandler));
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fCallCompletionHandler)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate = pTask->pEndpoint->pTemplate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
1df4b0cdc5ec23d817014f9347ef28222b51e3fbvboxsync switch (pTemplate->enmType)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync case PDMASYNCCOMPLETIONTEMPLATETYPE_DEV:
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync pTemplate->u.Dev.pfnCompleted(pTemplate->u.Dev.pDevIns, pTask->pvUser, rc);
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync break;
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync
9a0f1c40d078ffc54c3209648d12c70f36480067vboxsync case PDMASYNCCOMPLETIONTEMPLATETYPE_DRV:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->u.Drv.pfnCompleted(pTemplate->u.Drv.pDrvIns, pTemplate->u.Drv.pvTemplateUser, pTask->pvUser, rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case PDMASYNCCOMPLETIONTEMPLATETYPE_USB:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->u.Usb.pfnCompleted(pTemplate->u.Usb.pUsbIns, pTask->pvUser, rc);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTemplate->u.Int.pfnCompleted(pTemplate->pVM, pTask->pvUser, pTemplate->u.Int.pvUser, rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("Unknown template type!\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pdmR3AsyncCompletionPutTask(pTask->pEndpoint, pTask);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Worker initializing a endpoint class.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM instance data.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pEpClass Pointer to the endpoint class structure.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @param pCfgHandle Pointer to the the CFGM tree.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsyncint pdmR3AsyncCompletionEpClassInit(PVM pVM, PCPDMASYNCCOMPLETIONEPCLASSOPS pEpClassOps, PCFGMNODE pCfgHandle)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Validate input. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pEpClassOps, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(pEpClassOps->u32Version == PDMAC_EPCLASS_OPS_VERSION, VERR_VERSION_MISMATCH);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AssertReturn(pEpClassOps->u32VersionEnd == PDMAC_EPCLASS_OPS_VERSION, VERR_VERSION_MISMATCH);
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync LogFlowFunc((": pVM=%p pEpClassOps=%p{%s}\n", pVM, pEpClassOps, pEpClassOps->pcszName));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /* Allocate global class data. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = NULL;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_ASYNC_COMPLETION,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEpClassOps->cbEndpointClassGlobal,
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync (void **)&pEndpointClass);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Initialize common data. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpointClass->pVM = pVM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpointClass->pEndpointOps = pEpClassOps;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTCritSectInit(&pEndpointClass->CritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync {
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync PCFGMNODE pCfgNodeClass = CFGMR3GetChild(pCfgHandle, pEpClassOps->pcszName);
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync /* Create task cache */
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync rc = RTMemCacheCreate(&pEndpointClass->hMemCacheTasks, pEpClassOps->cbTask,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync 0, UINT32_MAX, NULL, NULL, NULL, 0);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Call the specific endpoint class initializer. */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync rc = pEpClassOps->pfnInitialize(pEndpointClass, pCfgNodeClass);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Create all bandwidth groups for resource control. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PCFGMNODE pCfgBwGrp = CFGMR3GetChild(pCfgNodeClass, "BwGroups");
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pCfgBwGrp)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (PCFGMNODE pCur = CFGMR3GetFirstChild(pCfgBwGrp); pCur; pCur = CFGMR3GetNextChild(pCur))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync uint32_t cbMax, cbStart, cbStep;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync size_t cchName = CFGMR3GetNameLen(pCur) + 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync char *pszBwGrpId = (char *)RTMemAllocZ(cchName);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!pszBwGrpId)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = VERR_NO_MEMORY;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = CFGMR3GetName(pCur, pszBwGrpId, cchName);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertRC(rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = CFGMR3QueryU32(pCur, "Max", &cbMax);
ab0130d1627b2b214952b929de71b89e4ba41eb1vboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = CFGMR3QueryU32Def(pCur, "Start", &cbStart, cbMax);
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync if (RT_SUCCESS(rc))
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync rc = CFGMR3QueryU32Def(pCur, "Step", &cbStep, 0);
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = pdmacAsyncCompletionBwMgrCreate(pEndpointClass, pszBwGrpId, cbMax, cbStart, cbStep);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync RTMemFree(pszBwGrpId);
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync if (RT_FAILURE(rc))
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync break;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync if (RT_SUCCESS(rc))
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync {
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync PUVM pUVM = pVM->pUVM;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync AssertMsg(!pUVM->pdm.s.apAsyncCompletionEndpointClass[pEpClassOps->enmClassType],
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync ("Endpoint class was already initialized\n"));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync pUVM->pdm.s.apAsyncCompletionEndpointClass[pEpClassOps->enmClassType] = pEndpointClass;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync LogFlowFunc((": Initialized endpoint class \"%s\" rc=%Rrc\n", pEpClassOps->pcszName, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync }
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync }
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync RTMemCacheDestroy(pEndpointClass->hMemCacheTasks);
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync }
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync RTCritSectDelete(&pEndpointClass->CritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync MMR3HeapFree(pEndpointClass);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc((": Failed to initialize endpoint class rc=%Rrc\n", rc));
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync}
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync/**
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync * Worker terminating all endpoint classes.
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns nothing
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pEndpointClass Pointer to the endpoint class to terminate.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync *
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * @remarks This method ensures that any still open endpoint is closed.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void pdmR3AsyncCompletionEpClassTerminate(PPDMASYNCCOMPLETIONEPCLASS pEndpointClass)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PVM pVM = pEndpointClass->pVM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Close all still open endpoints. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (pEndpointClass->pEndpointsHead)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDMR3AsyncCompletionEpClose(pEndpointClass->pEndpointsHead);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Destroy the bandwidth managers. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMACBWMGR pBwMgr = pEndpointClass->pBwMgrsHead;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (pBwMgr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync PPDMACBWMGR pFree = pBwMgr;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync pBwMgr = pBwMgr->pNext;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync MMR3HeapFree(pFree);
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Call the termination callback of the class. */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync pEndpointClass->pEndpointOps->pfnTerminate(pEndpointClass);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTMemCacheDestroy(pEndpointClass->hMemCacheTasks);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTCritSectDelete(&pEndpointClass->CritSect);
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Free the memory of the class finally and clear the entry in the class array. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[pEndpointClass->pEndpointOps->enmClassType] = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MMR3HeapFree(pEndpointClass);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initialize the async completion manager.
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint pdmR3AsyncCompletionInit(PVM pVM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc((": pVM=%p\n", pVM));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VM_ASSERT_EMT(pVM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PCFGMNODE pCfgRoot = CFGMR3GetRoot(pVM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PCFGMNODE pCfgAsyncCompletion = CFGMR3GetChild(CFGMR3GetChild(pCfgRoot, "PDM"), "AsyncCompletion");
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = pdmR3AsyncCompletionEpClassInit(pVM, &g_PDMAsyncCompletionEndpointClassFile, pCfgAsyncCompletion);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc((": pVM=%p rc=%Rrc\n", pVM, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Terminates the async completion manager.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM Pointer to the shared VM structure.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint pdmR3AsyncCompletionTerm(PVM pVM)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc((": pVM=%p\n", pVM));
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync PUVM pUVM = pVM->pUVM;
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync for (size_t i = 0; i < RT_ELEMENTS(pUVM->pdm.s.apAsyncCompletionEndpointClass); i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pUVM->pdm.s.apAsyncCompletionEndpointClass[i])
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pdmR3AsyncCompletionEpClassTerminate(pUVM->pdm.s.apAsyncCompletionEndpointClass[i]);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * Resume worker for the async completion manager.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns nothing.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @param pVM Pointer to the shared VM structure.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid pdmR3AsyncCompletionResume(PVM pVM)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc((": pVM=%p\n", pVM));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PUVM pUVM = pVM->pUVM;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Log the bandwidth groups and all assigned endpoints. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (size_t i = 0; i < RT_ELEMENTS(pUVM->pdm.s.apAsyncCompletionEndpointClass); i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pUVM->pdm.s.apAsyncCompletionEndpointClass[i])
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync {
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync PPDMASYNCCOMPLETIONEPCLASS pEpClass = pUVM->pdm.s.apAsyncCompletionEndpointClass[i];
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync PPDMACBWMGR pBwMgr = pEpClass->pBwMgrsHead;
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync PPDMASYNCCOMPLETIONENDPOINT pEp;
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync
0f8b9243304469cd1e58d6986931bbfed5ba359evboxsync if (pBwMgr)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("AIOMgr: Bandwidth groups for class '%s'\n", i == PDMASYNCCOMPLETIONEPCLASSTYPE_FILE
be9bc9b4ba510c4b4159c193f783d024633ef8e9vboxsync ? "File" : "<Unknown>"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (pBwMgr)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("AIOMgr: Id: %s\n", pBwMgr->pszId));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("AIOMgr: Max: %u B/s\n", pBwMgr->cbTransferPerSecMax));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("AIOMgr: Start: %u B/s\n", pBwMgr->cbTransferPerSecStart));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("AIOMgr: Step: %u B/s\n", pBwMgr->cbTransferPerSecStep));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("AIOMgr: Endpoints:\n"));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync pEp = pEpClass->pEndpointsHead;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync while (pEp)
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync {
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync if (pEp->pBwMgr == pBwMgr)
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel(("AIOMgr: %s\n", pEp->pszUri));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync pEp = pEp->pNext;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync pBwMgr = pBwMgr->pNext;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync /* Print all endpoints without assigned bandwidth groups. */
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync pEp = pEpClass->pEndpointsHead;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync if (pEp)
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync LogRel(("AIOMgr: Endpoints without assigned bandwidth groups:\n"));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync while (pEp)
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync {
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync if (!pEp->pBwMgr)
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync LogRel(("AIOMgr: %s\n", pEp->pszUri));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync pEp = pEp->pNext;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync}
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync/**
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync * Tries to get a free task from the endpoint or class cache
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync * allocating the task if it fails.
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync *
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync * @returns Pointer to a new and initialized task or NULL
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync * @param pEndpoint The endpoint the task is for.
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync * @param pvUser Opaque user data for the task.
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync */
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsyncstatic PPDMASYNCCOMPLETIONTASK pdmR3AsyncCompletionGetTask(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, void *pvUser)
1f24d758b35a86f1075a86a4760da9bbc1e80229vboxsync{
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync PPDMASYNCCOMPLETIONTASK pTask = (PPDMASYNCCOMPLETIONTASK)RTMemCacheAlloc(pEndpointClass->hMemCacheTasks);
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync if (RT_LIKELY(pTask))
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync {
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync /* Initialize common parts. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTask->pvUser = pvUser;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTask->pEndpoint = pEndpoint;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Clear list pointers for safety. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTask->pPrev = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTask->pNext = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pTask->tsNsStart = RTTimeNanoTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_WITH_STATISTICS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAM_COUNTER_INC(&pEndpoint->StatIoOpsStarted);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
e11fe099decbb0f65cfcc7e2939fa00bacefbb1cvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return pTask;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * Puts a task in one of the caches.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @returns nothing.
96dce0123cc032388e78766d08f9ee5a66b80facvboxsync * @param pEndpoint The endpoint the task belongs to.
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync * @param pTask The task to cache.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void pdmR3AsyncCompletionPutTask(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, PPDMASYNCCOMPLETIONTASK pTask)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass;
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync uint64_t cNsRun = RTTimeNanoTS() - pTask->tsNsStart;
9f16100a870e25701da9bc9819e15c0f9fb3870evboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (RT_UNLIKELY(cNsRun >= RT_NS_10SEC))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogRel(("AsyncCompletion: Task %#p completed after %llu seconds\n", pTask, cNsRun / RT_NS_1SEC));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync#ifdef VBOX_WITH_STATISTICS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PSTAMCOUNTER pStatCounter;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (cNsRun < RT_NS_1US)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pStatCounter = &pEndpoint->StatTaskRunTimesNs[cNsRun / (RT_NS_1US / 10)];
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync else if (cNsRun < RT_NS_1MS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pStatCounter = &pEndpoint->StatTaskRunTimesUs[cNsRun / (RT_NS_1MS / 10)];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if (cNsRun < RT_NS_1SEC)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pStatCounter = &pEndpoint->StatTaskRunTimesMs[cNsRun / (RT_NS_1SEC / 10)];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if (cNsRun < RT_NS_1SEC_64*100)
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync pStatCounter = &pEndpoint->StatTaskRunTimesSec[cNsRun / (RT_NS_1SEC_64*100 / 10)];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pStatCounter = &pEndpoint->StatTaskRunOver100Sec;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAM_COUNTER_INC(pStatCounter);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAM_COUNTER_INC(&pEndpoint->StatIoOpsCompleted);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpoint->cIoOpsCompleted++;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t tsMsCur = RTTimeMilliTS();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t tsInterval = tsMsCur - pEndpoint->tsIntervalStartMs;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if (tsInterval >= 1000)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpoint->StatIoOpsPerSec.c = pEndpoint->cIoOpsCompleted / (tsInterval / 1000);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync pEndpoint->tsIntervalStartMs = tsMsCur;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpoint->cIoOpsCompleted = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* VBOX_WITH_STATISTICS */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTMemCacheFree(pEndpointClass->hMemCacheTasks, pTask);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsyncstatic PPDMASYNCCOMPLETIONENDPOINT pdmR3AsyncCompletionFindEndpointWithUri(PPDMASYNCCOMPLETIONEPCLASS pEndpointClass,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *pszUri)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONENDPOINT pEndpoint = pEndpointClass->pEndpointsHead;
d99197f8edcfa672509d9418fa6441c0c66af33cvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync while (pEndpoint)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d99197f8edcfa672509d9418fa6441c0c66af33cvboxsync if (!RTStrCmp(pEndpoint->pszUri, pszUri))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return pEndpoint;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpoint = pEndpoint->pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT ppEndpoint,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const char *pszFilename, uint32_t fFlags,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONTEMPLATE pTemplate)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowFunc((": ppEndpoint=%p pszFilename=%p{%s} fFlags=%u pTemplate=%p\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ppEndpoint, pszFilename, pszFilename, fFlags, pTemplate));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync /* Sanity checks. */
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync AssertPtrReturn(ppEndpoint, VERR_INVALID_POINTER);
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pTemplate, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Check that the flags are valid. */
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync AssertReturn(((~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_DONT_LOCK | PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED) & fFlags) == 0),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VERR_INVALID_PARAMETER);
22408fe91738075b3c413b14a421d641aacad508vboxsync
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync PVM pVM = pTemplate->pVM;
22408fe91738075b3c413b14a421d641aacad508vboxsync PUVM pUVM = pVM->pUVM;
22408fe91738075b3c413b14a421d641aacad508vboxsync PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];
94f9530895973c2a15ee8da2442cd600fd91d4d7vboxsync PPDMASYNCCOMPLETIONENDPOINT pEndpoint = NULL;
22408fe91738075b3c413b14a421d641aacad508vboxsync
22408fe91738075b3c413b14a421d641aacad508vboxsync AssertMsg(pEndpointClass, ("File endpoint class was not initialized\n"));
22408fe91738075b3c413b14a421d641aacad508vboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /* Search for a already opened endpoint for this file. */
c279ef9298ff04e966225aa896bc7010562820b5vboxsync pEndpoint = pdmR3AsyncCompletionFindEndpointWithUri(pEndpointClass, pszFilename);
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync if (pEndpoint)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /* Endpoint found. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pEndpoint->cUsers++;
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync *ppEndpoint = pEndpoint;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Create an endpoint. */
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_ASYNC_COMPLETION,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pEndpointClass->pEndpointOps->cbEndpoint,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (void **)&pEndpoint);
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if (RT_SUCCESS(rc))
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /* Initialize common parts. */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pEndpoint->pNext = NULL;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pEndpoint->pPrev = NULL;
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync pEndpoint->pEpClass = pEndpointClass;
94f9530895973c2a15ee8da2442cd600fd91d4d7vboxsync pEndpoint->pTemplate = pTemplate;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pEndpoint->pszUri = RTStrDup(pszFilename);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpoint->cUsers = 1;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pEndpoint->pBwMgr = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if ( pEndpoint->pszUri
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && RT_SUCCESS(rc))
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync {
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync /* Call the initializer for the endpoint. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = pEndpointClass->pEndpointOps->pfnEpInitialize(pEndpoint, pszFilename, fFlags);
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync if (RT_SUCCESS(rc))
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync {
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync /* Link it into the list of endpoints. */
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync rc = RTCritSectEnter(&pEndpointClass->CritSect);
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc));
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync pEndpoint->pNext = pEndpointClass->pEndpointsHead;
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync if (pEndpointClass->pEndpointsHead)
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync pEndpointClass->pEndpointsHead->pPrev = pEndpoint;
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpointClass->pEndpointsHead = pEndpoint;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pEndpointClass->cEndpoints++;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync rc = RTCritSectLeave(&pEndpointClass->CritSect);
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc));
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /* Reference the template. */
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync ASMAtomicIncU32(&pTemplate->cUsed);
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync#ifdef VBOX_WITH_STATISTICS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Init the statistics part */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs); i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesNs[i], STAMTYPE_COUNTER,
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync STAMVISIBILITY_USED,
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync STAMUNIT_OCCURENCES,
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync "Nanosecond resolution runtime statistics",
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync "/PDM/AsyncCompletion/File/%s/TaskRun1Ns-%u-%u",
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync RTPathFilename(pEndpoint->pszUri),
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync i*100, i*100+100-1);
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync if (RT_FAILURE(rc))
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync break;
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync }
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync if (RT_SUCCESS(rc))
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs); i++)
352f5cf617a287b8a3ca2fbe1f23afe258874ce9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesUs[i], STAMTYPE_COUNTER,
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync STAMVISIBILITY_USED,
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync STAMUNIT_OCCURENCES,
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync "Microsecond resolution runtime statistics",
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync "/PDM/AsyncCompletion/File/%s/TaskRun2MicroSec-%u-%u",
22408fe91738075b3c413b14a421d641aacad508vboxsync RTPathFilename(pEndpoint->pszUri),
22408fe91738075b3c413b14a421d641aacad508vboxsync i*100, i*100+100-1);
22408fe91738075b3c413b14a421d641aacad508vboxsync if (RT_FAILURE(rc))
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync break;
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync }
22408fe91738075b3c413b14a421d641aacad508vboxsync }
22408fe91738075b3c413b14a421d641aacad508vboxsync
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesMs[i], STAMTYPE_COUNTER,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAMVISIBILITY_USED,
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync STAMUNIT_OCCURENCES,
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync "Milliseconds resolution runtime statistics",
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync "/PDM/AsyncCompletion/File/%s/TaskRun3Ms-%u-%u",
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync RTPathFilename(pEndpoint->pszUri),
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync i*100, i*100+100-1);
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync if (RT_FAILURE(rc))
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync break;
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync }
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunTimesSec[i], STAMTYPE_COUNTER,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync STAMVISIBILITY_USED,
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync STAMUNIT_OCCURENCES,
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync "Second resolution runtime statistics",
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync "/PDM/AsyncCompletion/File/%s/TaskRun4Sec-%u-%u",
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync RTPathFilename(pEndpoint->pszUri),
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync i*10, i*10+10-1);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync if (RT_FAILURE(rc))
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync break;
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync }
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync }
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if (RT_SUCCESS(rc))
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = STAMR3RegisterF(pVM, &pEndpoint->StatTaskRunOver100Sec, STAMTYPE_COUNTER,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAMVISIBILITY_USED,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync STAMUNIT_OCCURENCES,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync "Tasks which ran more than 100sec",
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync "/PDM/AsyncCompletion/File/%s/TaskRunSecGreater100Sec",
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync RTPathFilename(pEndpoint->pszUri));
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync }
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if (RT_SUCCESS(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsPerSec, STAMTYPE_COUNTER,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync STAMVISIBILITY_ALWAYS,
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync STAMUNIT_OCCURENCES,
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync "Processed I/O operations per second",
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync "/PDM/AsyncCompletion/File/%s/IoOpsPerSec",
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync RTPathFilename(pEndpoint->pszUri));
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if (RT_SUCCESS(rc))
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync {
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsStarted, STAMTYPE_COUNTER,
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync STAMVISIBILITY_ALWAYS,
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync STAMUNIT_OCCURENCES,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync "Started I/O operations for this endpoint",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "/PDM/AsyncCompletion/File/%s/IoOpsStarted",
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync RTPathFilename(pEndpoint->pszUri));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync }
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync if (RT_SUCCESS(rc))
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = STAMR3RegisterF(pVM, &pEndpoint->StatIoOpsCompleted, STAMTYPE_COUNTER,
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync STAMVISIBILITY_ALWAYS,
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync STAMUNIT_OCCURENCES,
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync "Completed I/O operations for this endpoint",
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync "/PDM/AsyncCompletion/File/%s/IoOpsCompleted",
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync RTPathFilename(pEndpoint->pszUri));
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync /** @todo why bother maintaing rc when it's just ignored /
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync logged and not returned? */
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pEndpoint->tsIntervalStartMs = RTTimeMilliTS();
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync#endif
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync *ppEndpoint = pEndpoint;
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync LogFlowFunc((": Created endpoint for %s: rc=%Rrc\n", pszFilename, rc));
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync return VINF_SUCCESS;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync RTStrFree(pEndpoint->pszUri);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync MMR3HeapFree(pEndpoint);
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync }
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync LogFlowFunc((": Creation of endpoint for %s failed: rc=%Rrc\n", pszFilename, rc));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync return rc;
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync}
ebf9e36b6e5548e4db69cebbef120e669a459afevboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncVMMR3DECL(void) PDMR3AsyncCompletionEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync{
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync LogFlowFunc((": pEndpoint=%p\n", pEndpoint));
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /* Sanity checks. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturnVoid(VALID_PTR(pEndpoint));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pEndpoint->cUsers--;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /* If the last user closed the endpoint we will free it. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if (!pEndpoint->cUsers)
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync {
94f9530895973c2a15ee8da2442cd600fd91d4d7vboxsync PPDMASYNCCOMPLETIONEPCLASS pEndpointClass = pEndpoint->pEpClass;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pEndpointClass->pEndpointOps->pfnEpClose(pEndpoint);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Drop reference from the template. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ASMAtomicDecU32(&pEndpoint->pTemplate->cUsed);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Unlink the endpoint from the list. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = RTCritSectEnter(&pEndpointClass->CritSect);
47b5427d1a541bcd269bc625c35b19d849071edfvboxsync AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMASYNCCOMPLETIONENDPOINT pEndpointNext = pEndpoint->pNext;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync PPDMASYNCCOMPLETIONENDPOINT pEndpointPrev = pEndpoint->pPrev;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pEndpointPrev)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpointPrev->pNext = pEndpointNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pEndpointClass->pEndpointsHead = pEndpointNext;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync if (pEndpointNext)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pEndpointNext->pPrev = pEndpointPrev;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pEndpointClass->cEndpoints--;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTCritSectLeave(&pEndpointClass->CritSect);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsg(RT_SUCCESS(rc), ("Failed to enter critical section rc=%Rrc\n", rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync#ifdef VBOX_WITH_STATISTICS
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync /* Deregister the statistics part */
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync PVM pVM = pEndpointClass->pVM;
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesNs); i++)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesNs[i]);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesUs); i++)
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesUs[i]);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++)
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesMs[i]);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync for (unsigned i = 0; i < RT_ELEMENTS(pEndpoint->StatTaskRunTimesMs); i++)
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync STAMR3Deregister(pVM, &pEndpoint->StatTaskRunTimesSec[i]);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync STAMR3Deregister(pVM, &pEndpoint->StatTaskRunOver100Sec);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync STAMR3Deregister(pVM, &pEndpoint->StatIoOpsPerSec);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync STAMR3Deregister(pVM, &pEndpoint->StatIoOpsStarted);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync STAMR3Deregister(pVM, &pEndpoint->StatIoOpsCompleted);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync#endif
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync RTStrFree(pEndpoint->pszUri);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync MMR3HeapFree(pEndpoint);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync }
3f1e0eea71cabeb90529e546f16eb7aee513fde9vboxsync}
ed5875886aed64570809cf39f881a0fcb93f44a7vboxsync
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionEpRead(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync PCRTSGSEG paSegments, unsigned cSegments,
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync size_t cbRead, void *pvUser,
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync PPPDMASYNCCOMPLETIONTASK ppTask)
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync{
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync AssertPtrReturn(pEndpoint, VERR_INVALID_POINTER);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync AssertPtrReturn(paSegments, VERR_INVALID_POINTER);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync AssertPtrReturn(ppTask, VERR_INVALID_POINTER);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync AssertReturn(cSegments > 0, VERR_INVALID_PARAMETER);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync AssertReturn(cbRead > 0, VERR_INVALID_PARAMETER);
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync AssertReturn(off >= 0, VERR_INVALID_PARAMETER);
ed5875886aed64570809cf39f881a0fcb93f44a7vboxsync
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync PPDMASYNCCOMPLETIONTASK pTask;
d2c6b2e8826a5ef34170fef0c72c3fc7c5c1b46avboxsync
51afd9e19409617e8f3a204d58e96e22ee618e57vboxsync pTask = pdmR3AsyncCompletionGetTask(pEndpoint, pvUser);
ed5875886aed64570809cf39f881a0fcb93f44a7vboxsync if (!pTask)
94f9530895973c2a15ee8da2442cd600fd91d4d7vboxsync return VERR_NO_MEMORY;
51afd9e19409617e8f3a204d58e96e22ee618e57vboxsync
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync int rc = pEndpoint->pEpClass->pEndpointOps->pfnEpRead(pTask, pEndpoint, off,
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync paSegments, cSegments, cbRead);
ed5875886aed64570809cf39f881a0fcb93f44a7vboxsync if (RT_SUCCESS(rc))
8bc010ff67963900f9c39d93ce1a64a4e1c08ba1vboxsync *ppTask = pTask;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync pdmR3AsyncCompletionPutTask(pEndpoint, pTask);
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync return rc;
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync}
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync
e131925debcc0add6ebecf92e6d09d62150476a4vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionEpWrite(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync PCRTSGSEG paSegments, unsigned cSegments,
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync size_t cbWrite, void *pvUser,
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync PPPDMASYNCCOMPLETIONTASK ppTask)
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync{
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync AssertPtrReturn(pEndpoint, VERR_INVALID_POINTER);
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync AssertPtrReturn(paSegments, VERR_INVALID_POINTER);
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync AssertPtrReturn(ppTask, VERR_INVALID_POINTER);
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync AssertReturn(cSegments > 0, VERR_INVALID_PARAMETER);
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync AssertReturn(cbWrite > 0, VERR_INVALID_PARAMETER);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync AssertReturn(off >= 0, VERR_INVALID_PARAMETER);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync PPDMASYNCCOMPLETIONTASK pTask;
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync pTask = pdmR3AsyncCompletionGetTask(pEndpoint, pvUser);
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync if (!pTask)
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync return VERR_NO_MEMORY;
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsync int rc = pEndpoint->pEpClass->pEndpointOps->pfnEpWrite(pTask, pEndpoint, off,
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync paSegments, cSegments, cbWrite);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync if (RT_SUCCESS(rc))
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync {
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync *ppTask = pTask;
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync }
22408fe91738075b3c413b14a421d641aacad508vboxsync else
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync pdmR3AsyncCompletionPutTask(pEndpoint, pTask);
22408fe91738075b3c413b14a421d641aacad508vboxsync
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync return rc;
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync}
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionEpFlush(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync void *pvUser,
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync PPPDMASYNCCOMPLETIONTASK ppTask)
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync{
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync AssertPtrReturn(pEndpoint, VERR_INVALID_POINTER);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync AssertPtrReturn(ppTask, VERR_INVALID_POINTER);
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync PPDMASYNCCOMPLETIONTASK pTask;
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync pTask = pdmR3AsyncCompletionGetTask(pEndpoint, pvUser);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync if (!pTask)
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync return VERR_NO_MEMORY;
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync int rc = pEndpoint->pEpClass->pEndpointOps->pfnEpFlush(pTask, pEndpoint);
5ae72b1f28e1d602e74d89e79e43778c9fc18203vboxsync if (RT_SUCCESS(rc))
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync *ppTask = pTask;
5ae72b1f28e1d602e74d89e79e43778c9fc18203vboxsync else
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync pdmR3AsyncCompletionPutTask(pEndpoint, pTask);
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync return rc;
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync}
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync
e131925debcc0add6ebecf92e6d09d62150476a4vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionEpGetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync uint64_t *pcbSize)
e131925debcc0add6ebecf92e6d09d62150476a4vboxsync{
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync AssertPtrReturn(pEndpoint, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pEndpoint->pEpClass->pEndpointOps->pfnEpGetSize)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return pEndpoint->pEpClass->pEndpointOps->pfnEpGetSize(pEndpoint, pcbSize);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VERR_NOT_SUPPORTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVMMR3DECL(int) PDMR3AsyncCompletionEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint64_t cbSize)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
ed5875886aed64570809cf39f881a0fcb93f44a7vboxsync AssertPtrReturn(pEndpoint, VERR_INVALID_POINTER);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
22408fe91738075b3c413b14a421d641aacad508vboxsync if (pEndpoint->pEpClass->pEndpointOps->pfnEpSetSize)
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync return pEndpoint->pEpClass->pEndpointOps->pfnEpSetSize(pEndpoint, cbSize);
22408fe91738075b3c413b14a421d641aacad508vboxsync return VERR_NOT_SUPPORTED;
22408fe91738075b3c413b14a421d641aacad508vboxsync}
22408fe91738075b3c413b14a421d641aacad508vboxsync
22408fe91738075b3c413b14a421d641aacad508vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionEpSetBwMgr(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
22408fe91738075b3c413b14a421d641aacad508vboxsync const char *pcszBwMgr)
e41f0459369a6d814aa36bf4def225482fc56026vboxsync{
e41f0459369a6d814aa36bf4def225482fc56026vboxsync AssertPtrReturn(pEndpoint, VERR_INVALID_POINTER);
e41f0459369a6d814aa36bf4def225482fc56026vboxsync PPDMACBWMGR pBwMgrOld = NULL;
22408fe91738075b3c413b14a421d641aacad508vboxsync PPDMACBWMGR pBwMgrNew = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pcszBwMgr)
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync {
22408fe91738075b3c413b14a421d641aacad508vboxsync pBwMgrNew = pdmacBwMgrFindById(pEndpoint->pEpClass, pcszBwMgr);
22408fe91738075b3c413b14a421d641aacad508vboxsync if (pBwMgrNew)
22408fe91738075b3c413b14a421d641aacad508vboxsync pdmacBwMgrRef(pBwMgrNew);
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync else
22408fe91738075b3c413b14a421d641aacad508vboxsync rc = VERR_NOT_FOUND;
22408fe91738075b3c413b14a421d641aacad508vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync if (RT_SUCCESS(rc))
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync {
22408fe91738075b3c413b14a421d641aacad508vboxsync pBwMgrOld = ASMAtomicXchgPtrT(&pEndpoint->pBwMgr, pBwMgrNew, PPDMACBWMGR);
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync if (pBwMgrOld)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pdmacBwMgrUnref(pBwMgrOld);
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
22408fe91738075b3c413b14a421d641aacad508vboxsync
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionTaskCancel(PPDMASYNCCOMPLETIONTASK pTask)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync return VERR_NOT_IMPLEMENTED;
323b78bf4831666c95416edf3b6e54657a769e5dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsyncVMMR3DECL(int) PDMR3AsyncCompletionBwMgrSetMaxForFile(PVM pVM, const char *pcszBwMgr, uint32_t cbMaxNew)
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync{
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync AssertPtrReturn(pVM, VERR_INVALID_POINTER);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync AssertPtrReturn(pcszBwMgr, VERR_INVALID_POINTER);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync int rc = VINF_SUCCESS;
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync PPDMASYNCCOMPLETIONEPCLASS pEpClass = pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync PPDMACBWMGR pBwMgr = pdmacBwMgrFindById(pEpClass, pcszBwMgr);
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync if (pBwMgr)
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync {
188ea1a2ae27e2575ff4361c41b368f29128a8c5vboxsync /*
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync * Set the new value for the start and max value to let the manager pick up
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync * the new limit immediately.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ASMAtomicXchgU32(&pBwMgr->cbTransferPerSecMax, cbMaxNew);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ASMAtomicXchgU32(&pBwMgr->cbTransferPerSecStart, cbMaxNew);
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync }
22408fe91738075b3c413b14a421d641aacad508vboxsync else
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync rc = VERR_NOT_FOUND;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
3242fe628b2306c050fb28c489d50bc63118f0c5vboxsync
afa761a969c8883e5ea370e898d40ce053fbcb22vboxsync