// KplTimeCallbackServiceUntil is called from the KplThreadRunloopCycle() function to call timer callbacks that are due void KplTimeCallbackServiceUntil(void *param, KplTime until) { KplTimeCallback cb; KplThread thread = (KplThread)param; cb = (KplTimeCallback)thread->timerCallbacks; if (NULL == cb) return; // mark all those that are due while (cb) { if (FskTimeCompare((FskTime)until, (FskTime)&cb->trigger) >= 0) break; cb->marked = true; cb = cb->next; } // Remove and call any timer callbacks that are due while (1) { cb = (KplTimeCallback)FskListGetNext(thread->timerCallbacks, NULL); if (!cb) break; if (!cb->marked) break; FskListRemove(&thread->timerCallbacks, cb); (*cb->callbackProc)(cb, &cb->trigger, cb->param); } if (thread->timerCallbacks) rescheduleTimer(thread); }
int timerLoop (void) { IxOsalTimeval now; IxOsalVoidFnVoidPtr callback = NULL; void *callbackParam = NULL; IxOsalTimerRec *nextTimer; IX_STATUS status; while (1) { /* * This loop catches all cases in a simple way. If multiple * timers expire together, then lowest will be <=0 until all * have been processed and the queue get won't get invoked. */ status = ixOsalSemaphoreWait (&ixOsalCriticalSectSem, IX_OSAL_WAIT_FOREVER); if (status != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "timerLoop fail to get semaphore \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } ixOsalTimeGet (&now); nextTimer = findNextTimeout (now); if ((nextTimer == NULL) || IX_OSAL_TIME_GT ((nextTimer->expires), (now))) { callback = NULL; } else { rescheduleTimer (nextTimer); callback = nextTimer->callback; callbackParam = nextTimer->callbackParam; } status = ixOsalSemaphorePost (&ixOsalCriticalSectSem); if (status != IX_SUCCESS) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, "timerLoop fail to release semaphore \n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } if (callback != NULL) { callTimerCallback (callback, callbackParam); } else { timerSleep (nextTimer, now); } } }
void KplTimeCallbackCancel(KplTimeCallback callback) { Boolean reschedule; KplThread thread; if (NULL == callback) return; thread = callback->owner; if ((NULL == thread) || ((NULL == thread->timerCallbacks) && (NULL == thread->suspendedTimerCallbacks))) return; reschedule = (callback == thread->timerCallbacks); if (!FskListRemove((FskList *)&thread->timerCallbacks, callback)) FskListRemove((FskList *)&thread->suspendedTimerCallbacks, callback); if (reschedule) rescheduleTimer(thread); }
// Insert this timer callback into the owning thread's "timerCallbacks" queue. void sInsertInTime(KplTimeCallback el) { KplTimeCallback cur, last = NULL; Boolean reschedule = false; KplTimeRecord now; KplThread thread; thread = (KplThread)el->owner; KplTimeGetNow(&now); if (1 == FskTimeCompare((FskTime)&el->trigger, (FskTime)&now)) el->trigger = now; cur = (KplTimeCallback)FskListGetNext(thread->timerCallbacks, NULL); el->next = NULL; el->marked = false; if (cur == NULL) { FskListPrepend(&thread->timerCallbacks, el); reschedule = true; goto done; } while (cur) { if (FskTimeCompare((FskTime)&el->trigger, (FskTime)&cur->trigger) > 0) { if (last == NULL) { reschedule = true; } FskListInsertAfter(&thread->timerCallbacks, el, last); goto done; } last = cur; cur = cur->next; } if (!cur && last) { FskListAppend(&thread->timerCallbacks, el); } done: if (reschedule) rescheduleTimer(thread); }