req.cpp revision c97989161fbe75bc14cea477a5443bbf474dd3ad
45e9809aff7304721fddb95654901b32195c9c7avboxsync/* $Id: VMReq.cpp 17451 2007-01-15 14:08:28Z bird $ */
45e9809aff7304721fddb95654901b32195c9c7avboxsync * innotek Portable Runtime - Request packets
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Copyright (C) 2006-2007 innotek GmbH
45e9809aff7304721fddb95654901b32195c9c7avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
45e9809aff7304721fddb95654901b32195c9c7avboxsync * available from http://www.virtualbox.org. This file is free software;
45e9809aff7304721fddb95654901b32195c9c7avboxsync * you can redistribute it and/or modify it under the terms of the GNU
45e9809aff7304721fddb95654901b32195c9c7avboxsync * General Public License as published by the Free Software Foundation,
45e9809aff7304721fddb95654901b32195c9c7avboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
45e9809aff7304721fddb95654901b32195c9c7avboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
45e9809aff7304721fddb95654901b32195c9c7avboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * If you received this file as part of a commercial VirtualBox
45e9809aff7304721fddb95654901b32195c9c7avboxsync * distribution, then only the terms of your commercial VirtualBox
45e9809aff7304721fddb95654901b32195c9c7avboxsync * license agreement apply instead of the previous paragraph.
45e9809aff7304721fddb95654901b32195c9c7avboxsync/*******************************************************************************
45e9809aff7304721fddb95654901b32195c9c7avboxsync* Header Files *
45e9809aff7304721fddb95654901b32195c9c7avboxsync*******************************************************************************/
45e9809aff7304721fddb95654901b32195c9c7avboxsync/*******************************************************************************
45e9809aff7304721fddb95654901b32195c9c7avboxsync* Internal Functions *
45e9809aff7304721fddb95654901b32195c9c7avboxsync*******************************************************************************/
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Create a request packet queueu
45e9809aff7304721fddb95654901b32195c9c7avboxsync * @returns iprt status code.
45e9809aff7304721fddb95654901b32195c9c7avboxsync * @param pReqQueue The request queue.
45e9809aff7304721fddb95654901b32195c9c7avboxsync *ppQueue = (PRTREQQUEUE)RTMemAllocZ(sizeof(RTREQQUEUE));
45e9809aff7304721fddb95654901b32195c9c7avboxsync * Destroy a request packet queueu
if (!pQueue)
AssertFailed();
return VERR_INVALID_PARAMETER;
return VINF_SUCCESS;
if (!pQueue)
AssertFailed();
return VERR_INVALID_PARAMETER;
if (!pReqs)
while (pReq)
while (pReqs)
return rc;
RTDECL(int) RTReqCall(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, PFNRT pfnFunction, unsigned cArgs, ...)
return rc;
RTDECL(int) RTReqCallVoid(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, PFNRT pfnFunction, unsigned cArgs, ...)
return rc;
RTDECL(int) RTReqCallEx(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...)
return rc;
RTDECL(int) RTReqCallV(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args)
LogFlow(("RTReqCallV: cMillies=%d fFlags=%#x pfnFunction=%p cArgs=%d\n", cMillies, fFlags, pfnFunction, cArgs));
AssertFailed();
return VERR_INVALID_PARAMETER;
return VERR_TOO_MUCH_DATA;
return rc;
return rc;
if (!pHead)
vmr3ReqJoinFreeSub(&pQueue->apReqFree[(i + 2 + (i == pQueue->iReqFree)) % ELEMENTS(pQueue->apReqFree)], pTail->pNext);
vmr3ReqJoinFreeSub(&pQueue->apReqFree[(pQueue->iReqFree + 2) % ELEMENTS(pQueue->apReqFree)], pList);
return VERR_RT_REQUEST_INVALID_TYPE;
while (--cTries >= 0)
PRTREQ volatile *ppHead = &pQueue->apReqFree[ASMAtomicIncU32(&pQueue->iReqFree) % ELEMENTS(pQueue->apReqFree)];
if ( pReq
if (pReq)
if (pReq)
if ( pNext
return rc;
return VINF_SUCCESS;
if (!pReq)
return VERR_NO_MEMORY;
return rc;
return VINF_SUCCESS;
if (!pReq)
return VINF_SUCCESS;
case RTREQSTATE_ALLOCATED:
case RTREQSTATE_COMPLETED:
return VERR_RT_REQUEST_STATE;
PRTREQ volatile *ppHead = &pQueue->apReqFree[ASMAtomicIncU32(&pQueue->iReqFree) % ELEMENTS(pQueue->apReqFree)];
return VINF_SUCCESS;
return VERR_RT_REQUEST_STATE;
return VERR_RT_REQUEST_INVALID_PACKAGE;
AssertMsgFailed(("Invalid package type %d valid range %d-%d inclusivly. This was verified on alloc too...\n",
return VERR_RT_REQUEST_INVALID_TYPE;
} while (!ASMAtomicCmpXchgPtr((void * volatile *)&pReq->pQueue->pReqs, (void *)pReq, (void *)pNext));
return rc;
return VERR_RT_REQUEST_STATE;
return VERR_RT_REQUEST_INVALID_PACKAGE;
AssertMsgFailed(("Invalid package type %d valid range %d-%d inclusivly. This was verified on alloc and queue too...\n",
return VERR_RT_REQUEST_INVALID_TYPE;
int rc;
return rc;
case RTREQTYPE_INTERNAL:
DECLCALLBACKMEMBER(int, pfn07)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
DECLCALLBACKMEMBER(int, pfn08)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
DECLCALLBACKMEMBER(int, pfn09)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
DECLCALLBACKMEMBER(int, pfn10)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
DECLCALLBACKMEMBER(int, pfn11)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
DECLCALLBACKMEMBER(int, pfn12)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
#ifdef __AMD64__
case 6: rcRet = u.pfn06(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5]); break;
case 7: rcRet = u.pfn07(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6]); break;
case 8: rcRet = u.pfn08(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7]); break;
case 9: rcRet = u.pfn09(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8]); break;
case 10: rcRet = u.pfn10(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9]); break;
case 11: rcRet = u.pfn11(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9], pauArgs[10]); break;
case 12: rcRet = u.pfn12(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9], pauArgs[10], pauArgs[11]); break;
# ifdef __GNUC__
LogFlow(("rtReqProcessOne: Completed request %p: rcReq=%Vrc rcRet=%Vrc - notifying waiting thread\n",
return rcRet;