RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First) { struct timeval tv; if (!rtTimerIsValid(pTimer)) return VERR_INVALID_HANDLE; if (!pTimer->fSuspended) return VERR_TIMER_ACTIVE; if ( pTimer->fSpecificCpu && !RTMpIsCpuOnline(pTimer->idCpu)) return VERR_CPU_OFFLINE; /* * Calc when it should start firing. */ u64First += RTTimeNanoTS(); pTimer->fSuspended = false; pTimer->iTick = 0; pTimer->u64StartTS = u64First; pTimer->u64NextTS = u64First; tv.tv_sec = u64First / 1000000000; tv.tv_usec = (u64First % 1000000000) / 1000; callout_reset(&pTimer->Callout, tvtohz(&tv), rtTimerFreeBSDCallback, pTimer); return VINF_SUCCESS; }
RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval) { if (!rtTimerIsValid(pTimer)) return VERR_INVALID_HANDLE; return VERR_NOT_SUPPORTED; }
RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First) { if (!rtTimerIsValid(pTimer)) return VERR_INVALID_HANDLE; if (!pTimer->fSuspended) return VERR_TIMER_ACTIVE; /* * Calc when it should start firing and give the thread a kick so it get going. */ u64First += RTTimeNanoTS(); RTSpinlockAcquire(g_Spinlock); g_u32ChangeNo++; if (!g_cActiveTimers) { int rc = rtTimerOs2Arm(); if (RT_FAILURE(rc)) { RTSpinlockRelease(g_Spinlock); return rc; } } g_cActiveTimers++; pTimer->fSuspended = false; pTimer->fDone = true; /* next tick, not current! */ pTimer->iTick = 0; pTimer->u64StartTS = u64First; pTimer->u64NextTS = u64First; RTSpinlockRelease(g_Spinlock); return VINF_SUCCESS; }
RTDECL(int) RTTimerStop(PRTTIMER pTimer) { if (!rtTimerIsValid(pTimer)) return VERR_INVALID_HANDLE; if (pTimer->fSuspended) return VERR_TIMER_SUSPENDED; /* * Suspend the timer. */ pTimer->fSuspended = true; callout_stop(&pTimer->Callout); return VINF_SUCCESS; }
RTDECL(int) RTTimerDestroy(PRTTIMER pTimer) { /* It's ok to pass NULL pointer. */ if (pTimer == /*NIL_RTTIMER*/ NULL) return VINF_SUCCESS; if (!rtTimerIsValid(pTimer)) return VERR_INVALID_HANDLE; /* * Free the associated resources. */ pTimer->u32Magic++; callout_stop(&pTimer->Callout); RTMemFree(pTimer); return VINF_SUCCESS; }
RTDECL(int) RTTimerDestroy(PRTTIMER pTimer) { /* It's ok to pass NULL pointer. */ if (pTimer == /*NIL_RTTIMER*/ NULL) return VINF_SUCCESS; if (!rtTimerIsValid(pTimer)) return VERR_INVALID_HANDLE; /* * Remove it from the list. */ RTSpinlockAcquire(g_Spinlock); g_u32ChangeNo++; if (g_pTimerHead == pTimer) g_pTimerHead = pTimer->pNext; else { PRTTIMER pPrev = g_pTimerHead; while (pPrev->pNext != pTimer) { pPrev = pPrev->pNext; if (RT_UNLIKELY(!pPrev)) { RTSpinlockRelease(g_Spinlock); return VERR_INVALID_HANDLE; } } pPrev->pNext = pTimer->pNext; } Assert(g_cTimers > 0); g_cTimers--; if (!pTimer->fSuspended) { Assert(g_cActiveTimers > 0); g_cActiveTimers--; if (!g_cActiveTimers) rtTimerOs2Dearm(); } RTSpinlockRelease(g_Spinlock); /* * Free the associated resources. */ pTimer->u32Magic++; RTMemFree(pTimer); return VINF_SUCCESS; }
RTDECL(int) RTTimerStop(PRTTIMER pTimer) { if (!rtTimerIsValid(pTimer)) return VERR_INVALID_HANDLE; if (pTimer->fSuspended) return VERR_TIMER_SUSPENDED; /* * Suspend the timer. */ RTSpinlockAcquire(g_Spinlock); g_u32ChangeNo++; pTimer->fSuspended = true; Assert(g_cActiveTimers > 0); g_cActiveTimers--; if (!g_cActiveTimers) rtTimerOs2Dearm(); RTSpinlockRelease(g_Spinlock); return VINF_SUCCESS; }