PDMQueue.cpp revision e9e3e0dde7d0aa3a9f0aa54638a613dbf1736408
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * PDM Queue - Transport data and tasks to EMT and R3.
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * available from http://www.virtualbox.org. This file is free software;
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * General Public License (GPL) as published by the Free Software
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync * additional information or have any questions.
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync/*******************************************************************************
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync* Header Files *
344115a50dfcaf97123d38b056161195a7e4e48cvboxsync*******************************************************************************/
* @param fRZEnabled Set if the queue will be used from RC/R0 and need to be allocated from the hyper heap.
static int pdmR3QueueCreate(PVM pVM, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, bool fRZEnabled, PPDMQUEUE *ppQueue)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
size_t cb = cbItem * cItems + RT_ALIGN_Z(RT_OFFSETOF(PDMQUEUE, aFreeItems[cItems + PDMQUEUE_FREE_SLACK]), 16);
int rc;
if (fRZEnabled)
return rc;
PPDMQUEUEITEMCORE pItem = (PPDMQUEUEITEMCORE)((char *)pQueue + RT_ALIGN_Z(RT_OFFSETOF(PDMQUEUE, aFreeItems[cItems + PDMQUEUE_FREE_SLACK]), 16));
if (fRZEnabled)
if (cMilliesInterval)
int rc = TMR3TimerCreateInternal(pVM, TMCLOCK_REAL, pdmR3QueueTimer, pQueue, "Queue timer", &pQueue->pTimer);
if (fRZEnabled)
return rc;
return VINF_SUCCESS;
VMMR3DECL(int) PDMR3QueueCreateDevice(PVM pVM, PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
LogFlow(("PDMR3QueueCreateDevice: pDevIns=%p cbItem=%d cItems=%d cMilliesInterval=%d pfnCallback=%p fRZEnabled=%RTbool\n",
if (!pfnCallback)
return VERR_INVALID_PARAMETER;
return rc;
VMMR3DECL(int) PDMR3QueueCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
LogFlow(("PDMR3QueueCreateDriver: pDrvIns=%p cbItem=%d cItems=%d cMilliesInterval=%d pfnCallback=%p\n",
if (!pfnCallback)
return VERR_INVALID_PARAMETER;
return rc;
VMMR3DECL(int) PDMR3QueueCreateInternal(PVM pVM, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
LogFlow(("PDMR3QueueCreateInternal: cbItem=%d cItems=%d cMilliesInterval=%d pfnCallback=%p fRZEnabled=%RTbool\n",
if (!pfnCallback)
return VERR_INVALID_PARAMETER;
return rc;
VMMR3DECL(int) PDMR3QueueCreateExternal(PVM pVM, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval, PFNPDMQUEUEEXT pfnCallback, void *pvUser, PPDMQUEUE *ppQueue)
LogFlow(("PDMR3QueueCreateExternal: cbItem=%d cItems=%d cMilliesInterval=%d pfnCallback=%p\n", cbItem, cItems, cMilliesInterval, pfnCallback));
if (!pfnCallback)
return VERR_INVALID_PARAMETER;
return rc;
if (!pQueue)
return VERR_INVALID_PARAMETER;
while (pCur)
while (pCur)
return VINF_SUCCESS;
if (!pDevIns)
return VERR_INVALID_PARAMETER;
while (pQueue)
} while (pQueue);
return VINF_SUCCESS;
if (!pDrvIns)
return VERR_INVALID_PARAMETER;
while (pQueue)
} while (pQueue);
return VINF_SUCCESS;
while (pQueue)
} while (pQueue);
/* Prevent other VCPUs from flushing queues at the same time; we'll never flush an item twice, but the order might change. */
goto check_queue;
PPDMQUEUEITEMCORE pItems = (PPDMQUEUEITEMCORE)ASMAtomicXchgPtr((void * volatile *)&pQueue->pPendingR3, NULL);
if ( !pItems
&& !pItemsRC
&& !pItemsR0)
while (pCur)
while (pItemsRC)
while (pItemsR0)
case PDMQUEUETYPE_DEV:
while (pItems)
case PDMQUEUETYPE_DRV:
while (pItems)
case PDMQUEUETYPE_INTERNAL:
while (pItems)
case PDMQUEUETYPE_EXTERNAL:
while (pItems)
if (pItems)
while (pCur)
if ( !pQueue