VDIoBackendMem.cpp revision 14a9673ef19f6d8d49f83050d86cb444a55d4008
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * VBox HDD container test utility, async I/O memory backend
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2011-2012 Oracle Corporation
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * available from http://www.virtualbox.org. This file is free software;
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * General Public License (GPL) as published by the Free Software
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync#define LOGGROUP LOGGROUP_DEFAULT /** @todo: Log group */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * Memory I/O request.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** I/O request direction. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Memory disk handle. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Start offset. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Size of the transfer. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Completion handler to call. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Opaque user data. */
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync /** S/G buffer. */
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync /** Segment array - variable size. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * I/O memory backend
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Thread handle for the backend. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Circular buffer used for submitting requests. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Size of the buffer in request items. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Event semaphore the thread waits on for more work. */
4bfa7b58e362a1bca0628643c352c137900bf01avboxsync /** Flag whether the server should be still running. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync volatile bool fRunning;
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync /** Number of requests waiting in the request buffer. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsyncstatic int vdIoBackendMemThread(RTTHREAD hThread, void *pvUser);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * Pokes the I/O thread that something interesting happened.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * @returns IPRT status code.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * @param pIoBackend The backend to poke.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsyncstatic int vdIoBackendMemThreadPoke(PVDIOBACKENDMEM pIoBackend)
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsyncint VDIoBackendMemCreate(PPVDIOBACKENDMEM ppIoBackend)
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync pIoBackend = (PVDIOBACKENDMEM)RTMemAllocZ(sizeof(VDIOBACKENDMEM));
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync rc = RTCircBufCreate(&pIoBackend->pRequestRing, VDMEMIOBACKEND_REQS * sizeof(PVDIOBACKENDREQ));
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync pIoBackend->cReqsRing = VDMEMIOBACKEND_REQS * sizeof(VDIOBACKENDREQ);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync rc = RTThreadCreate(&pIoBackend->hThreadIo, vdIoBackendMemThread, pIoBackend, 0, RTTHREADTYPE_IO,
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsyncint VDIoBackendMemDestroy(PVDIOBACKENDMEM pIoBackend)
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync RTThreadWait(pIoBackend->hThreadIo, RT_INDEFINITE_WAIT, NULL);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsyncint VDIoBackendMemTransfer(PVDIOBACKENDMEM pIoBackend, PVDMEMDISK pMemDisk,
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync VDIOTXDIR enmTxDir, uint64_t off, size_t cbTransfer,
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync PRTSGBUF pSgBuf, PFNVDIOCOMPLETE pfnComplete, void *pvUser)
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync unsigned cSegs = 0;
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync RTSgBufSegArrayCreate(pSgBuf, NULL, &cSegs, cbTransfer);
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync pReq = (PVDIOBACKENDREQ)RTMemAlloc(RT_OFFSETOF(VDIOBACKENDREQ, aSegs[cSegs]));
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync RTCircBufAcquireWriteBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ), (void **)&ppReq, &cbData);
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync RTSgBufSegArrayCreate(pSgBuf, &pReq->aSegs[0], &cSegs, cbTransfer);
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync RTCircBufReleaseWriteBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ));
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync uint32_t cReqsWaiting = ASMAtomicIncU32(&pIoBackend->cReqsWaiting);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * I/O thread for the memory backend.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * @returns IPRT status code.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * @param hThread The thread handle.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * @param pvUser Opaque user data.
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsyncstatic int vdIoBackendMemThread(RTTHREAD hThread, void *pvUser)
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync PVDIOBACKENDMEM pIoBackend = (PVDIOBACKENDMEM)pvUser;
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync int rc = RTSemEventWait(pIoBackend->EventSem, RT_INDEFINITE_WAIT);
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync uint32_t cReqsWaiting = ASMAtomicXchgU32(&pIoBackend->cReqsWaiting, 0);
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync /* Do we have another request? */
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync RTCircBufAcquireReadBlock(pIoBackend->pRequestRing, sizeof(PVDIOBACKENDREQ), (void **)&ppReq, &cbData);
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync Assert(!ppReq || cbData == sizeof(PVDIOBACKENDREQ));
d82d7a8b44b27420e50f410d8ee5b990bb8b8f12vboxsync RTCircBufReleaseReadBlock(pIoBackend->pRequestRing, cbData);
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync rcReq = VDMemDiskRead(pReq->pMemDisk, pReq->off, pReq->cbTransfer, &pReq->SgBuf);
14a9673ef19f6d8d49f83050d86cb444a55d4008vboxsync rcReq = VDMemDiskWrite(pReq->pMemDisk, pReq->off, pReq->cbTransfer, &pReq->SgBuf);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /* Notify completion. */