/* Process pending alarms. */
spin_lock_irqsave(&tmr->lock, flags);
list_for_each_entry_safe(alarm, atemp, &tmr->alarms, head) { /* Have we hit the earliest alarm that hasn't gone off? */ if (alarm->timestamp > nvkm_timer_read(tmr)) { /* Schedule it. If we didn't race, we're done. */
tmr->func->alarm_init(tmr, alarm->timestamp); if (alarm->timestamp > nvkm_timer_read(tmr)) break;
}
/* Move to completed list. We'll drop the lock before *executingthecallbacksoitcanrescheduleitself.
*/
list_del_init(&alarm->head);
list_add(&alarm->exec, &exec);
}
/* Shut down interrupt if no more pending alarms. */ if (list_empty(&tmr->alarms))
tmr->func->alarm_fini(tmr);
spin_unlock_irqrestore(&tmr->lock, flags);
if (nsec) { /* Insert into pending list, ordered earliest to latest. */
alarm->timestamp = nvkm_timer_read(tmr) + nsec;
list_for_each_entry(list, &tmr->alarms, head) { if (list->timestamp > alarm->timestamp) break;
}
list_add_tail(&alarm->head, &list->head);
/* Update HW if this is now the earliest alarm. */
list = list_first_entry(&tmr->alarms, typeof(*list), head); if (list == alarm) {
tmr->func->alarm_init(tmr, alarm->timestamp); /* This shouldn't happen if callers aren't stupid. * *Worstcasescenarioisthatit'lltakeroughly *4secondsforthenextalarmtotrigger.
*/
WARN_ON(alarm->timestamp <= nvkm_timer_read(tmr));
}
}
spin_unlock_irqrestore(&tmr->lock, flags);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.