本文整理匯總了C++中AssertMsg函數的典型用法代碼示例。如果您正苦於以下問題:C++ AssertMsg函數的具體用法?C++ AssertMsg怎麽用?C++ AssertMsg使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了AssertMsg函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的C++代碼示例。
示例1: AssertPtrReturn
int GuestFile::onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData)
{
AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER);
AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER);
LogFlowThisFuncEnter();
if (pSvcCbData->mParms < 3)
return VERR_INVALID_PARAMETER;
int vrc = VINF_SUCCESS;
int idx = 1; /* Current parameter index. */
CALLBACKDATA_FILE_NOTIFY dataCb;
/* pSvcCb->mpaParms[0] always contains the context ID. */
pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.uType);
pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.rc);
FileStatus_T fileStatus = FileStatus_Undefined;
int guestRc = (int)dataCb.rc; /* uint32_t vs. int. */
LogFlowFunc(("uType=%RU32, guestRc=%Rrc\n",
dataCb.uType, guestRc));
if (RT_FAILURE(guestRc))
{
int rc2 = setFileStatus(FileStatus_Error, guestRc);
AssertRC(rc2);
rc2 = signalWaitEventInternal(pCbCtx,
guestRc, NULL /* pPayload */);
AssertRC(rc2);
return VINF_SUCCESS; /* Report to the guest. */
}
switch (dataCb.uType)
{
case GUEST_FILE_NOTIFYTYPE_ERROR:
{
int rc2 = setFileStatus(FileStatus_Error, guestRc);
AssertRC(rc2);
break;
}
case GUEST_FILE_NOTIFYTYPE_OPEN:
{
if (pSvcCbData->mParms == 4)
{
pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle);
{
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
AssertMsg(mData.mID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID),
("File ID %RU32 does not match context ID %RU32\n", mData.mID,
VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID)));
/* Set the initial offset. On the guest the whole opening operation
* would fail if an initial seek isn't possible. */
mData.mOffCurrent = mData.mOpenInfo.mInitialOffset;
}
/* Set the process status. */
int rc2 = setFileStatus(FileStatus_Open, guestRc);
AssertRC(rc2);
}
else
vrc = VERR_NOT_SUPPORTED;
break;
}
case GUEST_FILE_NOTIFYTYPE_CLOSE:
{
int rc2 = setFileStatus(FileStatus_Closed, guestRc);
AssertRC(rc2);
break;
}
case GUEST_FILE_NOTIFYTYPE_READ:
{
if (pSvcCbData->mParms == 4)
{
pSvcCbData->mpaParms[idx++].getPointer(&dataCb.u.read.pvData,
&dataCb.u.read.cbData);
uint32_t cbRead = dataCb.u.read.cbData;
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
mData.mOffCurrent += cbRead;
alock.release();
com::SafeArray<BYTE> data((size_t)cbRead);
data.initFrom((BYTE*)dataCb.u.read.pvData, cbRead);
fireGuestFileReadEvent(mEventSource, mSession, this, mData.mOffCurrent,
cbRead, ComSafeArrayAsInParam(data));
//.........這裏部分代碼省略.........
示例2: socketpair
int HostDnsServiceLinux::monitorWorker()
{
AutoNotify a;
int rc = socketpair(AF_LOCAL, SOCK_DGRAM, 0, g_DnsMonitorStop);
AssertMsgReturn(rc == 0, ("socketpair: failed (%d: %s)\n", errno, strerror(errno)), E_FAIL);
FileDescriptor stopper0(g_DnsMonitorStop[0]);
FileDescriptor stopper1(g_DnsMonitorStop[1]);
pollfd polls[2];
RT_ZERO(polls);
polls[0].fd = a.fileDescriptor();
polls[0].events = POLLIN;
polls[1].fd = g_DnsMonitorStop[1];
polls[1].events = POLLIN;
monitorThreadInitializationDone();
int wd[2];
wd[0] = wd[1] = -1;
/* inotify inialization */
wd[0] = inotify_add_watch(a.fileDescriptor(),
g_ResolvConfFullPath.c_str(), IN_CLOSE_WRITE|IN_DELETE_SELF);
/**
* If /etc/resolv.conf exists we want to listen for movements: because
* # mv /etc/resolv.conf ...
* won't arm IN_DELETE_SELF on wd[0] instead it will fire IN_MOVE_FROM on wd[1].
*
* Because on some distributions /etc/resolv.conf is link, wd[0] can't detect deletion,
* it's recognizible on directory level (wd[1]) only.
*/
wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
wd[0] == -1 ? IN_MOVED_TO|IN_CREATE : IN_MOVED_FROM|IN_DELETE);
struct InotifyEventWithName combo;
while(true)
{
rc = poll(polls, 2, -1);
if (rc == -1)
continue;
AssertMsgReturn( ((polls[0].revents & (POLLERR|POLLNVAL)) == 0)
&& ((polls[1].revents & (POLLERR|POLLNVAL)) == 0),
("Debug Me"), VERR_INTERNAL_ERROR);
if (polls[1].revents & POLLIN)
return VINF_SUCCESS; /* time to shutdown */
if (polls[0].revents & POLLIN)
{
RT_ZERO(combo);
ssize_t r = read(polls[0].fd, static_cast<void *>(&combo), sizeof(combo));
NOREF(r);
if (combo.e.wd == wd[0])
{
if (combo.e.mask & IN_CLOSE_WRITE)
{
readResolvConf();
}
else if (combo.e.mask & IN_DELETE_SELF)
{
inotify_rm_watch(a.fileDescriptor(), wd[0]); /* removes file watcher */
inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
IN_MOVED_TO|IN_CREATE); /* alter folder watcher */
}
else if (combo.e.mask & IN_IGNORED)
{
wd[0] = -1; /* we want receive any events on this watch */
}
else
{
/**
* It shouldn't happen, in release we will just ignore in debug
* we will have to chance to look at into inotify_event
*/
AssertMsgFailed(("Debug Me!!!"));
}
}
else if (combo.e.wd == wd[1])
{
if ( combo.e.mask & IN_MOVED_FROM
|| combo.e.mask & IN_DELETE)
{
if (g_ResolvConf == combo.e.name)
{
/**
* Our file has been moved so we should change watching mode.
*/
inotify_rm_watch(a.fileDescriptor(), wd[0]);
wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
IN_MOVED_TO|IN_CREATE);
AssertMsg(wd[1] != -1,
("It shouldn't happen, further investigation is needed\n"));
}
//.........這裏部分代碼省略.........
示例3: DECLCALLBACK
static DECLCALLBACK(int) drvscsiReqTransferEnqueue(VSCSILUN hVScsiLun,
void *pvScsiLunUser,
VSCSIIOREQ hVScsiIoReq)
{
int rc = VINF_SUCCESS;
PDRVSCSI pThis = (PDRVSCSI)pvScsiLunUser;
if (pThis->pDrvBlockAsync)
{
/* async I/O path. */
VSCSIIOREQTXDIR enmTxDir;
LogFlowFunc(("Enqueuing hVScsiIoReq=%#p\n", hVScsiIoReq));
enmTxDir = VSCSIIoReqTxDirGet(hVScsiIoReq);
switch (enmTxDir)
{
case VSCSIIOREQTXDIR_FLUSH:
{
rc = pThis->pDrvBlockAsync->pfnStartFlush(pThis->pDrvBlockAsync, hVScsiIoReq);
if ( RT_FAILURE(rc)
&& rc != VERR_VD_ASYNC_IO_IN_PROGRESS
&& pThis->cErrors++ < MAX_LOG_REL_ERRORS)
LogRel(("SCSI#%u: Flush returned rc=%Rrc\n",
pThis->pDrvIns->iInstance, rc));
break;
}
case VSCSIIOREQTXDIR_UNMAP:
{
PCRTRANGE paRanges;
unsigned cRanges;
rc = VSCSIIoReqUnmapParamsGet(hVScsiIoReq, &paRanges, &cRanges);
AssertRC(rc);
pThis->pLed->Asserted.s.fWriting = pThis->pLed->Actual.s.fWriting = 1;
rc = pThis->pDrvBlockAsync->pfnStartDiscard(pThis->pDrvBlockAsync, paRanges, cRanges, hVScsiIoReq);
if ( RT_FAILURE(rc)
&& rc != VERR_VD_ASYNC_IO_IN_PROGRESS
&& pThis->cErrors++ < MAX_LOG_REL_ERRORS)
LogRel(("SCSI#%u: Discard returned rc=%Rrc\n",
pThis->pDrvIns->iInstance, rc));
break;
}
case VSCSIIOREQTXDIR_READ:
case VSCSIIOREQTXDIR_WRITE:
{
uint64_t uOffset = 0;
size_t cbTransfer = 0;
size_t cbSeg = 0;
PCRTSGSEG paSeg = NULL;
unsigned cSeg = 0;
rc = VSCSIIoReqParamsGet(hVScsiIoReq, &uOffset, &cbTransfer,
&cSeg, &cbSeg, &paSeg);
AssertRC(rc);
if (enmTxDir == VSCSIIOREQTXDIR_READ)
{
pThis->pLed->Asserted.s.fReading = pThis->pLed->Actual.s.fReading = 1;
rc = pThis->pDrvBlockAsync->pfnStartRead(pThis->pDrvBlockAsync, uOffset,
paSeg, cSeg, cbTransfer,
hVScsiIoReq);
STAM_REL_COUNTER_ADD(&pThis->StatBytesRead, cbTransfer);
}
else
{
pThis->pLed->Asserted.s.fWriting = pThis->pLed->Actual.s.fWriting = 1;
rc = pThis->pDrvBlockAsync->pfnStartWrite(pThis->pDrvBlockAsync, uOffset,
paSeg, cSeg, cbTransfer,
hVScsiIoReq);
STAM_REL_COUNTER_ADD(&pThis->StatBytesWritten, cbTransfer);
}
if ( RT_FAILURE(rc)
&& rc != VERR_VD_ASYNC_IO_IN_PROGRESS
&& pThis->cErrors++ < MAX_LOG_REL_ERRORS)
LogRel(("SCSI#%u: %s at offset %llu (%u bytes left) returned rc=%Rrc\n",
pThis->pDrvIns->iInstance,
enmTxDir == VSCSIIOREQTXDIR_READ
? "Read"
: "Write",
uOffset,
cbTransfer, rc));
break;
}
default:
AssertMsgFailed(("Invalid transfer direction %u\n", enmTxDir));
}
if (rc == VINF_VD_ASYNC_IO_FINISHED)
{
if (enmTxDir == VSCSIIOREQTXDIR_READ)
pThis->pLed->Actual.s.fReading = 0;
else if (enmTxDir == VSCSIIOREQTXDIR_WRITE)
pThis->pLed->Actual.s.fWriting = 0;
else
AssertMsg(enmTxDir == VSCSIIOREQTXDIR_FLUSH, ("Invalid transfer direction %u\n", enmTxDir));
//.........這裏部分代碼省略.........
示例4: tstRandAdv
//.........這裏部分代碼省略.........
{ INT32_MIN, INT32_MAX / 2 },
{ -0x20000000, INT32_MAX },
{ -0x10000000, INT32_MAX },
{ -0x08000000, INT32_MAX },
{ -0x00800000, INT32_MAX },
{ -0x00080000, INT32_MAX },
{ -0x00008000, INT32_MAX },
{ -0x00000800, INT32_MAX },
{ 2, INT32_MAX / 2 },
{ 4000000, INT32_MAX / 2 },
{ -4000000, INT32_MAX / 2 },
{ INT32_MIN / 2, INT32_MAX / 2 },
{ INT32_MIN / 3, INT32_MAX / 2 },
{ INT32_MIN / 3, INT32_MAX / 3 },
{ INT32_MIN / 3, INT32_MAX / 4 },
{ INT32_MIN / 4, INT32_MAX / 4 },
{ INT32_MIN / 5, INT32_MAX / 5 },
{ INT32_MIN / 6, INT32_MAX / 6 },
{ INT32_MIN / 7, INT32_MAX / 6 },
{ INT32_MIN / 7, INT32_MAX / 7 },
{ INT32_MIN / 7, INT32_MAX / 8 },
{ INT32_MIN / 8, INT32_MAX / 8 },
{ INT32_MIN / 9, INT32_MAX / 9 },
{ INT32_MIN / 9, INT32_MAX / 12 },
{ INT32_MIN / 12, INT32_MAX / 12 },
{ 0, TST_RAND_SAMPLE_RANGES - 1 },
{ -TST_RAND_SAMPLE_RANGES / 2, TST_RAND_SAMPLE_RANGES / 2 - 1 },
};
for (unsigned iTest = 0; iTest < RT_ELEMENTS(s_aS32Tests); iTest++)
{
uint32_t acHits[TST_RAND_SAMPLE_RANGES] = {0};
int32_t const iFirst = s_aS32Tests[iTest].i32First;
int32_t const iLast = s_aS32Tests[iTest].i32Last;
uint32_t const uRange = iLast - iFirst; AssertMsg(iLast >= iFirst, ("%d\n", iTest));
uint32_t const uDivisor = (uRange ? uRange : UINT32_MAX) / TST_RAND_SAMPLE_RANGES + 1;
RTPrintf("tstRand: TESTING RTRandAdvS32Ex(,%#RI32, %#RI32) distribution... [div=%#RX32 range=%#RX32]\n", iFirst, iLast, uDivisor, uRange);
for (unsigned iSample = 0; iSample < TST_RAND_SAMPLE_RANGES * 10240; iSample++)
{
int32_t iRand = RTRandAdvS32Ex(hRand, iFirst, iLast);
CHECK_EXPR_MSG(iRand >= iFirst, ("%#RI32 %#RI32\n", iRand, iFirst));
CHECK_EXPR_MSG(iRand <= iLast, ("%#RI32 %#RI32\n", iRand, iLast));
uint32_t off = iRand - iFirst;
acHits[off / uDivisor]++;
}
tstRandCheckDist(acHits, iTest);
}
#endif
#if 1
/* signed 64-bit */
static const struct
{
int64_t i64First;
int64_t i64Last;
} s_aS64Tests[] =
{
{ INT64_MIN, INT64_MAX },
{ INT64_MIN, INT64_MAX / 2 },
{ INT64_MIN / 2, INT64_MAX / 2 },
{ INT64_MIN / 2 + INT64_MIN / 4, INT64_MAX / 2 },
{ INT64_MIN / 2 + INT64_MIN / 8, INT64_MAX / 2 },
{ INT64_MIN / 2 + INT64_MIN / 16, INT64_MAX / 2 },
{ INT64_MIN / 2 + INT64_MIN / 64, INT64_MAX / 2 },
{ INT64_MIN / 2 + INT64_MIN / 64, INT64_MAX / 2 + INT64_MAX / 64 },
{ INT64_MIN / 2, INT64_MAX / 2 + INT64_MAX / 64 },
{ INT64_MIN / 2, INT64_MAX / 2 + INT64_MAX / 8 },
示例5: UIToolBar
/* Mini-toolbar constructor */
VBoxMiniToolBar::VBoxMiniToolBar(QWidget *pParent, Alignment alignment, bool fActive, bool fAutoHide)
: UIToolBar(pParent)
, m_pAutoHideAction(0)
, m_pDisplayLabel(0)
, m_pMinimizeAction(0)
, m_pRestoreAction(0)
, m_pCloseAction(0)
, m_fActive(fActive)
, m_fPolished(false)
, m_fSeamless(false)
, m_fAutoHide(fAutoHide)
, m_fSlideToScreen(true)
, m_fHideAfterSlide(false)
, m_iAutoHideCounter(0)
, m_iPositionX(0)
, m_iPositionY(0)
, m_pInsertPosition(0)
, m_alignment(alignment)
, m_fAnimated(true)
, m_iScrollDelay(10)
, m_iAutoScrollDelay(100)
, m_iAutoHideTotalCounter(10)
{
/* Check parent widget presence: */
AssertMsg(parentWidget(), ("Parent widget must be set!\n"));
/* Toolbar options: */
setIconSize(QSize(16, 16));
setVisible(false);
/* Left margin of tool-bar: */
m_Margins << widgetForAction(addWidget(new QWidget(this)));
/* Add pushpin: */
m_pAutoHideAction = new QAction(this);
m_pAutoHideAction->setIcon(UIIconPool::iconSet(":/pin_16px.png"));
m_pAutoHideAction->setToolTip(tr("Always show the toolbar"));
m_pAutoHideAction->setCheckable(true);
m_pAutoHideAction->setChecked(!m_fAutoHide);
connect(m_pAutoHideAction, SIGNAL(toggled(bool)), this, SLOT(togglePushpin(bool)));
addAction(m_pAutoHideAction);
/* Left menu margin: */
m_Spacings << widgetForAction(addWidget(new QWidget(this)));
/* Right menu margin: */
m_pInsertPosition = addWidget(new QWidget(this));
m_Spacings << widgetForAction(m_pInsertPosition);
/* Left label margin: */
m_LabelMargins << widgetForAction(addWidget(new QWidget(this)));
/* Insert a label for VM Name: */
m_pDisplayLabel = new QLabel(this);
m_pDisplayLabel->setAlignment(Qt::AlignCenter);
addWidget(m_pDisplayLabel);
/* Right label margin: */
m_LabelMargins << widgetForAction(addWidget(new QWidget(this)));
/* Minimize action: */
m_pMinimizeAction = new QAction(this);
m_pMinimizeAction->setIcon(UIIconPool::iconSet(":/minimize_16px.png"));
m_pMinimizeAction->setToolTip(tr("Minimize Window"));
connect(m_pMinimizeAction, SIGNAL(triggered()), this, SIGNAL(minimizeAction()));
addAction(m_pMinimizeAction);
/* Exit action: */
m_pRestoreAction = new QAction(this);
m_pRestoreAction->setIcon(UIIconPool::iconSet(":/restore_16px.png"));
m_pRestoreAction->setToolTip(tr("Exit Full Screen or Seamless Mode"));
connect(m_pRestoreAction, SIGNAL(triggered()), this, SIGNAL(exitAction()));
addAction(m_pRestoreAction);
/* Close action: */
m_pCloseAction = new QAction(this);
m_pCloseAction->setIcon(UIIconPool::iconSet(":/close_16px.png"));
m_pCloseAction->setToolTip(tr("Close VM"));
connect(m_pCloseAction, SIGNAL(triggered()), this, SIGNAL(closeAction()));
addAction(m_pCloseAction);
/* Right margin of tool-bar: */
m_Margins << widgetForAction(addWidget(new QWidget(this)));
/* Event-filter for parent widget to control resize: */
pParent->installEventFilter(this);
/* Enable mouse-tracking for this & children allowing to get mouse-move events: */
setMouseTrackingEnabled(m_fAutoHide);
}
示例6: rtHeapSimpleAllocBlock
/**
* Allocates a block of memory from the specified heap.
*
* No parameter validation or adjustment is performed.
*
* @returns Pointer to the allocated block.
* @returns NULL on failure.
*
* @param pHeapInt The heap.
* @param cb Size of the memory block to allocate.
* @param uAlignment The alignment specifications for the allocated block.
*/
static PRTHEAPSIMPLEBLOCK rtHeapSimpleAllocBlock(PRTHEAPSIMPLEINTERNAL pHeapInt, size_t cb, size_t uAlignment)
{
PRTHEAPSIMPLEBLOCK pRet = NULL;
PRTHEAPSIMPLEFREE pFree;
#ifdef RTHEAPSIMPLE_STRICT
rtHeapSimpleAssertAll(pHeapInt);
#endif
/*
* Search for a fitting block from the lower end of the heap.
*/
for (pFree = pHeapInt->pFreeHead;
pFree;
pFree = pFree->pNext)
{
uintptr_t offAlign;
ASSERT_BLOCK_FREE(pHeapInt, pFree);
/*
* Match for size and alignment.
*/
if (pFree->cb < cb)
continue;
offAlign = (uintptr_t)(&pFree->Core + 1) & (uAlignment - 1);
if (offAlign)
{
RTHEAPSIMPLEFREE Free;
PRTHEAPSIMPLEBLOCK pPrev;
offAlign = uAlignment - offAlign;
if (pFree->cb - offAlign < cb)
continue;
/*
* Make a stack copy of the free block header and adjust the pointer.
*/
Free = *pFree;
pFree = (PRTHEAPSIMPLEFREE)((uintptr_t)pFree + offAlign);
/*
* Donate offAlign bytes to the node in front of us.
* If we're the head node, we'll have to create a fake node. We'll
* mark it USED for simplicity.
*
* (Should this policy of donating memory to the guy in front of us
* cause big 'leaks', we could create a new free node if there is room
* for that.)
*/
pPrev = Free.Core.pPrev;
if (pPrev)
{
AssertMsg(!RTHEAPSIMPLEBLOCK_IS_FREE(pPrev), ("Impossible!\n"));
pPrev->pNext = &pFree->Core;
}
else
{
pPrev = (PRTHEAPSIMPLEBLOCK)(pHeapInt + 1);
Assert(pPrev == &pFree->Core);
pPrev->pPrev = NULL;
pPrev->pNext = &pFree->Core;
pPrev->pHeap = pHeapInt;
pPrev->fFlags = RTHEAPSIMPLEBLOCK_FLAGS_MAGIC;
}
pHeapInt->cbFree -= offAlign;
/*
* Recreate pFree in the new position and adjust the neighbors.
*/
*pFree = Free;
/* the core */
if (pFree->Core.pNext)
pFree->Core.pNext->pPrev = &pFree->Core;
pFree->Core.pPrev = pPrev;
/* the free part */
pFree->cb -= offAlign;
if (pFree->pNext)
pFree->pNext->pPrev = pFree;
else
pHeapInt->pFreeTail = pFree;
if (pFree->pPrev)
pFree->pPrev->pNext = pFree;
else
pHeapInt->pFreeHead = pFree;
ASSERT_BLOCK_FREE(pHeapInt, pFree);
ASSERT_BLOCK_USED(pHeapInt, pPrev);
//.........這裏部分代碼省略.........
示例7: switch
void CAI_PlaneSolver::GenerateSuggestionFromTrace( const AILocalMoveGoal_t &goal,
const AIMoveTrace_t &moveTrace, float probeDist,
float arcCenter, float arcSpan, int probeOffset )
{
AI_MoveSuggestion_t suggestion;
AI_MoveSuggType_t type;
switch ( moveTrace.fStatus )
{
case AIMR_BLOCKED_ENTITY: type = AIMST_AVOID_OBJECT; break;
case AIMR_BLOCKED_WORLD: type = AIMST_AVOID_WORLD; break;
case AIMR_BLOCKED_NPC: type = AIMST_AVOID_NPC; break;
case AIMR_ILLEGAL: type = AIMST_AVOID_DANGER; break;
default: type = AIMST_NO_KNOWLEDGE; AssertMsg( 0, "Unexpected mode status" ); break;
}
if ( goal.pMoveTarget != NULL && goal.pMoveTarget == moveTrace.pObstruction )
{
suggestion.Set( type, 0,
arcCenter, arcSpan,
moveTrace.pObstruction );
m_Solver.AddRegulation( suggestion );
return;
}
float clearDist = probeDist - moveTrace.flDistObstructed;
float pctBlocked = 1.0 - ( clearDist / probeDist );
float weight = CalculateRegulationWeight( moveTrace, pctBlocked );
if ( weight < 0.001 )
return;
if ( pctBlocked < 0.5 )
{
arcSpan *= pctBlocked * 2.0;
}
Vector vecToEnd = moveTrace.vEndPosition - GetLocalOrigin();
Vector crossProduct;
bool favorLeft = false, favorRight = false;
if ( moveTrace.fStatus == AIMR_BLOCKED_NPC )
{
Vector vecToOther = moveTrace.pObstruction->GetLocalOrigin() - GetLocalOrigin();
CrossProduct(vecToEnd, vecToOther, crossProduct);
favorLeft = ( crossProduct.z < 0 );
favorRight = ( crossProduct.z > 0 );
}
else if ( moveTrace.vHitNormal != vec3_origin )
{
CrossProduct(vecToEnd, moveTrace.vHitNormal, crossProduct);
favorLeft = ( crossProduct.z > 0 );
favorRight = ( crossProduct.z < 0 );
}
float thirdSpan = arcSpan / 3.0;
float favoredWeight = weight * pctBlocked;
suggestion.Set( type, weight,
arcCenter, thirdSpan,
moveTrace.pObstruction );
m_Solver.AddRegulation( suggestion );
suggestion.Set( type, ( favorRight ) ? favoredWeight : weight,
arcCenter - thirdSpan, thirdSpan,
moveTrace.pObstruction );
m_Solver.AddRegulation( suggestion );
suggestion.Set( type, ( favorLeft ) ? favoredWeight : weight,
arcCenter + thirdSpan, thirdSpan,
moveTrace.pObstruction );
m_Solver.AddRegulation( suggestion );
}
示例8: RTTcpSetSendCoalescing
Console::teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser)
{
TeleporterStateTrg *pState = (TeleporterStateTrg *)pvUser;
pState->mhSocket = Sock;
/*
* Disable Nagle and say hello.
*/
int vrc = RTTcpSetSendCoalescing(pState->mhSocket, false /*fEnable*/);
AssertRC(vrc);
vrc = RTTcpWrite(Sock, g_szWelcome, sizeof(g_szWelcome) - 1);
if (RT_FAILURE(vrc))
{
LogRel(("Teleporter: Failed to write welcome message: %Rrc\n", vrc));
return VINF_SUCCESS;
}
/*
* Password (includes '\n', see teleporterTrg).
*/
const char *pszPassword = pState->mstrPassword.c_str();
unsigned off = 0;
while (pszPassword[off])
{
char ch;
vrc = RTTcpRead(Sock, &ch, sizeof(ch), NULL);
if ( RT_FAILURE(vrc)
|| pszPassword[off] != ch)
{
if (RT_FAILURE(vrc))
LogRel(("Teleporter: Password read failure (off=%u): %Rrc\n", off, vrc));
else
LogRel(("Teleporter: Invalid password (off=%u)\n", off));
teleporterTcpWriteNACK(pState, VERR_AUTHENTICATION_FAILURE);
return VINF_SUCCESS;
}
off++;
}
vrc = teleporterTcpWriteACK(pState);
if (RT_FAILURE(vrc))
return VINF_SUCCESS;
/*
* Update the progress bar, with peer name if available.
*/
HRESULT hrc;
RTNETADDR Addr;
vrc = RTTcpGetPeerAddress(Sock, &Addr);
if (RT_SUCCESS(vrc))
{
LogRel(("Teleporter: Incoming VM from %RTnaddr!\n", &Addr));
hrc = pState->mptrProgress->SetNextOperation(BstrFmt(tr("Teleporting VM from %RTnaddr"), &Addr).raw(), 8);
}
else
{
LogRel(("Teleporter: Incoming VM!\n"));
hrc = pState->mptrProgress->SetNextOperation(Bstr(tr("Teleporting VM")).raw(), 8);
}
AssertMsg(SUCCEEDED(hrc) || hrc == E_FAIL, ("%Rhrc\n", hrc));
/*
* Stop the server and cancel the timeout timer.
*
* Note! After this point we must return VERR_TCP_SERVER_STOP, while prior
* to it we must not return that value!
*/
RTTcpServerShutdown(pState->mhServer);
RTTimerLRDestroy(*pState->mphTimerLR);
*pState->mphTimerLR = NIL_RTTIMERLR;
/*
* Command processing loop.
*/
bool fDone = false;
for (;;)
{
char szCmd[128];
vrc = teleporterTcpReadLine(pState, szCmd, sizeof(szCmd));
if (RT_FAILURE(vrc))
break;
if (!strcmp(szCmd, "load"))
{
vrc = teleporterTcpWriteACK(pState);
if (RT_FAILURE(vrc))
break;
int vrc2 = VMR3AtErrorRegisterU(pState->mpUVM,
Console::genericVMSetErrorCallback, &pState->mErrorText);
AssertRC(vrc2);
RTSocketRetain(pState->mhSocket); /* For concurrent access by I/O thread and EMT. */
pState->moffStream = 0;
void *pvUser2 = static_cast<void *>(static_cast<TeleporterState *>(pState));
vrc = VMR3LoadFromStream(VMR3GetVM(pState->mpUVM),
&g_teleporterTcpOps, pvUser2,
teleporterProgressCallback, pvUser2);
RTSocketRelease(pState->mhSocket);
vrc2 = VMR3AtErrorDeregister(VMR3GetVM(pState->mpUVM), Console::genericVMSetErrorCallback, &pState->mErrorText);
//.........這裏部分代碼省略.........
示例9: vboxNetFltDarwinMBufFromSG
/**
* Internal worker that create a darwin mbuf for a (scatter/)gather list.
*
* @returns Pointer to the mbuf.
* @param pThis The instance.
* @param pSG The (scatter/)gather list.
*/
static mbuf_t vboxNetFltDarwinMBufFromSG(PVBOXNETFLTINS pThis, PINTNETSG pSG)
{
/// @todo future? mbuf_how_t How = preemption enabled ? MBUF_DONTWAIT : MBUF_WAITOK;
mbuf_how_t How = MBUF_WAITOK;
/*
* We need some way of getting back to our instance data when
* the mbuf is freed, so use pvUserData for this.
* -- this is not relevant anylonger! --
*/
Assert(!pSG->pvUserData || pSG->pvUserData == pThis);
Assert(!pSG->pvUserData2);
pSG->pvUserData = pThis;
/*
* Allocate a packet and copy over the data.
*
* Using mbuf_attachcluster() here would've been nice but there are two
* issues with it: (1) it's 10.5.x only, and (2) the documentation indicates
* that it's not supposed to be used for really external buffers. The 2nd
* point might be argued against considering that the only m_clattach user
* is mallocs memory for the ext mbuf and not doing what's stated in the docs.
* However, it's hard to tell if these m_clattach buffers actually makes it
* to the NICs or not, and even if they did, the NIC would need the physical
* addresses for the pages they contain and might end up copying the data
* to a new mbuf anyway.
*
* So, in the end it's better to just do it the simple way that will work
* 100%, even if it involves some extra work (alloc + copy) we really wished
* to avoid.
*
* Note. We can't make use of the physical addresses on darwin because the
* way the mbuf / cluster stuff works (see mbuf_data_to_physical and
* mcl_to_paddr).
*/
mbuf_t pPkt = NULL;
errno_t err = mbuf_allocpacket(How, pSG->cbTotal, NULL, &pPkt);
if (!err)
{
/* Skip zero sized memory buffers (paranoia). */
mbuf_t pCur = pPkt;
while (pCur && !mbuf_maxlen(pCur))
pCur = mbuf_next(pCur);
Assert(pCur);
/* Set the required packet header attributes. */
mbuf_pkthdr_setlen(pPkt, pSG->cbTotal);
mbuf_pkthdr_setheader(pPkt, mbuf_data(pCur));
/* Special case the single buffer copy. */
if ( mbuf_next(pCur)
&& mbuf_maxlen(pCur) >= pSG->cbTotal)
{
mbuf_setlen(pCur, pSG->cbTotal);
IntNetSgRead(pSG, mbuf_data(pCur));
}
else
{
/* Multi buffer copying. */
size_t cbLeft = pSG->cbTotal;
size_t offSrc = 0;
while (cbLeft > 0 && pCur)
{
size_t cb = mbuf_maxlen(pCur);
if (cb > cbLeft)
cb = cbLeft;
mbuf_setlen(pCur, cb);
IntNetSgReadEx(pSG, offSrc, cb, mbuf_data(pCur));
/* advance */
offSrc += cb;
cbLeft -= cb;
pCur = mbuf_next(pCur);
}
Assert(cbLeft == 0);
}
if (!err)
{
/*
* Tag the packet and return successfully.
*/
PVBOXNETFLTTAG pTagData;
err = mbuf_tag_allocate(pPkt, g_idTag, 0 /* type */, sizeof(VBOXNETFLTTAG) /* tag len */, How, (void **)&pTagData);
if (!err)
{
Assert(pSG->aSegs[0].cb >= sizeof(pTagData->EthHdr));
memcpy(&pTagData->EthHdr, pSG->aSegs[0].pv, sizeof(pTagData->EthHdr));
return pPkt;
}
/* bailout: */
AssertMsg(err == ENOMEM || err == EWOULDBLOCK, ("err=%d\n", err));
}
//.........這裏部分代碼省略.........
示例10: DECLINLINE
/**
* Initializes a SG list from an mbuf.
*
* @returns Number of segments.
* @param pThis The instance.
* @param pMBuf The mbuf.
* @param pSG The SG.
* @param pvFrame The frame pointer, optional.
* @param cSegs The number of segments allocated for the SG.
* This should match the number in the mbuf exactly!
* @param fSrc The source of the frame.
*/
DECLINLINE(void) vboxNetFltDarwinMBufToSG(PVBOXNETFLTINS pThis, mbuf_t pMBuf, void *pvFrame, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc)
{
NOREF(pThis);
/*
* Walk the chain and convert the buffers to segments. Works INTNETSG::cbTotal.
*/
unsigned iSeg = 0;
IntNetSgInitTempSegs(pSG, 0 /*cbTotal*/, cSegs, 0 /*cSegsUsed*/);
for (mbuf_t pCur = pMBuf; pCur; pCur = mbuf_next(pCur))
{
size_t cbSeg = mbuf_len(pCur);
if (cbSeg)
{
void *pvSeg = mbuf_data(pCur);
/* deal with pvFrame */
if (!iSeg && pvFrame && pvFrame != pvSeg)
{
void *pvStart = mbuf_datastart(pMBuf);
uintptr_t offSeg = (uintptr_t)pvSeg - (uintptr_t)pvStart;
uintptr_t offSegEnd = offSeg + cbSeg;
Assert(pvStart && pvSeg && offSeg < mbuf_maxlen(pMBuf) && offSegEnd <= mbuf_maxlen(pMBuf)); NOREF(offSegEnd);
uintptr_t offFrame = (uintptr_t)pvFrame - (uintptr_t)pvStart;
if (RT_LIKELY(offFrame < offSeg))
{
pvSeg = pvFrame;
cbSeg += offSeg - offFrame;
}
else
AssertMsgFailed(("pvFrame=%p pvStart=%p pvSeg=%p offSeg=%p cbSeg=%#zx offSegEnd=%p offFrame=%p maxlen=%#zx\n",
pvFrame, pvStart, pvSeg, offSeg, cbSeg, offSegEnd, offFrame, mbuf_maxlen(pMBuf)));
pvFrame = NULL;
}
AssertBreak(iSeg < cSegs);
pSG->cbTotal += cbSeg;
pSG->aSegs[iSeg].cb = cbSeg;
pSG->aSegs[iSeg].pv = pvSeg;
pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;
iSeg++;
}
/* The pvFrame might be in a now empty buffer. */
else if ( !iSeg
&& pvFrame
&& (uintptr_t)pvFrame - (uintptr_t)mbuf_datastart(pMBuf) < mbuf_maxlen(pMBuf))
{
cbSeg = (uintptr_t)mbuf_datastart(pMBuf) + mbuf_maxlen(pMBuf) - (uintptr_t)pvFrame;
pSG->cbTotal += cbSeg;
pSG->aSegs[iSeg].cb = cbSeg;
pSG->aSegs[iSeg].pv = pvFrame;
pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;
iSeg++;
pvFrame = NULL;
}
}
Assert(iSeg && iSeg <= cSegs);
pSG->cSegsUsed = iSeg;
#ifdef PADD_RUNT_FRAMES_FROM_HOST
/*
* Add a trailer if the frame is too small.
*
* Since we're getting to the packet before it is framed, it has not
* yet been padded. The current solution is to add a segment pointing
* to a buffer containing all zeros and pray that works for all frames...
*/
if (pSG->cbTotal < 60 && (fSrc & INTNETTRUNKDIR_HOST))
{
AssertReturnVoid(iSeg < cSegs);
static uint8_t const s_abZero[128] = {0};
pSG->aSegs[iSeg].Phys = NIL_RTHCPHYS;
pSG->aSegs[iSeg].pv = (void *)&s_abZero[0];
pSG->aSegs[iSeg].cb = 60 - pSG->cbTotal;
pSG->cbTotal = 60;
pSG->cSegsUsed++;
}
#endif
#ifdef VBOXNETFLT_DARWIN_TEST_SEG_SIZE
/*
* Redistribute the segments.
*/
if (pSG->cSegsUsed < pSG->cSegsAlloc)
{
/* copy the segments to the end. */
//.........這裏部分代碼省略.........
示例11: vboxNetFltPortOsSetActive
void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive)
{
ifnet_t pIfNet = vboxNetFltDarwinRetainIfNet(pThis);
if (pIfNet)
{
if (pThis->fDisablePromiscuous)
{
/*
* Promiscuous mode should not be used (wireless), we just need to
* make sure the interface is up.
*/
if (fActive)
{
u_int16_t fIf = ifnet_flags(pIfNet);
if ((fIf & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))
{
ifnet_set_flags(pIfNet, IFF_UP, IFF_UP);
ifnet_ioctl(pIfNet, 0, SIOCSIFFLAGS, NULL);
}
}
}
else
{
/*
* This api is a bit weird, the best reference is the code.
*
* Also, we have a bit or race conditions wrt the maintenance of
* host the interface promiscuity for vboxNetFltPortOsIsPromiscuous.
*/
unsigned const cPromiscBefore = VBOX_GET_PCOUNT(pIfNet);
u_int16_t fIf;
if (fActive)
{
Assert(!pThis->u.s.fSetPromiscuous);
errno_t err = ENETDOWN;
ASMAtomicWriteBool(&pThis->u.s.fNeedSetPromiscuous, true);
/*
* Try bring the interface up and running if it's down.
*/
fIf = ifnet_flags(pIfNet);
if ((fIf & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))
{
err = ifnet_set_flags(pIfNet, IFF_UP, IFF_UP);
errno_t err2 = ifnet_ioctl(pIfNet, 0, SIOCSIFFLAGS, NULL);
if (!err)
err = err2;
fIf = ifnet_flags(pIfNet);
}
/*
* Is it already up? If it isn't, leave it to the link event or
* we'll upset if_pcount (as stated above, ifnet_set_promiscuous is weird).
*/
if ((fIf & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
{
err = ifnet_set_promiscuous(pIfNet, 1);
pThis->u.s.fSetPromiscuous = err == 0;
if (!err)
{
ASMAtomicWriteBool(&pThis->u.s.fNeedSetPromiscuous, false);
/* check if it actually worked, this stuff is not always behaving well. */
if (!(ifnet_flags(pIfNet) & IFF_PROMISC))
{
err = ifnet_set_flags(pIfNet, IFF_PROMISC, IFF_PROMISC);
if (!err)
err = ifnet_ioctl(pIfNet, 0, SIOCSIFFLAGS, NULL);
if (!err)
Log(("vboxNetFlt: fixed IFF_PROMISC on %s (%d->%d)\n", pThis->szName, cPromiscBefore, VBOX_GET_PCOUNT(pIfNet)));
else
Log(("VBoxNetFlt: failed to fix IFF_PROMISC on %s, err=%d (%d->%d)\n",
pThis->szName, err, cPromiscBefore, VBOX_GET_PCOUNT(pIfNet)));
}
}
else
Log(("VBoxNetFlt: ifnet_set_promiscuous -> err=%d grr! (%d->%d)\n", err, cPromiscBefore, VBOX_GET_PCOUNT(pIfNet)));
}
else if (!err)
Log(("VBoxNetFlt: Waiting for the link to come up... (%d->%d)\n", cPromiscBefore, VBOX_GET_PCOUNT(pIfNet)));
if (err)
LogRel(("VBoxNetFlt: Failed to put '%s' into promiscuous mode, err=%d (%d->%d)\n", pThis->szName, err, cPromiscBefore, VBOX_GET_PCOUNT(pIfNet)));
}
else
{
ASMAtomicWriteBool(&pThis->u.s.fNeedSetPromiscuous, false);
if (pThis->u.s.fSetPromiscuous)
{
errno_t err = ifnet_set_promiscuous(pIfNet, 0);
AssertMsg(!err, ("%d\n", err)); NOREF(err);
}
pThis->u.s.fSetPromiscuous = false;
fIf = ifnet_flags(pIfNet);
Log(("VBoxNetFlt: fIf=%#x; %d->%d\n", fIf, cPromiscBefore, VBOX_GET_PCOUNT(pIfNet)));
}
}
vboxNetFltDarwinReleaseIfNet(pThis, pIfNet);
}
//.........這裏部分代碼省略.........
示例12: drvdiskintReadVerify
/**
* Verifies a read request.
*
* @returns VBox status code.
* @param pThis Disk integrity driver instance data.
* @param paSeg Segment array of the containing the data buffers to verify.
* @param cSeg Number of segments.
* @param off Start offset.
* @param cbWrite Number of bytes to verify.
*/
static int drvdiskintReadVerify(PDRVDISKINTEGRITY pThis, PCRTSGSEG paSeg, unsigned cSeg,
uint64_t off, size_t cbRead)
{
int rc = VINF_SUCCESS;
LogFlowFunc(("pThis=%#p paSeg=%#p cSeg=%u off=%llx cbRead=%u\n",
pThis, paSeg, cSeg, off, cbRead));
Assert(off % 512 == 0);
Assert(cbRead % 512 == 0);
/* Compare read data */
size_t cbLeft = cbRead;
RTFOFF offCurr = (RTFOFF)off;
RTSGBUF SgBuf;
RTSgBufInit(&SgBuf, paSeg, cSeg);
while (cbLeft)
{
PDRVDISKSEGMENT pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetRangeGet(pThis->pTreeSegments, offCurr);
size_t cbRange = 0;
bool fCmp = false;
unsigned offSeg = 0;
if (!pSeg)
{
/* Get next segment */
pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetGetBestFit(pThis->pTreeSegments, offCurr, true);
if (!pSeg)
{
/* No data in the tree for this read. Assume everything is ok. */
cbRange = cbLeft;
}
else if (offCurr + (RTFOFF)cbLeft <= pSeg->Core.Key)
cbRange = cbLeft;
else
cbRange = pSeg->Core.Key - offCurr;
}
else
{
fCmp = true;
offSeg = offCurr - pSeg->Core.Key;
cbRange = RT_MIN(cbLeft, (size_t)(pSeg->Core.KeyLast + 1 - offCurr));
}
if (fCmp)
{
RTSGSEG Seg;
RTSGBUF SgBufCmp;
size_t cbOff = 0;
Seg.cbSeg = cbRange;
Seg.pvSeg = pSeg->pbSeg + offSeg;
RTSgBufInit(&SgBufCmp, &Seg, 1);
if (RTSgBufCmpEx(&SgBuf, &SgBufCmp, cbRange, &cbOff, true))
{
/* Corrupted disk, print I/O log entry of the last write which accessed this range. */
uint32_t cSector = (offSeg + cbOff) / 512;
AssertMsg(cSector < pSeg->cIoLogEntries, ("Internal bug!\n"));
RTMsgError("Corrupted disk at offset %llu (%u bytes in the current read buffer)!\n",
offCurr + cbOff, cbOff);
RTMsgError("Last write to this sector started at offset %llu with %u bytes (%u references to this log entry)\n",
pSeg->apIoLog[cSector]->off,
pSeg->apIoLog[cSector]->cbWrite,
pSeg->apIoLog[cSector]->cRefs);
RTAssertDebugBreak();
}
}
else
RTSgBufAdvance(&SgBuf, cbRange);
offCurr += cbRange;
cbLeft -= cbRange;
}
return rc;
}
示例13: drvdiskintWriteRecord
/**
* Record a successful write to the virtual disk.
*
* @returns VBox status code.
* @param pThis Disk integrity driver instance data.
* @param paSeg Segment array of the write to record.
* @param cSeg Number of segments.
* @param off Start offset.
* @param cbWrite Number of bytes to record.
*/
static int drvdiskintWriteRecord(PDRVDISKINTEGRITY pThis, PCRTSGSEG paSeg, unsigned cSeg,
uint64_t off, size_t cbWrite)
{
int rc = VINF_SUCCESS;
LogFlowFunc(("pThis=%#p paSeg=%#p cSeg=%u off=%llx cbWrite=%u\n",
pThis, paSeg, cSeg, off, cbWrite));
/* Update the segments */
size_t cbLeft = cbWrite;
RTFOFF offCurr = (RTFOFF)off;
RTSGBUF SgBuf;
PIOLOGENT pIoLogEnt = (PIOLOGENT)RTMemAllocZ(sizeof(IOLOGENT));
if (!pIoLogEnt)
return VERR_NO_MEMORY;
pIoLogEnt->off = off;
pIoLogEnt->cbWrite = cbWrite;
pIoLogEnt->cRefs = 0;
RTSgBufInit(&SgBuf, paSeg, cSeg);
while (cbLeft)
{
PDRVDISKSEGMENT pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetRangeGet(pThis->pTreeSegments, offCurr);
size_t cbRange = 0;
bool fSet = false;
unsigned offSeg = 0;
if (!pSeg)
{
/* Get next segment */
pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetGetBestFit(pThis->pTreeSegments, offCurr, true);
if ( !pSeg
|| offCurr + (RTFOFF)cbLeft <= pSeg->Core.Key)
cbRange = cbLeft;
else
cbRange = pSeg->Core.Key - offCurr;
Assert(cbRange % 512 == 0);
/* Create new segment */
pSeg = (PDRVDISKSEGMENT)RTMemAllocZ(RT_OFFSETOF(DRVDISKSEGMENT, apIoLog[cbRange / 512]));
if (pSeg)
{
pSeg->Core.Key = offCurr;
pSeg->Core.KeyLast = offCurr + (RTFOFF)cbRange - 1;
pSeg->cbSeg = cbRange;
pSeg->pbSeg = (uint8_t *)RTMemAllocZ(cbRange);
pSeg->cIoLogEntries = cbRange / 512;
if (!pSeg->pbSeg)
RTMemFree(pSeg);
else
{
bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core);
AssertMsg(fInserted, ("Bug!\n"));
fSet = true;
}
}
}
else
{
fSet = true;
offSeg = offCurr - pSeg->Core.Key;
cbRange = RT_MIN(cbLeft, (size_t)(pSeg->Core.KeyLast + 1 - offCurr));
}
if (fSet)
{
AssertPtr(pSeg);
size_t cbCopied = RTSgBufCopyToBuf(&SgBuf, pSeg->pbSeg + offSeg, cbRange);
Assert(cbCopied == cbRange);
/* Update the I/O log pointers */
Assert(offSeg % 512 == 0);
Assert(cbRange % 512 == 0);
while (offSeg < cbRange)
{
uint32_t uSector = offSeg / 512;
PIOLOGENT pIoLogOld = NULL;
AssertMsg(uSector < pSeg->cIoLogEntries, ("Internal bug!\n"));
pIoLogOld = pSeg->apIoLog[uSector];
if (pIoLogOld)
{
pIoLogOld->cRefs--;
if (!pIoLogOld->cRefs)
RTMemFree(pIoLogOld);
}
//.........這裏部分代碼省略.........
示例14: DECLINLINE
/**
* Allocates a page from the page pool.
*
* @returns Pointer to allocated page(s).
* @returns NULL on failure.
* @param pPool Pointer to the page pool.
* @thread The Emulation Thread.
*/
DECLINLINE(void *) mmR3PagePoolAlloc(PMMPAGEPOOL pPool)
{
VM_ASSERT_EMT(pPool->pVM);
STAM_COUNTER_INC(&pPool->cAllocCalls);
/*
* Walk free list.
*/
if (pPool->pHeadFree)
{
PMMPAGESUBPOOL pSub = pPool->pHeadFree;
/* decrement free count and unlink if no more free entries. */
if (!--pSub->cPagesFree)
pPool->pHeadFree = pSub->pNextFree;
#ifdef VBOX_WITH_STATISTICS
pPool->cFreePages--;
#endif
/* find free spot in bitmap. */
#ifdef USE_INLINE_ASM_BIT_OPS
const int iPage = ASMBitFirstClear(pSub->auBitmap, pSub->cPages);
if (iPage >= 0)
{
Assert(!ASMBitTest(pSub->auBitmap, iPage));
ASMBitSet(pSub->auBitmap, iPage);
return (uint8_t *)pSub->pvPages + PAGE_SIZE * iPage;
}
#else
unsigned *pu = &pSub->auBitmap[0];
unsigned *puEnd = &pSub->auBitmap[pSub->cPages / (sizeof(pSub->auBitmap) * 8)];
while (pu < puEnd)
{
unsigned u;
if ((u = *pu) != ~0U)
{
unsigned iBit = 0;
unsigned uMask = 1;
while (iBit < sizeof(pSub->auBitmap[0]) * 8)
{
if (!(u & uMask))
{
*pu |= uMask;
return (uint8_t *)pSub->pvPages
+ PAGE_SIZE * (iBit + ((uint8_t *)pu - (uint8_t *)&pSub->auBitmap[0]) * 8);
}
iBit++;
uMask <<= 1;
}
STAM_COUNTER_INC(&pPool->cErrors);
AssertMsgFailed(("how odd, expected to find a free bit in %#x, but didn't\n", u));
}
/* next */
pu++;
}
#endif
STAM_COUNTER_INC(&pPool->cErrors);
#ifdef VBOX_WITH_STATISTICS
pPool->cFreePages++;
#endif
AssertMsgFailed(("how strange, expected to find a free bit in %p, but didn't (%d pages supposed to be free!)\n", pSub, pSub->cPagesFree + 1));
}
/*
* Allocate new subpool.
*/
unsigned cPages = !pPool->fLow ? 128 : 32;
PMMPAGESUBPOOL pSub;
int rc = MMHyperAlloc(pPool->pVM,
RT_OFFSETOF(MMPAGESUBPOOL, auBitmap[cPages / (sizeof(pSub->auBitmap[0]) * 8)])
+ (sizeof(SUPPAGE) + sizeof(MMPPLOOKUPHCPHYS)) * cPages
+ sizeof(MMPPLOOKUPHCPTR),
0,
MM_TAG_MM_PAGE,
(void **)&pSub);
if (RT_FAILURE(rc))
return NULL;
PSUPPAGE paPhysPages = (PSUPPAGE)&pSub->auBitmap[cPages / (sizeof(pSub->auBitmap[0]) * 8)];
Assert((uintptr_t)paPhysPages >= (uintptr_t)&pSub->auBitmap[1]);
if (!pPool->fLow)
{
rc = SUPR3PageAllocEx(cPages,
0 /* fFlags */,
&pSub->pvPages,
NULL,
paPhysPages);
if (RT_FAILURE(rc))
rc = VMSetError(pPool->pVM, rc, RT_SRC_POS,
N_("Failed to lock host %zd bytes of memory (out of memory)"), (size_t)cPages << PAGE_SHIFT);
}
else
rc = SUPR3LowAlloc(cPages, &pSub->pvPages, NULL, paPhysPages);
//.........這裏部分代碼省略.........
示例15: RTR0DECL
/**
* Allocates physical contiguous memory (below 4GB).
* The allocation is page aligned and the content is undefined.
*
* @returns Pointer to the memory block. This is page aligned.
* @param pPhys Where to store the physical address.
* @param cb The allocation size in bytes. This is always
* rounded up to PAGE_SIZE.
*/
RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb)
{
int cOrder;
unsigned cPages;
struct page *paPages;
/*
* validate input.
*/
Assert(VALID_PTR(pPhys));
Assert(cb > 0);
/*
* Allocate page pointer array.
*/
cb = RT_ALIGN_Z(cb, PAGE_SIZE);
cPages = cb >> PAGE_SHIFT;
cOrder = CalcPowerOf2Order(cPages);
#if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32)
/* ZONE_DMA32: 0-4GB */
paPages = alloc_pages(GFP_DMA32 | __GFP_NOWARN, cOrder);
if (!paPages)
#endif
#ifdef RT_ARCH_AMD64
/* ZONE_DMA; 0-16MB */
paPages = alloc_pages(GFP_DMA | __GFP_NOWARN, cOrder);
#else
/* ZONE_NORMAL: 0-896MB */
paPages = alloc_pages(GFP_USER | __GFP_NOWARN, cOrder);
#endif
if (paPages)
{
/*
* Reserve the pages and mark them executable.
*/
unsigned iPage;
for (iPage = 0; iPage < cPages; iPage++)
{
Assert(!PageHighMem(&paPages[iPage]));
if (iPage + 1 < cPages)
{
AssertMsg( (uintptr_t)phys_to_virt(page_to_phys(&paPages[iPage])) + PAGE_SIZE
== (uintptr_t)phys_to_virt(page_to_phys(&paPages[iPage + 1]))
&& page_to_phys(&paPages[iPage]) + PAGE_SIZE
== page_to_phys(&paPages[iPage + 1]),
("iPage=%i cPages=%u [0]=%#llx,%p [1]=%#llx,%p\n", iPage, cPages,
(long long)page_to_phys(&paPages[iPage]), phys_to_virt(page_to_phys(&paPages[iPage])),
(long long)page_to_phys(&paPages[iPage + 1]), phys_to_virt(page_to_phys(&paPages[iPage + 1])) ));
}
SetPageReserved(&paPages[iPage]);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 20) /** @todo find the exact kernel where change_page_attr was introduced. */
MY_SET_PAGES_EXEC(&paPages[iPage], 1);
#endif
}
*pPhys = page_to_phys(paPages);
return phys_to_virt(page_to_phys(paPages));
}
return NULL;
}