VDIoBackendMem.cpp revision 39cac49f62afd27b0ffdbb779c7c64211939030c
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * VBox HDD container test utility, async I/O memory backend
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync * Copyright (C) 2011 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 /** Number of segments in the array. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Completion handler to call. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Opaque user data. */
39cac49f62afd27b0ffdbb779c7c64211939030cvboxsync /** Segment array - variable in 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. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /** Flag whether the the server should be still running. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync volatile bool fRunning;
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));
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync rc = RTCircBufCreate(&pIoBackend->pRequestRing, VDMEMIOBACKEND_REQS * sizeof(VDIOBACKENDREQ));
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,
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync VDIOTXDIR enmTxDir, uint64_t off, size_t cbTransfer, PCRTSGSEG paSegs,
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync unsigned cSegs, PFNVDIOCOMPLETE pfnComplete, void *pvUser)
39cac49f62afd27b0ffdbb779c7c64211939030cvboxsync RTCircBufAcquireWriteBlock(pIoBackend->pRequestRing, RT_OFFSETOF(VDIOBACKENDREQ, aSegs[cSegs]), (void **)&pReq, &cbData);
39cac49f62afd27b0ffdbb779c7c64211939030cvboxsync for (unsigned i = 0; i < cSegs; i++)
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync RTCircBufReleaseWriteBlock(pIoBackend->pRequestRing, sizeof(VDIOBACKENDREQ));
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);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync RTCircBufAcquireReadBlock(pIoBackend->pRequestRing, sizeof(VDIOBACKENDREQ), (void **)&pReq, &cbData);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync rcReq = VDMemDiskRead(pReq->pMemDisk, pReq->off, pReq->cbTransfer, &SgBuf);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync rcReq = VDMemDiskWrite(pReq->pMemDisk, pReq->off, pReq->cbTransfer, &SgBuf);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /* Notify completion. */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync RTCircBufReleaseReadBlock(pIoBackend->pRequestRing, cbData);
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync /* Do we have another request? */
078c5b8c5c814755aab943bf62cadef7e91c419cvboxsync RTCircBufAcquireReadBlock(pIoBackend->pRequestRing, sizeof(VDIOBACKENDREQ), (void **)&pReq, &cbData);