VDIoBackendMem.cpp revision 14a9673ef19f6d8d49f83050d86cb444a55d4008
/** $Id$ */
/** @file
*
* VBox HDD container test utility, async I/O memory backend
*/
/*
* Copyright (C) 2011-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include <iprt/semaphore.h>
#include "VDMemDisk.h"
#include "VDIoBackendMem.h"
#define VDMEMIOBACKEND_REQS 1024
/**
* Memory I/O request.
*/
typedef struct VDIOBACKENDREQ
{
/** I/O request direction. */
/** Memory disk handle. */
/** Start offset. */
/** Size of the transfer. */
/** Completion handler to call. */
/** Opaque user data. */
void *pvUser;
/** S/G buffer. */
/** Segment array - variable size. */
typedef PVDIOBACKENDREQ *PPVDIOBACKENDREQ;
/**
* I/O memory backend
*/
typedef struct VDIOBACKENDMEM
{
/** Thread handle for the backend. */
/** Circular buffer used for submitting requests. */
/** Size of the buffer in request items. */
unsigned cReqsRing;
/** Event semaphore the thread waits on for more work. */
/** Flag whether the server should be still running. */
volatile bool fRunning;
/** Number of requests waiting in the request buffer. */
volatile uint32_t cReqsWaiting;
/**
* Pokes the I/O thread that something interesting happened.
*
* @returns IPRT status code.
*
* @param pIoBackend The backend to poke.
*/
{
}
{
int rc = VINF_SUCCESS;
if (pIoBackend)
{
if (RT_SUCCESS(rc))
{
pIoBackend->fRunning = true;
if (RT_SUCCESS(rc))
{
RTTHREADFLAGS_WAITABLE, "MemIo");
if (RT_SUCCESS(rc))
{
LogFlowFunc(("returns success\n"));
return VINF_SUCCESS;
}
}
}
}
else
rc = VERR_NO_MEMORY;
return rc;
}
{
return VINF_SUCCESS;
}
{
unsigned cSegs = 0;
LogFlowFunc(("Queuing request\n"));
if (enmTxDir != VDIOTXDIR_FLUSH)
if (!pReq)
return VERR_NO_MEMORY;
RTCircBufAcquireWriteBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ), (void **)&ppReq, &cbData);
if (!pReq)
{
return VERR_NO_MEMORY;
}
if (enmTxDir != VDIOTXDIR_FLUSH)
{
}
if (cReqsWaiting == 1)
return VINF_SUCCESS;
}
/**
* I/O thread for the memory backend.
*
* @returns IPRT status code.
*
* @param hThread The thread handle.
* @param pvUser Opaque user data.
*/
{
while (pIoBackend->fRunning)
{
break;
while (cReqsWaiting)
{
int rcReq = VINF_SUCCESS;
/* Do we have another request? */
RTCircBufAcquireReadBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ), (void **)&ppReq, &cbData);
cReqsWaiting--;
LogFlowFunc(("Processing request\n"));
{
case VDIOTXDIR_READ:
{
break;
}
case VDIOTXDIR_WRITE:
{
break;
}
case VDIOTXDIR_FLUSH:
break;
default:
AssertMsgFailed(("Invalid TX direction!\n"));
}
/* Notify completion. */
}
}
return VINF_SUCCESS;
}