/** * The slave DPC callback for an omni timer. * * @param pDpc The DPC object. * @param pvUser Pointer to the sub-timer. * @param SystemArgument1 Some system stuff. * @param SystemArgument2 Some system stuff. */ static void _stdcall rtTimerNtOmniSlaveCallback(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PRTTIMERNTSUBTIMER pSubTimer = (PRTTIMERNTSUBTIMER)pvUser; PRTTIMER pTimer = pSubTimer->pParent; AssertPtr(pTimer); #ifdef RT_STRICT if (KeGetCurrentIrql() < DISPATCH_LEVEL) RTAssertMsg2Weak("rtTimerNtOmniSlaveCallback: Irql=%d expected >=%d\n", KeGetCurrentIrql(), DISPATCH_LEVEL); int iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId()); if (pSubTimer - &pTimer->aSubTimers[0] != iCpuSelf) RTAssertMsg2Weak("rtTimerNtOmniSlaveCallback: iCpuSelf=%d pSubTimer=%p / %d\n", iCpuSelf, pSubTimer, pSubTimer - &pTimer->aSubTimers[0]); #endif /* * Check that we haven't been suspended before doing the callout. */ if ( !ASMAtomicUoReadBool(&pTimer->fSuspended) && pTimer->u32Magic == RTTIMER_MAGIC) { if (!pTimer->u64NanoInterval) ASMAtomicWriteBool(&pTimer->fSuspended, true); pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick); } NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2); }
/** * The timer callback for an omni-timer. * * This is responsible for queueing the DPCs for the other CPUs and * perform the callback on the CPU on which it is called. * * @param pDpc The DPC object. * @param pvUser Pointer to the sub-timer. * @param SystemArgument1 Some system stuff. * @param SystemArgument2 Some system stuff. */ static void _stdcall rtTimerNtOmniMasterCallback(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PRTTIMERNTSUBTIMER pSubTimer = (PRTTIMERNTSUBTIMER)pvUser; PRTTIMER pTimer = pSubTimer->pParent; int iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId()); AssertPtr(pTimer); #ifdef RT_STRICT if (KeGetCurrentIrql() < DISPATCH_LEVEL) RTAssertMsg2Weak("rtTimerNtOmniMasterCallback: Irql=%d expected >=%d\n", KeGetCurrentIrql(), DISPATCH_LEVEL); if (pSubTimer - &pTimer->aSubTimers[0] != iCpuSelf) RTAssertMsg2Weak("rtTimerNtOmniMasterCallback: iCpuSelf=%d pSubTimer=%p / %d\n", iCpuSelf, pSubTimer, pSubTimer - &pTimer->aSubTimers[0]); #endif /* * Check that we haven't been suspended before scheduling the other DPCs * and doing the callout. */ if ( !ASMAtomicUoReadBool(&pTimer->fSuspended) && pTimer->u32Magic == RTTIMER_MAGIC) { RTCPUSET OnlineSet; RTMpGetOnlineSet(&OnlineSet); for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu) && iCpuSelf != iCpu) KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0); pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick); } NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2); }
RTDECL(int) RTTimerDestroy(PRTTIMER pTimer) { /* It's ok to pass NULL pointer. */ if (pTimer == /*NIL_RTTIMER*/ NULL) return VINF_SUCCESS; AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); /* * We do not support destroying a timer from the callback because it is * not 101% safe since we cannot flush DPCs. Solaris has the same restriction. */ AssertReturn(KeGetCurrentIrql() == PASSIVE_LEVEL, VERR_INVALID_CONTEXT); /* * Invalidate the timer, stop it if it's running and finally * free up the memory. */ ASMAtomicWriteU32(&pTimer->u32Magic, ~RTTIMER_MAGIC); if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) rtTimerNtStopWorker(pTimer); /* * Flush DPCs to be on the safe side. */ if (g_pfnrtNtKeFlushQueuedDpcs) g_pfnrtNtKeFlushQueuedDpcs(); RTMemFree(pTimer); return VINF_SUCCESS; }
VBoxDbgConsole::backRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead) { VBoxDbgConsole *pThis = VBOXDBGCONSOLE_FROM_DBGCBACK(pBack); Assert(pcbRead); /** @todo implement this bit */ if (pcbRead) *pcbRead = 0; pThis->lock(); int rc = VINF_SUCCESS; if (!ASMAtomicUoReadBool(&pThis->m_fTerminate)) { if (pThis->m_cbInputBuf) { const char *psz = pThis->m_pszInputBuf; size_t cbRead = RT_MIN(pThis->m_cbInputBuf, cbBuf); memcpy(pvBuf, psz, cbRead); psz += cbRead; pThis->m_cbInputBuf -= cbRead; if (*psz) memmove(pThis->m_pszInputBuf, psz, pThis->m_cbInputBuf); pThis->m_pszInputBuf[pThis->m_cbInputBuf] = '\0'; *pcbRead = cbRead; } } else rc = VERR_GENERAL_FAILURE; pThis->unlock(); return rc; }
/** * Timer callback function for the non-omni timers. * * @returns HRTIMER_NORESTART or HRTIMER_RESTART depending on whether it's a one-shot or interval timer. * @param pDpc Pointer to the DPC. * @param pvUser Pointer to our internal timer structure. * @param SystemArgument1 Some system argument. * @param SystemArgument2 Some system argument. */ static void _stdcall rtTimerNtSimpleCallback(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PRTTIMER pTimer = (PRTTIMER)pvUser; AssertPtr(pTimer); #ifdef RT_STRICT if (KeGetCurrentIrql() < DISPATCH_LEVEL) RTAssertMsg2Weak("rtTimerNtSimpleCallback: Irql=%d expected >=%d\n", KeGetCurrentIrql(), DISPATCH_LEVEL); #endif /* * Check that we haven't been suspended before doing the callout. */ if ( !ASMAtomicUoReadBool(&pTimer->fSuspended) && pTimer->u32Magic == RTTIMER_MAGIC) { ASMAtomicWriteHandle(&pTimer->aSubTimers[0].hActiveThread, RTThreadNativeSelf()); if (!pTimer->u64NanoInterval) ASMAtomicWriteBool(&pTimer->fSuspended, true); uint64_t iTick = ++pTimer->aSubTimers[0].iTick; if (pTimer->u64NanoInterval) rtTimerNtRearmInternval(pTimer, iTick, &pTimer->aSubTimers[0].NtDpc); pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick); ASMAtomicWriteHandle(&pTimer->aSubTimers[0].hActiveThread, NIL_RTNATIVETHREAD); } NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2); }
bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis) { struct ifnet *ifp, *ifp0; ifp = ASMAtomicUoReadPtrT(&pThis->u.s.ifp, struct ifnet *); VBOXCURVNET_SET(ifp->if_vnet); /* * Attempt to check if the interface is still there and re-initialize if * something has changed. */ ifp0 = ifunit(pThis->szName); if (ifp != ifp0) { ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, true); ng_rmnode_self(pThis->u.s.node); pThis->u.s.node = NULL; } if (ifp0 != NULL) { vboxNetFltOsDeleteInstance(pThis); vboxNetFltOsInitInstance(pThis, NULL); } VBOXCURVNET_RESTORE(); return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost); }
VBoxDbgConsole::backThread(RTTHREAD Thread, void *pvUser) { VBoxDbgConsole *pThis = (VBoxDbgConsole *)pvUser; LogFlow(("backThread: Thread=%p pvUser=%p\n", (void *)Thread, pvUser)); NOREF(Thread); /* * Create and execute the console. */ int rc = pThis->dbgcCreate(&pThis->m_Back.Core, 0); ASMAtomicUoWriteBool(&pThis->m_fThreadTerminated, true); if (!ASMAtomicUoReadBool(&pThis->m_fTerminate)) QApplication::postEvent(pThis, new VBoxDbgConsoleEvent(rc == VINF_SUCCESS ? VBoxDbgConsoleEvent::kTerminatedUser : VBoxDbgConsoleEvent::kTerminatedOther)); LogFlow(("backThread: returns %Rrc (m_fTerminate=%RTbool)\n", rc, ASMAtomicUoReadBool(&pThis->m_fTerminate))); return rc; }
RTDECL(RTTHREADSTATE) RTThreadGetReallySleeping(RTTHREAD hThread) { RTTHREADSTATE enmState = RTTHREADSTATE_INVALID; PRTTHREADINT pThread = rtThreadGet(hThread); if (pThread) { enmState = rtThreadGetState(pThread); if (!ASMAtomicUoReadBool(&pThread->fReallySleeping)) enmState = RTTHREADSTATE_RUNNING; rtThreadRelease(pThread); } return enmState; }
RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First) { /* * Validate. */ AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) return VERR_TIMER_ACTIVE; if ( pTimer->fSpecificCpu && !RTMpIsCpuOnline(pTimer->idCpu)) return VERR_CPU_OFFLINE; /* * Start the timer. */ PKDPC pMasterDpc = pTimer->fOmniTimer ? &pTimer->aSubTimers[RTMpCpuIdToSetIndex(pTimer->idCpu)].NtDpc : &pTimer->aSubTimers[0].NtDpc; #ifndef RTR0TIMER_NT_MANUAL_RE_ARM uint64_t u64Interval = pTimer->u64NanoInterval / 1000000; /* This is ms, believe it or not. */ ULONG ulInterval = (ULONG)u64Interval; if (ulInterval != u64Interval) ulInterval = MAXLONG; else if (!ulInterval && pTimer->u64NanoInterval) ulInterval = 1; #endif LARGE_INTEGER DueTime; DueTime.QuadPart = -(int64_t)(u64First / 100); /* Relative, NT time. */ if (!DueTime.QuadPart) DueTime.QuadPart = -1; unsigned cSubTimers = pTimer->fOmniTimer ? pTimer->cSubTimers : 1; for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++) pTimer->aSubTimers[iCpu].iTick = 0; ASMAtomicWriteS32(&pTimer->cOmniSuspendCountDown, 0); ASMAtomicWriteBool(&pTimer->fSuspended, false); #ifdef RTR0TIMER_NT_MANUAL_RE_ARM pTimer->uNtStartTime = rtTimerNtQueryInterruptTime() + u64First / 100; KeSetTimerEx(&pTimer->NtTimer, DueTime, 0, pMasterDpc); #else KeSetTimerEx(&pTimer->NtTimer, DueTime, ulInterval, pMasterDpc); #endif return VINF_SUCCESS; }
RTDECL(int) RTTimerStop(PRTTIMER pTimer) { /* * Validate. */ AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); if (ASMAtomicUoReadBool(&pTimer->fSuspended)) return VERR_TIMER_SUSPENDED; /* * Call the worker we share with RTTimerDestroy. */ rtTimerNtStopWorker(pTimer); return VINF_SUCCESS; }
/** * Timer callback function for the non-omni timers. * * @returns HRTIMER_NORESTART or HRTIMER_RESTART depending on whether it's a one-shot or interval timer. * @param pDpc Pointer to the DPC. * @param pvUser Pointer to our internal timer structure. * @param SystemArgument1 Some system argument. * @param SystemArgument2 Some system argument. */ static void _stdcall rtTimerNtSimpleCallback(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PRTTIMER pTimer = (PRTTIMER)pvUser; AssertPtr(pTimer); #ifdef RT_STRICT if (KeGetCurrentIrql() < DISPATCH_LEVEL) RTAssertMsg2Weak("rtTimerNtSimpleCallback: Irql=%d expected >=%d\n", KeGetCurrentIrql(), DISPATCH_LEVEL); #endif /* * Check that we haven't been suspended before doing the callout. */ if ( !ASMAtomicUoReadBool(&pTimer->fSuspended) && pTimer->u32Magic == RTTIMER_MAGIC) pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->aSubTimers[0].iTick); NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2); }
/** * Helper for determining whether the host wants the interface to be * promiscuous. */ static bool vboxNetFltDarwinIsPromiscuous(PVBOXNETFLTINS pThis) { bool fRc = false; ifnet_t pIfNet = vboxNetFltDarwinRetainIfNet(pThis); if (pIfNet) { /* gather the data */ uint16_t fIf = ifnet_flags(pIfNet); unsigned cPromisc = VBOX_GET_PCOUNT(pIfNet); bool fSetPromiscuous = ASMAtomicUoReadBool(&pThis->u.s.fSetPromiscuous); vboxNetFltDarwinReleaseIfNet(pThis, pIfNet); /* calc the return. */ fRc = (fIf & IFF_PROMISC) && cPromisc > fSetPromiscuous; } return fRc; }
/** * Reads and retains the host interface handle. * * @returns The handle, NULL if detached. * @param pThis */ DECLINLINE(ifnet_t) vboxNetFltDarwinRetainIfNet(PVBOXNETFLTINS pThis) { ifnet_t pIfNet = NULL; /* * Be careful here to avoid problems racing the detached callback. */ RTSpinlockAcquire(pThis->hSpinlock); if (!ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost)) { pIfNet = ASMAtomicUoReadPtrT(&pThis->u.s.pIfNet, ifnet_t); if (pIfNet) ifnet_reference(pIfNet); } RTSpinlockReleaseNoInts(pThis->hSpinlock); return pIfNet; }
static DECLCALLBACK(int) Once2Thread(RTTHREAD hThread, void *pvUser) { NOREF(hThread); NOREF(pvUser); int rc = RTSemEventMultiWait(g_hEventMulti, RT_INDEFINITE_WAIT); if (RT_FAILURE(rc)) return rc; rc = RTOnce(&g_Once2, Once2CB, (void *)42); if (RT_SUCCESS(rc)) { if (!ASMAtomicUoReadBool(&g_fOnce2Ready)) { RTPrintf("tstOnce: ERROR - Once2CB: Not initialized!\n"); g_cErrors++; } } return rc; }
VBoxDbgConsole::backWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten) { VBoxDbgConsole *pThis = VBOXDBGCONSOLE_FROM_DBGCBACK(pBack); int rc = VINF_SUCCESS; pThis->lock(); if (cbBuf + pThis->m_cbOutputBuf >= pThis->m_cbOutputBufAlloc) { size_t cbNew = RT_ALIGN_Z(cbBuf + pThis->m_cbOutputBufAlloc + 1, 1024); void *pv = RTMemRealloc(pThis->m_pszOutputBuf, cbNew); if (!pv) { pThis->unlock(); if (pcbWritten) *pcbWritten = 0; return VERR_NO_MEMORY; } pThis->m_pszOutputBuf = (char *)pv; pThis->m_cbOutputBufAlloc = cbNew; } /* * Add the output. */ memcpy(pThis->m_pszOutputBuf + pThis->m_cbOutputBuf, pvBuf, cbBuf); pThis->m_cbOutputBuf += cbBuf; pThis->m_pszOutputBuf[pThis->m_cbOutputBuf] = '\0'; if (pcbWritten) *pcbWritten = cbBuf; if (ASMAtomicUoReadBool(&pThis->m_fTerminate)) rc = VERR_GENERAL_FAILURE; /* * Tell the GUI thread to draw this text. * We cannot do it from here without frequent crashes. */ if (!pThis->m_fUpdatePending) QApplication::postEvent(pThis, new VBoxDbgConsoleEvent(VBoxDbgConsoleEvent::kUpdate)); pThis->unlock(); return rc; }
RTDECL(int) RTTimerDestroy(PRTTIMER pTimer) { /* It's ok to pass NULL pointer. */ if (pTimer == /*NIL_RTTIMER*/ NULL) return VINF_SUCCESS; AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); /* * Invalidate the timer, stop it if it's running and finally * free up the memory. */ ASMAtomicWriteU32(&pTimer->u32Magic, ~RTTIMER_MAGIC); if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) rtTimerNtStopWorker(pTimer); RTMemFree(pTimer); return VINF_SUCCESS; }
VBoxDbgConsole::backInput(PDBGCBACK pBack, uint32_t cMillies) { VBoxDbgConsole *pThis = VBOXDBGCONSOLE_FROM_DBGCBACK(pBack); pThis->lock(); bool fRc = true; if (!pThis->m_cbInputBuf) { /* * Wait outside the lock for the requested time, then check again. */ pThis->unlock(); RTSemEventWait(pThis->m_EventSem, cMillies); pThis->lock(); fRc = pThis->m_cbInputBuf || ASMAtomicUoReadBool(&pThis->m_fTerminate); } pThis->unlock(); return fRc; }
RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First) { /* * Validate. */ AssertPtrReturn(pTimer, VERR_INVALID_HANDLE); AssertReturn(pTimer->u32Magic == RTTIMER_MAGIC, VERR_INVALID_HANDLE); if (!ASMAtomicUoReadBool(&pTimer->fSuspended)) return VERR_TIMER_ACTIVE; if ( pTimer->fSpecificCpu && !RTMpIsCpuOnline(pTimer->idCpu)) return VERR_CPU_OFFLINE; /* * Start the timer. */ PKDPC pMasterDpc = pTimer->fOmniTimer ? &pTimer->aSubTimers[RTMpCpuIdToSetIndex(pTimer->idCpu)].NtDpc : &pTimer->aSubTimers[0].NtDpc; uint64_t u64Interval = pTimer->u64NanoInterval / 1000000; /* This is ms, believe it or not. */ ULONG ulInterval = (ULONG)u64Interval; if (ulInterval != u64Interval) ulInterval = MAXLONG; else if (!ulInterval && pTimer->u64NanoInterval) ulInterval = 1; LARGE_INTEGER DueTime; DueTime.QuadPart = -(int64_t)(u64First / 100); /* Relative, NT time. */ if (DueTime.QuadPart) DueTime.QuadPart = -1; ASMAtomicWriteBool(&pTimer->fSuspended, false); KeSetTimerEx(&pTimer->NtTimer, DueTime, ulInterval, pMasterDpc); return VINF_SUCCESS; }
/** * Worker that we can wrap with error variable saving and restoring. */ static bool rtAssertShouldPanicWorker(void) { /* * Check for the VBOX_ASSERT variable. */ const char *psz = RTEnvGet("VBOX_ASSERT"); /* not defined => default behaviour. */ if (!psz) return true; /* 'breakpoint' or 'panic' means default behaviour. */ if (!strcmp(psz, "breakpoint") || !strcmp(psz, "panic")) return true; #ifdef VBOX_RTASSERT_WITH_GDB /* 'gdb' - means try launch a gdb session in xterm. */ if (!strcmp(psz, "gdb")) { /* Did we already fire up gdb? If so, just hit the breakpoint. */ static bool volatile s_fAlreadyLaunchedGdb = false; if (ASMAtomicUoReadBool(&s_fAlreadyLaunchedGdb)) return true; /* Try find a suitable terminal program. */ const char *pszTerm = RTEnvGet("VBOX_ASSERT_TERM"); if ( !pszTerm || !RTPathExists(pszTerm)) { pszTerm = "/usr/bin/gnome-terminal"; if (!RTPathExists(pszTerm)) { pszTerm = "/usr/X11R6/bin/xterm"; if (!RTPathExists(pszTerm)) { pszTerm ="/usr/bin/xterm"; if (!RTPathExists(pszTerm)) return true; } } } /* And find gdb. */ const char *pszGdb = RTEnvGet("VBOX_ASSERT_GDB"); if ( !pszGdb || !RTPathExists(pszGdb)) { pszGdb = "/usr/bin/gdb"; if (!RTPathExists(pszGdb)) pszGdb = "gdb"; } /* Try spawn the process. */ char szCmd[512]; size_t cch = RTStrPrintf(szCmd, sizeof(szCmd), "%s -p %d ", pszGdb, RTProcSelf()); if (cch < sizeof(szCmd)) { char *pszExecName = &szCmd[cch]; if (!RTProcGetExecutablePath(pszExecName, sizeof(szCmd) - cch)) *pszExecName = '\0'; } const char *apszArgs[] = { pszTerm, "-e", szCmd, NULL }; RTPROCESS Process; int rc = RTProcCreate(apszArgs[0], &apszArgs[0], RTENV_DEFAULT, 0, &Process); if (RT_FAILURE(rc)) return false; ASMAtomicWriteBool(&s_fAlreadyLaunchedGdb, true); /* Wait for gdb to attach. */ RTThreadSleep(15000); return true; } #endif /* '*' - don't hit the breakpoint. */ return false; }
/** * The timer callback for an omni-timer. * * This is responsible for queueing the DPCs for the other CPUs and * perform the callback on the CPU on which it is called. * * @param pDpc The DPC object. * @param pvUser Pointer to the sub-timer. * @param SystemArgument1 Some system stuff. * @param SystemArgument2 Some system stuff. */ static void _stdcall rtTimerNtOmniMasterCallback(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PRTTIMERNTSUBTIMER pSubTimer = (PRTTIMERNTSUBTIMER)pvUser; PRTTIMER pTimer = pSubTimer->pParent; int iCpuSelf = RTMpCpuIdToSetIndex(RTMpCpuId()); AssertPtr(pTimer); #ifdef RT_STRICT if (KeGetCurrentIrql() < DISPATCH_LEVEL) RTAssertMsg2Weak("rtTimerNtOmniMasterCallback: Irql=%d expected >=%d\n", KeGetCurrentIrql(), DISPATCH_LEVEL); if (pSubTimer - &pTimer->aSubTimers[0] != iCpuSelf) RTAssertMsg2Weak("rtTimerNtOmniMasterCallback: iCpuSelf=%d pSubTimer=%p / %d\n", iCpuSelf, pSubTimer, pSubTimer - &pTimer->aSubTimers[0]); #endif /* * Check that we haven't been suspended before scheduling the other DPCs * and doing the callout. */ if ( !ASMAtomicUoReadBool(&pTimer->fSuspended) && pTimer->u32Magic == RTTIMER_MAGIC) { RTCPUSET OnlineSet; RTMpGetOnlineSet(&OnlineSet); ASMAtomicWriteHandle(&pSubTimer->hActiveThread, RTThreadNativeSelf()); if (pTimer->u64NanoInterval) { /* * Recurring timer. */ for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu) && iCpuSelf != iCpu) KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0); uint64_t iTick = ++pSubTimer->iTick; rtTimerNtRearmInternval(pTimer, iTick, &pTimer->aSubTimers[RTMpCpuIdToSetIndex(pTimer->idCpu)].NtDpc); pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick); } else { /* * Single shot timers gets complicated wrt to fSuspended maintance. */ uint32_t cCpus = 0; for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) if (RTCpuSetIsMemberByIndex(&OnlineSet, iCpu)) cCpus++; ASMAtomicAddS32(&pTimer->cOmniSuspendCountDown, cCpus); for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu) && iCpuSelf != iCpu) if (!KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0)) ASMAtomicDecS32(&pTimer->cOmniSuspendCountDown); /* already queued and counted. */ if (ASMAtomicDecS32(&pTimer->cOmniSuspendCountDown) <= 0) ASMAtomicWriteBool(&pTimer->fSuspended, true); pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick); } ASMAtomicWriteHandle(&pSubTimer->hActiveThread, NIL_RTNATIVETHREAD); } NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2); }
/** * * @see iff_event_func in the darwin kpi. */ static void vboxNetFltDarwinIffEvent(void *pvThis, ifnet_t pIfNet, protocol_family_t eProtocol, const struct kev_msg *pEvMsg) { PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)pvThis; LogFlow(("vboxNetFltDarwinIffEvent: pThis=%p\n", pThis)); NOREF(pThis); NOREF(pIfNet); NOREF(eProtocol); NOREF(pEvMsg); /* * Watch out for the interface going online / offline. */ if ( VALID_PTR(pThis) && VALID_PTR(pEvMsg) && pEvMsg->vendor_code == KEV_VENDOR_APPLE && pEvMsg->kev_class == KEV_NETWORK_CLASS && pEvMsg->kev_subclass == KEV_DL_SUBCLASS) { if (pThis->u.s.pIfNet == pIfNet) { if (pEvMsg->event_code == KEV_DL_LINK_ON) { if (ASMAtomicUoReadBool(&pThis->u.s.fNeedSetPromiscuous)) { /* failed to bring it online. */ errno_t err = ifnet_set_promiscuous(pIfNet, 1); if (!err) { ASMAtomicWriteBool(&pThis->u.s.fSetPromiscuous, true); ASMAtomicWriteBool(&pThis->u.s.fNeedSetPromiscuous, false); Log(("vboxNetFltDarwinIffEvent: enabled promiscuous mode on %s (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pIfNet))); } else Log(("vboxNetFltDarwinIffEvent: ifnet_set_promiscuous failed on %s, err=%d (%d)\n", pThis->szName, err, VBOX_GET_PCOUNT(pIfNet))); } else if ( ASMAtomicUoReadBool(&pThis->u.s.fSetPromiscuous) && !(ifnet_flags(pIfNet) & IFF_PROMISC)) { /* Try fix the inconsistency. */ errno_t err = ifnet_set_flags(pIfNet, IFF_PROMISC, IFF_PROMISC); if (!err) err = ifnet_ioctl(pIfNet, 0, SIOCSIFFLAGS, NULL); if (!err && (ifnet_flags(pIfNet) & IFF_PROMISC)) Log(("vboxNetFltDarwinIffEvent: fixed IFF_PROMISC on %s (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pIfNet))); else Log(("vboxNetFltDarwinIffEvent: failed to fix IFF_PROMISC on %s, err=%d flags=%#x (%d)\n", pThis->szName, err, ifnet_flags(pIfNet), VBOX_GET_PCOUNT(pIfNet))); } else Log(("vboxNetFltDarwinIffEvent: online, '%s'. flags=%#x (%d)\n", pThis->szName, ifnet_flags(pIfNet), VBOX_GET_PCOUNT(pIfNet))); } else if (pEvMsg->event_code == KEV_DL_LINK_OFF) Log(("vboxNetFltDarwinIffEvent: %s goes down (%d)\n", pThis->szName, VBOX_GET_PCOUNT(pIfNet))); /** @todo KEV_DL_LINK_ADDRESS_CHANGED -> pfnReportMacAddress */ /** @todo KEV_DL_SIFFLAGS -> pfnReportPromiscuousMode */ } else Log(("vboxNetFltDarwinIffEvent: pThis->u.s.pIfNet=%p pIfNet=%p (%d)\n", pThis->u.s.pIfNet, pIfNet, VALID_PTR(pIfNet) ? VBOX_GET_PCOUNT(pIfNet) : -1)); } else if (VALID_PTR(pEvMsg)) Log(("vboxNetFltDarwinIffEvent: vendor_code=%#x kev_class=%#x kev_subclass=%#x event_code=%#x\n", pEvMsg->vendor_code, pEvMsg->kev_class, pEvMsg->kev_subclass, pEvMsg->event_code)); }
bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis) { vboxNetFltDarwinAttachToInterface(pThis, true /* fRediscovery */); return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost); }
RTDECL(bool) RTAssertAreQuiet(void) { return ASMAtomicUoReadBool(&g_fQuiet); }
RTDECL(bool) RTAssertMayPanic(void) { return ASMAtomicUoReadBool(&g_fMayPanic); }