void HRTWorkQueue::process(void) { DF_LOG_DEBUG("HRTWorkQueue::process"); uint64_t next; uint64_t elapsed; uint64_t remaining; timespec ts; uint64_t now; while (!m_exit_requested) { DF_LOG_DEBUG("HRTWorkQueue::process In while"); hrtLock(); // Wake up every 10 sec if nothing scheduled next = 10000000; DFUIntList::Index idx = nullptr; idx = m_work_list.next(idx); now = offsetTime(); while ((!m_exit_requested) && (idx != nullptr)) { DF_LOG_DEBUG("HRTWorkQueue::process work exists"); now = offsetTime(); unsigned int index; m_work_list.get(idx, index); if (index < g_work_items->size()) { WorkItem *item; g_work_items->getAt(index, &item); elapsed = now - item->m_queue_time; //DF_LOG_DEBUG("now = %lu elapsed = %lu delay = %luusec\n", now, elapsed, item.m_delay_usec); if (elapsed >= item->m_delay_usec) { DF_LOG_DEBUG("HRTWorkQueue::process do work (%p) (%u)", item, item->m_delay_usec); item->updateStats(now); // reschedule work item->m_queue_time = offsetTime(); item->m_in_use = true; void *tmpptr = item->m_arg; hrtUnlock(); item->m_callback(tmpptr); hrtLock(); // Start again from the top to get rescheduled work idx = nullptr; idx = m_work_list.next(idx); } else { remaining = item->m_delay_usec - elapsed; if (remaining < next) { next = remaining; } // try the next in the list idx = m_work_list.next(idx); } } } // pthread_cond_timedwait uses absolute time ts = offsetTimeToAbsoluteTime(now + next); #ifdef __PX4_QURT uint64_t now_later = offsetTime(); int64_t diff = (int64_t)(now + next) - (int64_t)now_later; // TODO FIXME: sometimes timeouts < 100 us seem to hang, therefore this workaround if (diff > 100) { #endif DF_LOG_DEBUG("HRTWorkQueue::process waiting for work (%" PRIi64 ")", diff); // Wait until next expiry or until a new item is rescheduled pthread_cond_timedwait(&g_reschedule_cond, &g_hrt_lock, &ts); #ifdef __PX4_QURT } #endif hrtUnlock(); } }
void HRTWorkQueue::process(void) { DF_LOG_DEBUG("HRTWorkQueue::process"); uint64_t next; uint64_t elapsed; timespec ts; uint64_t now; while (!m_exit_requested) { DF_LOG_DEBUG("HRTWorkQueue::process In while"); hrtLock(); DFUIntList::Index idx = nullptr; idx = m_work_list.next(idx); now = offsetTime(); // Wake up every 10 sec if nothing scheduled next = now + 10000000; while ((!m_exit_requested) && (idx != nullptr)) { DF_LOG_DEBUG("HRTWorkQueue::process work exists"); unsigned int index; m_work_list.get(idx, index); if (index < g_work_items->size()) { WorkItem *item = nullptr; g_work_items->getAt(index, &item); now = offsetTime(); elapsed = now - item->m_queue_time; //DF_LOG_DEBUG("now = %lu elapsed = %lu delay = %luusec\n", now, elapsed, item.m_delay_usec); if (elapsed >= item->m_delay_usec) { DF_LOG_DEBUG("HRTWorkQueue::process do work (%p) (%u)", item, item->m_delay_usec); item->updateStats(now); // reschedule work item->m_queue_time += item->m_delay_usec; item->m_in_use = true; void *tmpptr = item->m_arg; hrtUnlock(); item->m_callback(tmpptr); hrtLock(); } // Get next scheduling time uint64_t cur_next = item->m_queue_time + item->m_delay_usec; if (cur_next < next) { next = cur_next; } idx = m_work_list.next(idx); } } if (next > offsetTime()) { // pthread_cond_timedwait uses absolute time ts = offsetTimeToAbsoluteTime(next); DF_LOG_DEBUG("HRTWorkQueue::process waiting for work (%" PRIi64 ")", next - offsetTime()); // Wait until next expiry or until a new item is rescheduled pthread_cond_timedwait(&g_reschedule_cond, &g_hrt_lock, &ts); } hrtUnlock(); } }