📄 hxsched.cpp
字号:
{ m_bLocked = TRUE; theErr = ExecuteCurrentFunctions (bAtInterrupt); m_bLocked = FALSE; } if (m_pCoreMutex) { m_pCoreMutex->Unlock(); } return theErr;}HX_RESULT HXScheduler::ExecuteCurrentFunctions(BOOL bAtInterrupt){ BOOL bShouldServiceSystem = FALSE; BOOL bShouldServiceInterrupt = FALSE; BOOL bImmediatesPending = FALSE; BOOL bInterruptImmediatesPending = FALSE; if (FALSE == UpdateCurrentTime(bAtInterrupt, bShouldServiceSystem, bShouldServiceInterrupt)) { return HXR_OK; } /* if not at interrupt time, execute interrupt safe & * non-interrupt safe tasks */ if( bShouldServiceInterrupt && !m_pInterruptTimeScheduler->empty() ) { m_pInterruptTimeScheduler->execute(m_CurrentTimeVal); /* * Don't execute more then 100 immediate elements. We don't wanna * hold on too long and spin here. */ int count = 0; // Keep executing until there are no more zero time elements while ((bInterruptImmediatesPending = m_pInterruptTimeScheduler->immediate()) && (count < 100)) { count += m_pInterruptTimeScheduler->execute(m_CurrentTimeVal); } } if (bShouldServiceSystem && !m_pScheduler->empty()) { m_pScheduler->execute(m_CurrentTimeVal); /* * Don't execute more then 100 immediate elements. We don't wanna * hold on too long and spin here. */ int count = 0; // Keep executing until there are no more zero time elements while ((bImmediatesPending = m_pScheduler->immediate()) && (count < 100)) { count += m_pScheduler->execute(m_CurrentTimeVal); }#if defined(_WIN32) || defined(THREADS_SUPPORTED) BOOL bChange = FALSE; if (m_pScheduler->empty()) { if (m_ulCurrentGranularity < MINIMUM_GRANULARITY && (MINIMUM_GRANULARITY - m_ulCurrentGranularity >= MINIMUM_DIFFERENCE)) { bChange = TRUE; m_ulCurrentGranularity = MINIMUM_GRANULARITY; } } else if (m_ulCurrentGranularity > MINIMUM_DIFFERENCE) { Timeval timeout = m_pScheduler->head_time() - m_CurrentTimeVal; INT32 lTimeoutInMs; if (timeout.tv_sec >= 0) { lTimeoutInMs = timeout.tv_sec * 1000 + timeout.tv_usec / 1000; } else { lTimeoutInMs = 0; } if (lTimeoutInMs > 0 && (UINT32) lTimeoutInMs < m_ulCurrentGranularity && (m_ulCurrentGranularity - (UINT32) lTimeoutInMs >= MINIMUM_DIFFERENCE)) { bChange = TRUE; m_ulCurrentGranularity = (UINT32) ((lTimeoutInMs >= MINIMUM_DIFFERENCE ? lTimeoutInMs: MINIMUM_DIFFERENCE)); } } if (bChange) { m_pTimeline->Pause(); /* Reset the granularity */ m_pTimeline->SetGranularity(m_ulCurrentGranularity); /* Resume */ m_pTimeline->Resume(); }#endif /*_WIN32*/ } m_bImmediatesPending = bImmediatesPending || bInterruptImmediatesPending; Timeval timeout; if (!m_pScheduler->empty()) { timeout = m_pScheduler->head_time() - m_CurrentTimeVal; if (timeout.tv_sec >= 0) { m_ulSystemNextDueTime = (UINT32) (timeout.tv_sec*1000+timeout.tv_usec/1000); } else { m_ulSystemNextDueTime = 0; } } else { m_ulSystemNextDueTime = m_ulCurrentGranularity; } if (!m_pInterruptTimeScheduler->empty()) { timeout = m_pInterruptTimeScheduler->head_time() - m_CurrentTimeVal; if (timeout.tv_sec >= 0) { m_ulInterruptNextDueTime = (UINT32) (timeout.tv_sec*1000+timeout.tv_usec/1000); } else { m_ulInterruptNextDueTime = 0; } } else { m_ulInterruptNextDueTime = m_ulCurrentGranularity; } return HXR_OK;}BOOL HXScheduler::IsEmpty() { return (m_pScheduler->empty() && m_pInterruptTimeScheduler->empty());}BOOL HXScheduler::GetNextEventDueTimeDiff(ULONG32 &ulEarliestDueTimeDiff){ if (m_pScheduler->empty() && m_pInterruptTimeScheduler->empty()) return FALSE; Timeval nextDueTime; Timeval now; now.tv_sec = m_CurrentTimeVal.tv_sec; now.tv_usec = m_CurrentTimeVal.tv_usec; if (m_pScheduler->empty()) { nextDueTime = m_pInterruptTimeScheduler->head_time(); } else if (m_pInterruptTimeScheduler->empty()) { nextDueTime = m_pScheduler->head_time(); } else { if (m_pInterruptTimeScheduler->head_time() < m_pScheduler->head_time()) { nextDueTime = m_pInterruptTimeScheduler->head_time(); } else { nextDueTime = m_pScheduler->head_time(); } } if (nextDueTime > now) { nextDueTime -= now; } else { nextDueTime = 0.0; } ulEarliestDueTimeDiff = (ULONG32) ( nextDueTime.tv_sec*1000 + nextDueTime.tv_usec/1000); return TRUE;}HX_RESULT HXScheduler::StartScheduler(){ return StartSchedulerImplementation(FALSE);}HX_RESULT HXScheduler::StartSchedulerTimerFixup(){ return StartSchedulerImplementation(TRUE);}HX_RESULT HXScheduler::StartSchedulerImplementation(BOOL TimerFixup){ HX_RESULT theErr = HXR_OK; /* Stop any already running scheduler*/ StopScheduler(); (void) gettimeofday((Timeval*)&m_CurrentTimeVal, 0); m_ulLastUpdateTime = HX_GET_TICKCOUNT();#if defined(_WIN32) || defined(THREADS_SUPPORTED) if (m_bIsInterruptEnabled) { if (!m_pAsyncTimer) { m_pAsyncTimer = new CAsyncTimer(this); } if (!m_pAsyncTimer) { return HXR_OUTOFMEMORY; } m_pAsyncTimer->SetGranularity(MINIMUM_GRANULARITY); theErr = m_pAsyncTimer->StartTimer(); }#endif // _WIN32 || THREADS_SUPPORTED if (!m_pTimeline) { m_pTimeline = new Timeline; } if (m_pTimeline) { m_pTimeline->Init( (IUnknown*) (IHXScheduler*) this, m_bUseDeferredTask);#if defined(_MACINTOSH) && defined(THREADS_SUPPORTED) m_pTimeline->SetCoreMutex(m_pCoreMutex);#endif m_pTimeline->SetStartTime(0); m_ulCurrentGranularity = MINIMUM_GRANULARITY; m_pTimeline->SetGranularity(m_ulCurrentGranularity); if (TimerFixup) m_pTimeline->SetTimerFixup(TRUE); m_pTimeline->Resume(); } else { theErr = HXR_OUTOFMEMORY; } return theErr;}void HXScheduler::StopScheduler(){#if defined(_WIN32) || defined(THREADS_SUPPORTED) if (m_pAsyncTimer) { m_pAsyncTimer->StopTimer(); }#endif if (m_pTimeline) { m_pTimeline->Pause(); m_pTimeline->Done(); }}BOOL HXScheduler::IsAtInterruptTime(void){#ifdef _MACINTOSH return !IsMacInCooperativeThread();#elif defined (_WIN32) || defined(THREADS_SUPPORTED) return (m_bIsInterruptEnabled && m_pAsyncTimer->InTimerThread());#endif return FALSE;}BOOL HXScheduler::UpdateCurrentTime(BOOL bAtInterrupt, BOOL& bShouldServiceSystem, BOOL& bShouldServiceInterrupt){ BOOL bResult = TRUE;#if defined(_WINDOWS) || defined(_WIN32) || defined (_MACINTOSH) || defined(THREADS_SUPPORTED) UINT32 ulCurrentTime = HX_GET_TICKCOUNT(); UINT32 ulElapsedTime = CALCULATE_ELAPSED_TICKS(m_ulLastUpdateTime, ulCurrentTime);// UINT32 ulCurrentTimeBetter = HX_GET_BETTERTICKCOUNT();//{FILE* f1 = ::fopen("d:\\temp\\better.txt", "a+"); ::fprintf(f1, "Diff %lu %lu %lu %lu\n", ulCurrentTime, ulCurrentTimeBetter, ulElapsedTime, CALCULATE_ELAPSED_TICKS(ulCurrentTimeBetter, ulCurrentTime));::fclose(f1);} if (ulElapsedTime >= m_ulInterruptNextDueTime) { bShouldServiceInterrupt = TRUE; } if (!bAtInterrupt && ulElapsedTime >= m_ulSystemNextDueTime) { bShouldServiceSystem = TRUE; }//{FILE* f1 = ::fopen("d:\\temp\\pq.txt", "a+"); ::fprintf(f1, "\nUpdateCurrentTime %d %lu", m_ulCoreThreadID == GetCurrentThreadId(), CALCULATE_ELAPSED_TICKS(m_ulLastUpdateTime, ulCurrentTime));::fclose(f1);} if (bShouldServiceSystem || bShouldServiceInterrupt) { m_CurrentTimeVal += (1000 * ulElapsedTime); m_ulLastUpdateTime = ulCurrentTime; }#else if (!bAtInterrupt) { bShouldServiceSystem = TRUE; } bShouldServiceInterrupt = TRUE; (void) gettimeofday(&m_CurrentTimeVal, 0);#endif if (!(bShouldServiceSystem || bShouldServiceInterrupt)) { bResult = FALSE; if (!m_pScheduler->empty() && m_pScheduler->head_time() != m_headTime) { m_headTime = m_pScheduler->head_time(); bResult = TRUE; } if (!m_pInterruptTimeScheduler->empty() && m_pInterruptTimeScheduler->head_time() != m_interruptHeadTime) { m_interruptHeadTime = m_pInterruptTimeScheduler->head_time(); bResult = TRUE; } } return bResult;}void HXScheduler::NotifyPlayState(BOOL bInPlayingState){#if defined(_WIN32) || defined(THREADS_SUPPORTED) if (m_pAsyncTimer) { m_pAsyncTimer->NotifyPlayState(bInPlayingState); }#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -