static void mainloop(void) { gtimer_t *gti; gti_callback_t *cb; time_t now; struct timespec ts; const char *id; while (tvheadend_is_running()) { now = gdispatch_clock_update(); ts.tv_sec = now + 3600; ts.tv_nsec = 0; /* Global timers */ pthread_mutex_lock(&global_lock); // TODO: there is a risk that if timers re-insert themselves to // the top of the list with a 0 offset we could loop indefinitely #if 0 tvhdebug(LS_GTIMER, "now %"PRItime_t, ts.tv_sec); LIST_FOREACH(gti, >imers, gti_link) tvhdebug(LS_GTIMER, " gti %p expire %"PRItimet, gti, gti->gti_expire.tv_sec); #endif while((gti = LIST_FIRST(>imers)) != NULL) { if (gti->gti_expire > now) { ts.tv_sec = gti->gti_expire; break; } #if ENABLE_GTIMER_CHECK id = gti->gti_id; #else id = NULL; #endif tprofile_start(>imer_profile, id); cb = gti->gti_callback; LIST_REMOVE(gti, gti_link); gti->gti_callback = NULL; cb(gti->gti_opaque); tprofile_finish(>imer_profile); } /* Wait */ pthread_cond_timedwait(>imer_cond, &global_lock, &ts); pthread_mutex_unlock(&global_lock); } }
static int64_t mdispatch_clock_update(void) { int64_t mono = getmonoclock(); if (mono > atomic_get_s64(&mtimer_periodic)) { atomic_set_s64(&mtimer_periodic, mono + MONOCLOCK_RESOLUTION); gdispatch_clock_update(); /* gclk() update */ comet_flush(); /* Flush idle comet mailboxes */ } atomic_set_s64(&__mdispatch_clock, mono); return mono; }
static void mainloop(void) { gtimer_t *gti; gti_callback_t *cb; time_t now; struct timespec ts; #if ENABLE_GTIMER_CHECK int64_t mtm; const char *id; const char *fcn; #endif while (tvheadend_is_running()) { now = gdispatch_clock_update(); ts.tv_sec = now + 3600; ts.tv_nsec = 0; /* Global timers */ pthread_mutex_lock(&global_lock); // TODO: there is a risk that if timers re-insert themselves to // the top of the list with a 0 offset we could loop indefinitely #if 0 tvhdebug("gtimer", "now %"PRItime_t, ts.tv_sec); LIST_FOREACH(gti, >imers, gti_link) tvhdebug("gtimer", " gti %p expire %"PRItimet, gti, gti->gti_expire.tv_sec); #endif while((gti = LIST_FIRST(>imers)) != NULL) { if (gti->gti_expire > now) { ts.tv_sec = gti->gti_expire; break; } #if ENABLE_GTIMER_CHECK mtm = getmonoclock(); id = gti->gti_id; fcn = gti->gti_fcn; #endif cb = gti->gti_callback; LIST_REMOVE(gti, gti_link); gti->gti_callback = NULL; cb(gti->gti_opaque); #if ENABLE_GTIMER_CHECK mtm = getmonoclock() - mtm; if (mtm > 10000) tvhtrace("gtimer", "%s:%s duration %"PRId64"us", id, fcn, mtm); #endif } /* Wait */ pthread_cond_timedwait(>imer_cond, &global_lock, &ts); pthread_mutex_unlock(&global_lock); } }