本文整理汇总了C++中RT_UNLIKELY函数的典型用法代码示例。如果您正苦于以下问题:C++ RT_UNLIKELY函数的具体用法?C++ RT_UNLIKELY怎么用?C++ RT_UNLIKELY使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了RT_UNLIKELY函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: PDMBOTHCBDECL
/**
* @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
*/
PDMBOTHCBDECL(int) drvNetShaperUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
{
PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp));
if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet)))
return VERR_NET_DOWN;
//LogFlow(("drvNetShaperUp_AllocBuf: cb=%d\n", cbMin));
STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesRequested, cbMin);
STAM_REL_COUNTER_INC(&pThis->StatXmitPktsRequested);
#if defined(IN_RING3) || defined(IN_RING0)
if (!PDMNsAllocateBandwidth(&pThis->Filter, cbMin))
{
STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesDenied, cbMin);
STAM_REL_COUNTER_INC(&pThis->StatXmitPktsDenied);
return VERR_TRY_AGAIN;
}
#endif
STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesGranted, cbMin);
STAM_REL_COUNTER_INC(&pThis->StatXmitPktsGranted);
//LogFlow(("drvNetShaperUp_AllocBuf: got cb=%d\n", cbMin));
return pThis->CTX_SUFF(pIBelowNet)->pfnAllocBuf(pThis->CTX_SUFF(pIBelowNet), cbMin, pGso, ppSgBuf);
}
示例2: RTDECL
RTDECL(int) RTPoll(RTPOLLSET hPollSet, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid)
{
RTPOLLSETINTERNAL *pThis = hPollSet;
AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
AssertReturn(pThis->u32Magic == RTPOLLSET_MAGIC, VERR_INVALID_HANDLE);
AssertPtrNull(pfEvents);
AssertPtrNull(pid);
/*
* Set the busy flag and do the job.
*/
AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS);
int rc;
if (cMillies == RT_INDEFINITE_WAIT || cMillies == 0)
{
do rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
while (rc == VERR_INTERRUPTED);
}
else
{
uint64_t MsStart = RTTimeMilliTS();
rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
while (RT_UNLIKELY(rc == VERR_INTERRUPTED))
{
if (RTTimeMilliTS() - MsStart >= cMillies)
{
rc = VERR_TIMEOUT;
break;
}
rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
}
}
ASMAtomicWriteBool(&pThis->fBusy, false);
return rc;
}
示例3: crUnpackDrawPixels
void crUnpackDrawPixels(PCrUnpackerState pState)
{
CHECK_BUFFER_SIZE_STATIC_LAST(pState, sizeof(int) + 20, GLint);
GLsizei width = READ_DATA(pState, sizeof( int ) + 0, GLsizei );
GLsizei height = READ_DATA(pState, sizeof( int ) + 4, GLsizei );
GLenum format = READ_DATA(pState, sizeof( int ) + 8, GLenum );
GLenum type = READ_DATA(pState, sizeof( int ) + 12, GLenum );
GLint noimagedata = READ_DATA(pState, sizeof( int ) + 16, GLint );
GLvoid *pixels;
if (noimagedata && !crStateIsBufferBound(pState->pStateTracker, GL_PIXEL_UNPACK_BUFFER_ARB))
return;
if (noimagedata)
pixels = (void*) (uintptr_t) READ_DATA(pState, sizeof( int ) + 20, GLint);
else
{
size_t cbImg = crImageSize( format, type, width, height );
if (RT_UNLIKELY(cbImg == 0))
{
pState->rcUnpack = VERR_INVALID_PARAMETER;
return;
}
pixels = DATA_POINTER(pState, sizeof( int ) + 24, GLvoid );
CHECK_ARRAY_SIZE_FROM_PTR_UPDATE_LAST(pState, pixels, cbImg, GLubyte);
}
pState->pDispatchTbl->PixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
pState->pDispatchTbl->PixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
pState->pDispatchTbl->PixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
pState->pDispatchTbl->PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
pState->pDispatchTbl->DrawPixels( width, height, format, type, pixels );
INCR_VAR_PTR(pState);
}
示例4: VMM_INT_DECL
/**
* Updates Hyper-V's reference TSC page.
*
* @returns VBox status code.
* @param pVM Pointer to the VM.
* @param u64Offset The computed TSC offset.
* @thread EMT.
*/
VMM_INT_DECL(int) gimR0HvUpdateParavirtTsc(PVM pVM, uint64_t u64Offset)
{
Assert(GIMIsEnabled(pVM));
bool fHvTscEnabled = MSR_GIM_HV_REF_TSC_IS_ENABLED(pVM->gim.s.u.Hv.u64TscPageMsr);
if (RT_UNLIKELY(!fHvTscEnabled))
return VERR_GIM_PVTSC_NOT_ENABLED;
PCGIMHV pcHv = &pVM->gim.s.u.Hv;
PCGIMMMIO2REGION pcRegion = &pcHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX];
PGIMHVREFTSC pRefTsc = (PGIMHVREFTSC)pcRegion->CTX_SUFF(pvPage);
Assert(pRefTsc);
/*
* Hyper-V reports the reference time in 100 nanosecond units.
*/
uint64_t u64Tsc100Ns = TMCpuTicksPerSecond(pVM) / RT_NS_10MS;
int64_t i64TscOffset = (int64_t)u64Offset / u64Tsc100Ns;
/*
* The TSC page can be simulatenously read by other VCPUs in the guest. The
* spinlock is only for protecting simultaneous hypervisor writes from other
* EMTs.
*/
RTSpinlockAcquire(pcHv->hSpinlockR0);
if (pRefTsc->i64TscOffset != i64TscOffset)
{
if (pRefTsc->u32TscSequence < UINT32_C(0xfffffffe))
ASMAtomicIncU32(&pRefTsc->u32TscSequence);
else
ASMAtomicWriteU32(&pRefTsc->u32TscSequence, 1);
ASMAtomicWriteS64(&pRefTsc->i64TscOffset, i64TscOffset);
}
RTSpinlockRelease(pcHv->hSpinlockR0);
Assert(pRefTsc->u32TscSequence != 0);
Assert(pRefTsc->u32TscSequence != UINT32_C(0xffffffff));
return VINF_SUCCESS;
}
示例5: VirtioPciPutQueue
/**
* Virtio Pci put queue routine. Places the queue and frees associated queue.
*
* @param pDevice Pointer to the Virtio device instance.
* @param pQueue Pointer to the queue.
*/
static void VirtioPciPutQueue(PVIRTIODEVICE pDevice, PVIRTIOQUEUE pQueue)
{
LogFlowFunc((VIRTIOLOGNAME ":VirtioPciPutQueue pDevice=%p pQueue=%p\n", pDevice, pQueue));
AssertReturnVoid(pDevice);
AssertReturnVoid(pQueue);
virtio_pci_t *pPci = pDevice->pvHyper;
AssertReturnVoid(pPci);
virtio_pci_queue_t *pPciQueue = pQueue->pvData;
if (RT_UNLIKELY(!pPciQueue))
{
LogRel((VIRTIOLOGNAME ":VirtioPciPutQueue missing Pci queue.\n"));
return;
}
ddi_put16(pPci->hIO, (uint16_t *)(pPci->addrIOBase + VIRTIO_PCI_QUEUE_SEL), pQueue->QueueIndex);
ddi_put32(pPci->hIO, (uint32_t *)(pPci->addrIOBase + VIRTIO_PCI_QUEUE_PFN), 0);
ddi_dma_unbind_handle(pPciQueue->hDMA);
ddi_dma_mem_free(&pPciQueue->hIO);
ddi_dma_free_handle(&pPciQueue->hDMA);
RTMemFree(pPciQueue);
}
示例6: vbglR3GRAlloc
int vbglR3GRAlloc(VMMDevRequestHeader **ppReq, uint32_t cb, VMMDevRequestType enmReqType)
{
VMMDevRequestHeader *pReq;
AssertPtrReturn(ppReq, VERR_INVALID_PARAMETER);
AssertMsgReturn(cb >= sizeof(VMMDevRequestHeader), ("%#x vs %#zx\n", cb, sizeof(VMMDevRequestHeader)),
VERR_INVALID_PARAMETER);
pReq = (VMMDevRequestHeader *)RTMemTmpAlloc(cb);
if (RT_UNLIKELY(!pReq))
return VERR_NO_MEMORY;
pReq->size = cb;
pReq->version = VMMDEV_REQUEST_HEADER_VERSION;
pReq->requestType = enmReqType;
pReq->rc = VERR_GENERAL_FAILURE;
pReq->reserved1 = 0;
pReq->reserved2 = 0;
*ppReq = pReq;
return VINF_SUCCESS;
}
示例7: DECLCALLBACK
/**
* @interface_method_impl{PDMIBASE,pfnWriteControl}
*/
static DECLCALLBACK(int) drvHostParallelWriteControl(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t fReg)
{
PDRVHOSTPARALLEL pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPARALLEL, CTX_SUFF(IHostParallelConnector));
int rc = VINF_SUCCESS;
int rcLnx = 0;
LogFlowFunc(("fReg=%#x\n", fReg));
# ifndef VBOX_WITH_WIN_PARPORT_SUP
rcLnx = ioctl(RTFileToNative(pThis->hFileDevice), PPWCONTROL, &fReg);
if (RT_UNLIKELY(rcLnx < 0))
rc = RTErrConvertFromErrno(errno);
# else /* VBOX_WITH_WIN_PARPORT_SUP */
uint64_t u64Data;
u64Data = (uint8_t)fReg;
if (pThis->fParportAvail)
{
LogFlowFunc(("calling R0 to write CTRL, data=%#x\n", u64Data));
rc = PDMDrvHlpCallR0(pThis->CTX_SUFF(pDrvIns), DRVHOSTPARALLELR0OP_WRITECONTROL, u64Data);
AssertRC(rc);
}
# endif /* VBOX_WITH_WIN_PARPORT_SUP */
return rc;
}
示例8: rtManifestGetEntry
/**
* Gets an entry.
*
* @returns IPRT status code.
* @param pThis The manifest to work with.
* @param pszEntry The entry name.
* @param fNeedNormalization Whether rtManifestValidateNameEntry said it
* needed normalization.
* @param cchEntry The length of the name.
* @param ppEntry Where to return the entry pointer on success.
*/
static int rtManifestGetEntry(RTMANIFESTINT *pThis, const char *pszEntry, bool fNeedNormalization, size_t cchEntry,
PRTMANIFESTENTRY *ppEntry)
{
PRTMANIFESTENTRY pEntry;
AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0);
if (!fNeedNormalization)
pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszEntry);
else
{
char *pszCopy = (char *)RTMemTmpAlloc(cchEntry + 1);
if (RT_UNLIKELY(!pszCopy))
return VERR_NO_TMP_MEMORY;
memcpy(pszCopy, pszEntry, cchEntry + 1);
rtManifestNormalizeEntry(pszCopy);
pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszCopy);
RTMemTmpFree(pszCopy);
}
*ppEntry = pEntry;
return pEntry ? VINF_SUCCESS : VERR_NOT_FOUND;
}
示例9: rtAsn1ObjId_ReadComponent
/**
* Reads one object ID component, returning it's value and encoded length.
*
* @returns The encoded length (positive) on success, negative IPRT status code
* on failure.
* @param pbContent The start of the component to parse.
* @param cbContent The number of content bytes left.
* @param puValue Where to return the value.
*/
static int rtAsn1ObjId_ReadComponent(uint8_t const *pbContent, uint32_t cbContent, uint32_t *puValue)
{
if (cbContent >= 1)
{
/* The first byte. */
uint8_t b = *pbContent;
if (!(b & 0x80))
{
*puValue = b;
return 1;
}
/* Encoded as more than one byte. Make sure that it's efficently
encoded as 8.19.2 indicates it must. */
if (b != 0x80)
{
uint32_t off = 1;
uint32_t uValue = b & 0x7f;
while (off < cbContent)
{
b = pbContent[off++];
uValue <<= 7;
uValue |= b & 0x7f;
if (!(b & 0x80))
{
*puValue = uValue;
return (int)off;
}
if (RT_UNLIKELY(uValue & UINT32_C(0x0e000000)))
return VERR_ASN1_OBJID_COMPONENT_TOO_BIG;
}
}
return VERR_ASN1_INVALID_OBJID_ENCODING;
}
return VERR_NO_DATA;
}
示例10: VBoxUSBMonSolarisAttach
/**
* Attach entry point, to attach a device to the system or resume it.
*
* @param pDip The module structure instance.
* @param enmCmd Attach type (ddi_attach_cmd_t)
*
* @returns corresponding solaris error code.
*/
static int VBoxUSBMonSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
{
LogFunc((DEVICE_NAME ":VBoxUSBMonSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
switch (enmCmd)
{
case DDI_ATTACH:
{
if (RT_UNLIKELY(g_pDip))
{
LogRel((DEVICE_NAME ":VBoxUSBMonSolarisAttach global instance already initialized.\n"));
return DDI_FAILURE;
}
g_pDip = pDip;
int instance = ddi_get_instance(pDip);
int rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0,
"none", "none", 0660);
if (rc == DDI_SUCCESS)
{
ddi_report_dev(pDip);
return rc;
}
else
LogRel((DEVICE_NAME ":VBoxUSBMonSolarisAttach ddi_create_minor_node failed! rc=%d\n", rc));
return DDI_FAILURE;
}
case DDI_RESUME:
{
/* We don't have to bother about power management. */
return DDI_SUCCESS;
}
default:
return DDI_FAILURE;
}
}
示例11: VMMDECL
/**
* Physical access handler for MMIO ranges.
*
* @returns VBox status code (appropriate for GC return).
* @param pVM The cross context VM structure.
* @param pVCpu The cross context virtual CPU structure of the calling EMT.
* @param uErrorCode CPU Error code.
* @param pCtxCore Trap register frame.
* @param GCPhysFault The GC physical address.
*/
VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault)
{
/*
* We don't have a range here, so look it up before calling the common function.
*/
int rc2 = IOM_LOCK_SHARED(pVM); NOREF(rc2);
#ifndef IN_RING3
if (rc2 == VERR_SEM_BUSY)
return VINF_IOM_R3_MMIO_READ_WRITE;
#endif
PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhysFault);
if (RT_UNLIKELY(!pRange))
{
IOM_UNLOCK_SHARED(pVM);
return VERR_IOM_MMIO_RANGE_NOT_FOUND;
}
iomMmioRetainRange(pRange);
IOM_UNLOCK_SHARED(pVM);
VBOXSTRICTRC rcStrict = iomMmioCommonPfHandler(pVM, pVCpu, (uint32_t)uErrorCode, pCtxCore, GCPhysFault, pRange);
iomMmioReleaseRange(pVM, pRange);
return VBOXSTRICTRC_VAL(rcStrict);
}
示例12: usbProxySolarisIOCtl
/**
* The client driver IOCtl Wrapper function.
*
* @returns VBox status code.
* @param pDevSol The Solaris device instance.
* @param Function The Function.
* @param pvData Opaque pointer to the data.
* @param cbData Size of the data pointed to by pvData.
*/
static int usbProxySolarisIOCtl(PUSBPROXYDEVSOL pDevSol, unsigned Function, void *pvData, size_t cbData)
{
if (RT_UNLIKELY(pDevSol->hFile == NIL_RTFILE))
{
LogFlow((USBPROXY ":usbProxySolarisIOCtl connection to driver gone!\n"));
return VERR_VUSB_DEVICE_NOT_ATTACHED;
}
VBOXUSBREQ Req;
Req.u32Magic = VBOXUSB_MAGIC;
Req.rc = -1;
Req.cbData = cbData;
Req.pvDataR3 = pvData;
int Ret = -1;
int rc = RTFileIoCtl(pDevSol->hFile, Function, &Req, sizeof(Req), &Ret);
if (RT_SUCCESS(rc))
{
if (RT_FAILURE(Req.rc))
{
if (Req.rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
{
pDevSol->pProxyDev->fDetached = true;
usbProxySolarisCloseFile(pDevSol);
LogRel((USBPROXY ":Command %#x failed, USB Device '%s' disconnected!\n", Function, pDevSol->pProxyDev->pUsbIns->pszName));
}
else
LogRel((USBPROXY ":Command %#x failed. Req.rc=%Rrc\n", Function, Req.rc));
}
return Req.rc;
}
LogRel((USBPROXY ":Function %#x failed. rc=%Rrc\n", Function, rc));
return rc;
}
示例13: ScmStreamPutCh
/**
* Write a character to the stream.
*
* @returns IPRT status code
* @param pStream The stream. Must be in write mode.
* @param pchBuf What to write.
* @param cchBuf How much to write.
*/
int ScmStreamPutCh(PSCMSTREAM pStream, char ch)
{
AssertReturn(pStream->fWriteOrRead, VERR_ACCESS_DENIED);
if (RT_FAILURE(pStream->rc))
return pStream->rc;
/*
* Only deal with the simple cases here, use ScmStreamWrite for the
* annoying stuff.
*/
size_t off = pStream->off;
if ( ch == '\n'
|| RT_UNLIKELY(off + 1 > pStream->cbAllocated))
return ScmStreamWrite(pStream, &ch, 1);
/*
* Just append it.
*/
pStream->pch[off] = ch;
pStream->off = off + 1;
pStream->paLines[pStream->iLine].cch++;
return VINF_SUCCESS;
}
示例14: DECL_FORCE_INLINE
DECL_FORCE_INLINE(int) rtSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, bool fAutoResume, PCRTLOCKVALSRCPOS pSrcPos)
{
/*
* Validate input.
*/
struct RTSEMMUTEXINTERNAL *pThis = hMutexSem;
AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
/*
* Check if nested request.
*/
pthread_t Self = pthread_self();
if ( pThis->Owner == Self
&& pThis->cNestings > 0)
{
#ifdef RTSEMMUTEX_STRICT
int rc9 = RTLockValidatorRecExclRecursion(&pThis->ValidatorRec, pSrcPos);
if (RT_FAILURE(rc9))
return rc9;
#endif
ASMAtomicIncU32(&pThis->cNestings);
return VINF_SUCCESS;
}
#ifdef RTSEMMUTEX_STRICT
RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
if (cMillies)
{
int rc9 = RTLockValidatorRecExclCheckOrder(&pThis->ValidatorRec, hThreadSelf, pSrcPos, cMillies);
if (RT_FAILURE(rc9))
return rc9;
}
#else
RTTHREAD hThreadSelf = RTThreadSelf();
#endif
/*
* Convert timeout value.
*/
struct timespec ts;
struct timespec *pTimeout = NULL;
uint64_t u64End = 0; /* shut up gcc */
if (cMillies != RT_INDEFINITE_WAIT)
{
ts.tv_sec = cMillies / 1000;
ts.tv_nsec = (cMillies % 1000) * UINT32_C(1000000);
u64End = RTTimeSystemNanoTS() + cMillies * UINT64_C(1000000);
pTimeout = &ts;
}
/*
* Lock the mutex.
* Optimize for the uncontended case (makes 1-2 ns difference).
*/
if (RT_UNLIKELY(!ASMAtomicCmpXchgS32(&pThis->iState, 1, 0)))
{
for (;;)
{
int32_t iOld = ASMAtomicXchgS32(&pThis->iState, 2);
/*
* Was the lock released in the meantime? This is unlikely (but possible)
*/
if (RT_UNLIKELY(iOld == 0))
break;
/*
* Go to sleep.
*/
if (pTimeout && ( pTimeout->tv_sec || pTimeout->tv_nsec ))
{
#ifdef RTSEMMUTEX_STRICT
int rc9 = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true,
cMillies, RTTHREADSTATE_MUTEX, true);
if (RT_FAILURE(rc9))
return rc9;
#else
RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, true);
#endif
}
long rc = sys_futex(&pThis->iState, FUTEX_WAIT, 2, pTimeout, NULL, 0);
RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_MUTEX);
if (RT_UNLIKELY(pThis->u32Magic != RTSEMMUTEX_MAGIC))
return VERR_SEM_DESTROYED;
/*
* Act on the wakup code.
*/
if (rc == -ETIMEDOUT)
{
Assert(pTimeout);
return VERR_TIMEOUT;
}
if (rc == 0)
/* we'll leave the loop now unless another thread is faster */;
else if (rc == -EWOULDBLOCK)
/* retry with new value. */;
//.........这里部分代码省略.........
示例15: main
int main(int argc, char **argv)
{
int rcRet = 0;
int i;
int rc;
int cIterations = argc > 1 ? RTStrToUInt32(argv[1]) : 32;
if (cIterations == 0)
cIterations = 64;
/*
* Init.
*/
RTR3InitExe(argc, &argv, 0);
PSUPDRVSESSION pSession;
rc = SUPR3Init(&pSession);
rcRet += rc != 0;
RTPrintf("tstInt: SUPR3Init -> rc=%Rrc\n", rc);
char szFile[RTPATH_MAX];
if (!rc)
{
rc = RTPathExecDir(szFile, sizeof(szFile) - sizeof("/VMMR0.r0"));
}
char szAbsFile[RTPATH_MAX];
if (RT_SUCCESS(rc))
{
strcat(szFile, "/VMMR0.r0");
rc = RTPathAbs(szFile, szAbsFile, sizeof(szAbsFile));
}
if (RT_SUCCESS(rc))
{
/*
* Load VMM code.
*/
rc = SUPR3LoadVMM(szAbsFile);
if (RT_SUCCESS(rc))
{
/*
* Create a fake 'VM'.
*/
PVMR0 pVMR0 = NIL_RTR0PTR;
PVM pVM = NULL;
const unsigned cPages = RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT;
PSUPPAGE paPages = (PSUPPAGE)RTMemAllocZ(cPages * sizeof(SUPPAGE));
if (paPages)
rc = SUPR3LowAlloc(cPages, (void **)&pVM, &pVMR0, &paPages[0]);
else
rc = VERR_NO_MEMORY;
if (RT_SUCCESS(rc))
{
pVM->pVMRC = 0;
pVM->pVMR3 = pVM;
pVM->pVMR0 = pVMR0;
pVM->paVMPagesR3 = paPages;
pVM->pSession = pSession;
pVM->enmVMState = VMSTATE_CREATED;
rc = SUPR3SetVMForFastIOCtl(pVMR0);
if (!rc)
{
/*
* Call VMM code with invalid function.
*/
for (i = cIterations; i > 0; i--)
{
rc = SUPR3CallVMMR0(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, NULL);
if (rc != VINF_SUCCESS)
{
RTPrintf("tstInt: SUPR3CallVMMR0 -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
rcRet++;
break;
}
}
RTPrintf("tstInt: Performed SUPR3CallVMMR0 %d times (rc=%Rrc)\n", cIterations, rc);
/*
* The fast path.
*/
if (rc == VINF_SUCCESS)
{
RTTimeNanoTS();
uint64_t StartTS = RTTimeNanoTS();
uint64_t StartTick = ASMReadTSC();
uint64_t MinTicks = UINT64_MAX;
for (i = 0; i < 1000000; i++)
{
uint64_t OneStartTick = ASMReadTSC();
rc = SUPR3CallVMMR0Fast(pVMR0, VMMR0_DO_NOP, 0);
uint64_t Ticks = ASMReadTSC() - OneStartTick;
if (Ticks < MinTicks)
MinTicks = Ticks;
if (RT_UNLIKELY(rc != VINF_SUCCESS))
{
RTPrintf("tstInt: SUPR3CallVMMR0Fast -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i);
rcRet++;
break;
}
}
uint64_t Ticks = ASMReadTSC() - StartTick;
//.........这里部分代码省略.........