req.cpp revision 17ef1920962b3df57bf6d2704ced1586396d96f0
/* $Id$ */
/** @file
* IPRT - Request packets
*/
/*
* Copyright (C) 2006-2011 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.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/semaphore.h>
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
{
/*
* Ignore NULL (all free functions should do this imho).
*/
if (!pReq)
return VINF_SUCCESS;
/*
* Check packet state.
*/
{
case RTREQSTATE_ALLOCATED:
case RTREQSTATE_COMPLETED:
break;
default:
return VERR_RT_REQUEST_STATE;
}
/*
* Make it a free packet and put it into one of the free packet lists.
*/
{
PRTREQ volatile *ppHead = &pQueue->apReqFree[ASMAtomicIncU32(&pQueue->iReqFree) % RT_ELEMENTS(pQueue->apReqFree)];
do
{
}
else
{
}
return VINF_SUCCESS;
}
{
/*
* Verify the supplied package.
*/
{
return VERR_RT_REQUEST_STATE;
}
{
AssertMsgFailed(("Invalid request package! Anyone cooking their own packages???\n"));
return VERR_RT_REQUEST_INVALID_PACKAGE;
}
{
AssertMsgFailed(("Invalid package type %d valid range %d-%d inclusively. This was verified on alloc too...\n",
return VERR_RT_REQUEST_INVALID_TYPE;
}
int rc = VINF_SUCCESS;
/*
* Insert it.
*/
do
{
/*
* Notify queue thread.
*/
/*
* Wait and return.
*/
if (!(fFlags & RTREQFLAGS_NO_WAIT))
return rc;
}
{
/*
* Verify the supplied package.
*/
{
return VERR_RT_REQUEST_STATE;
}
{
AssertMsgFailed(("Invalid request package! Anyone cooking their own packages???\n"));
return VERR_RT_REQUEST_INVALID_PACKAGE;
}
{
AssertMsgFailed(("Invalid package type %d valid range %d-%d inclusively. This was verified on alloc and queue too...\n",
return VERR_RT_REQUEST_INVALID_TYPE;
}
/*
* Wait on the package.
*/
int rc;
if (cMillies != RT_INDEFINITE_WAIT)
else
{
do
{
}
if (rc == VINF_SUCCESS)
rc = VINF_SUCCESS;
return rc;
}
/**
* Process one request.
*
* @returns IPRT status code.
*
* @param pReq Request packet to process.
*/
{
/*
* Process the request.
*/
{
/*
* A packed down call frame.
*/
case RTREQTYPE_INTERNAL:
{
union
{
DECLCALLBACKMEMBER(int, pfn00)(void);
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);
} u;
#ifndef RT_ARCH_X86
{
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;
default:
break;
}
#else /* RT_ARCH_X86 */
# ifdef __GNUC__
"subl %2, %%esp\n\t"
"andl $0xfffffff0, %%esp\n\t"
"shrl $2, %2\n\t"
"movl %%esp, %%edi\n\t"
"rep movsl\n\t"
"movl %%edx, %%edi\n\t"
"call *%%eax\n\t"
"mov %%edi, %%esp\n\t"
: "=a" (rcRet),
"=S" (pauArgs),
"=c" (cbArgs)
: "0" (u.pfn),
"1" (pauArgs),
"2" (cbArgs)
: "edi", "edx");
# else
{
}
# endif
#endif /* RT_ARCH_X86 */
break;
}
default:
break;
}
/*
* Complete the request.
*/
{
/* Free the packet, nobody is waiting. */
LogFlow(("rtReqProcessOne: Completed request %p: rcReq=%Rrc rcRet=%Rrc - freeing it\n",
}
else
{
/* Notify the waiter and him free up the packet. */
LogFlow(("rtReqProcessOne: Completed request %p: rcReq=%Rrc rcRet=%Rrc - notifying waiting thread\n",
if (rc2 != VINF_SUCCESS)
{
}
}
return rcRet;
}