Beispiel #1
0
static void wakeup_cb(mrp_wakeup_t *w, mrp_wakeup_event_t event,
                      void *user_data)
{
    static struct timeval  prev[2] = { {0, 0}, {0, 0} };
    const char            *evt;
    struct timeval         now;
    double                 diff;
    int                    id;

    MRP_UNUSED(w);
    MRP_UNUSED(user_data);

    timeval_now(&now);

    switch (event) {
    case MRP_WAKEUP_EVENT_TIMER: evt = "timer";           break;
    case MRP_WAKEUP_EVENT_IO:    evt = "I/O (or signal)"; break;
    case MRP_WAKEUP_EVENT_LIMIT: evt = "limit";           break;
    default:                     evt = "???";
    }

    id = user_data ? 1 : 0;

    if (MRP_LIKELY(prev[id].tv_usec != 0)) {
        diff = timeval_diff(&now, &prev[id]) / 1000.0;
        info("woken up #%d by %s, %.2f msecs since previous", id, evt, diff);
    }

    prev[id] = now;
}
Beispiel #2
0
static gboolean glib_timer_cb(gpointer user_data)
{
    glib_timer_t   *t = (glib_timer_t *)user_data;
    struct timeval  now;
    double          diff, error;

    timeval_now(&now);
    diff  = timeval_diff(&now, &t->prev) / 1000.0;
    error = diff - t->interval;
    if (error < 0.0)
        error = -error;

    info("GLIB timer #%d: %d/%d, diff %.2f (lag %.2f, %.3f %%)",
         t->id, t->count, t->target, diff, error, 100 * error / diff);

    t->count++;
    t->prev = now;

    if (t->count >= t->target) {
        info("GLIB timer #%d has finished.", t->id);

        t->gsrc = 0;
        cfg.nrunning--;
        return FALSE;
    }
    else
        return TRUE;
}
Beispiel #3
0
void timer_cb(mrp_timer_t *timer, void *user_data)
{
    test_timer_t   *t = (test_timer_t *)user_data;
    struct timeval  now;
    double          diff, error;

    MRP_UNUSED(timer);

    timeval_now(&now);
    diff  = timeval_diff(&now, &t->prev) / 1000.0;
    error = diff - t->interval;
    if (error < 0.0)
        error = -error;

    info("MRPH timer #%d: %d/%d, diff %.2f (lag %.2f, %.3f %%)",
         t->id, t->count, t->target, diff, error, 100 * error / diff);

    t->count++;
    t->prev = now;

    if (t->count >= t->target) {
        info("MRPH timer #%d has finished.", t->id);

        mrp_del_timer(t->timer);
        t->timer = NULL;
        cfg.nrunning--;
    }
}
Beispiel #4
0
void cron_init(void)
{
	cron_info.chunk_job = memchunk_new("cron/job", sizeof (Job), 8);
	timeval_now(&cron_info.epoch);
	cron_info.now = cron_info.epoch;
	cron_info.id_next  = 1;
	cron_info.id_reuse = NULL;
	cron_info.oneshot  = NULL;
	cron_info.periodic = NULL;
}
Beispiel #5
0
void cron_update(void)
{
	TimeVal	now;
	double	dt;
	List	*iter, *next;

	timeval_now(&now);
	dt = timeval_elapsed(&cron_info.now, &now);

	for(iter = cron_info.oneshot; iter != NULL; iter = next)
	{
		Job	*job = list_data(iter);

		next = list_next(iter);
		if(timeval_passed(&job->when.oneshot, &now))
		{
			if(job->handler == (int (*)(void *)) printf)
				printf("%s\n", (const char *) job->data);
			else
				job->handler(job->data);
			job_remove(&cron_info.oneshot, iter);
		}
	}

	for(iter = cron_info.periodic; iter != NULL; iter = next)
	{
		Job	*job = list_data(iter);

		next = list_next(iter);
		job->when.periodic.bucket += dt;
		if(job->when.periodic.bucket >= job->when.periodic.period)
		{
			if(job->handler == (int (*)(void *)) printf)	/* Clever? */
				printf("%s\n", (const char *) job->data);
			else
			{
				if(!job->handler(job->data))
					job_remove(&cron_info.periodic, iter);
				else
					job->when.periodic.bucket = 0.0;
			}
		}
	}
	cron_info.now = now;
}
Beispiel #6
0
/* Usually called from the timer callback of @progress->timer.  */
void
update_progress(struct progress *progress, off_t loaded, off_t size, off_t pos)
{
	off_t bytes_delta;
	timeval_T now, elapsed, dis_b_max, dis_b_interval;

	timeval_now(&now);
	timeval_sub(&elapsed, &progress->last_time, &now);
	timeval_copy(&progress->last_time, &now);

	progress->loaded = loaded;
	bytes_delta = progress->loaded - progress->last_loaded;
	progress->last_loaded = progress->loaded;

	timeval_add_interval(&progress->elapsed, &elapsed);

	timeval_add_interval(&progress->dis_b, &elapsed);
	timeval_from_milliseconds(&dis_b_max, mult_ms(SPD_DISP_TIME, CURRENT_SPD_SEC));
	timeval_from_milliseconds(&dis_b_interval, SPD_DISP_TIME);

	while (timeval_cmp(&progress->dis_b, &dis_b_max) >= 0) {
		progress->cur_loaded -= progress->data_in_secs[0];
		memmove(progress->data_in_secs, progress->data_in_secs + 1,
			sizeof(*progress->data_in_secs) * (CURRENT_SPD_SEC - 1));
		progress->data_in_secs[CURRENT_SPD_SEC - 1] = 0;
		timeval_sub_interval(&progress->dis_b, &dis_b_interval);
	}
	progress->data_in_secs[CURRENT_SPD_SEC - 1] += bytes_delta;
	progress->cur_loaded += bytes_delta;

	progress->current_speed = progress->cur_loaded / (CURRENT_SPD_SEC * ((long) SPD_DISP_TIME) / 1000);

	progress->pos = pos;
	progress->size = size;
	if (progress->size != -1 && progress->size < progress->pos)
		progress->size = progress->pos;

	progress->average_speed = timeval_div_off_t(progress->loaded, &progress->elapsed);
	if (progress->average_speed)	/* Division by zero risk */
		timeval_from_seconds(&progress->estimated_time,
				   (progress->size - progress->pos) / progress->average_speed);

	install_timer(&progress->timer, SPD_DISP_TIME,
		      progress_timeout, progress);
}
Beispiel #7
0
/*! Unlike in install_timer(), @a timer_func need not erase the
 * expired timer ID from @a progress->timer.  update_progress()
 * installs the timer with a wrapper function that takes care of
 * erasing the timer ID.  */
void
start_update_progress(struct progress *progress, void (*timer_func)(void *),
		      void *timer_func_data)
{
	if (!progress->valid) {
		struct progress tmp;

		/* Just copy useful fields from invalid progress. */
		memset(&tmp, 0, sizeof(tmp));
		tmp.start = progress->start;
		tmp.seek  = progress->seek;
		tmp.valid = 1;

		memcpy(progress, &tmp, sizeof(*progress));
	}
	timeval_now(&progress->last_time);
	progress->last_loaded = progress->loaded;
	progress->timer_func = timer_func;
	progress->timer_func_data = timer_func_data;
}
Beispiel #8
0
static void setup_glib_timers(void)
{
    glib_timer_t *t;
    int           intervals[] = { GTIMER_INTERVALS, 0 }, *iv = intervals;
    int           msecs, i;

    if ((gtimers = mrp_allocz_array(glib_timer_t, cfg.ngtimer)) != NULL) {
        for (i = 0, t = gtimers; i < cfg.ngtimer; i++, t++) {
            t->id = i;

            msecs = *iv;
            while (cfg.runtime / msecs < 1 && msecs > 0)
                msecs /= 2;
            msecs *= 1000;
            if (!msecs)
                msecs = 500;

            t->interval = msecs;
            t->target   = 1000 * cfg.runtime / msecs;
            if (!t->target)
                continue;

            timeval_now(&t->prev);
            t->gsrc = g_timeout_add(msecs, glib_timer_cb, t);

            if (t->gsrc != 0)
                info("GLIB timer #%d: interval=%d, target=%d", t->id, *iv,
                     t->target);
            else
                fatal("GLIB timer #%d: failed to create", t->id);

            cfg.nrunning++;
            iv++;
            if (!*iv)
                iv = intervals;
        }
    }
    else
        if (cfg.ntimer > 0)
            fatal("could not allocate %d GLIB timers", cfg.ngtimer);
}
Beispiel #9
0
static void setup_timers(mrp_mainloop_t *ml)
{
    test_timer_t *t;
    int           intervals[] = { TIMER_INTERVALS, 0 }, *iv = intervals;
    int           msecs, i;

    if ((timers = mrp_allocz_array(test_timer_t, cfg.ntimer)) != NULL) {
        for (i = 0, t = timers; i < cfg.ntimer; i++, t++) {
            t->id = i;

            msecs = *iv;
            while (cfg.runtime / msecs < 1 && msecs > 0)
                msecs /= 2;
            msecs *= 1000;
            if (!msecs)
                msecs = 500;

            t->interval = msecs;
            t->target   = 1000 * cfg.runtime / msecs;
            if (!t->target)
                continue;

            timeval_now(&t->prev);
            t->timer = mrp_add_timer(ml, t->interval, timer_cb, t);

            if (t->timer != NULL)
                info("MRPH timer #%d: interval=%d, target=%d", t->id, *iv,
                     t->target);
            else
                fatal("MRPH timer #%d: failed to create", t->id);

            cfg.nrunning++;
            iv++;
            if (!*iv)
                iv = intervals;
        }
    }
    else
        if (cfg.ntimer > 0)
            fatal("could not allocate %d timers", cfg.ntimer);
}
Beispiel #10
0
void sync_update(double slice)
{
	List	*iter, *next;
	PNode	*n;
	TimeVal	now;

	/* Create nodes that need to be created. */
	for(iter = sync_info.queue_create; iter != NULL; iter = next)
	{
		next = list_next(iter);
		n = list_data(iter);
		verse_send_node_create(~0, n->type, 0);
		/* Move node from "to create" to "pending" list; no change in refcount. */
		sync_info.queue_create = list_unlink(sync_info.queue_create, iter);
		list_destroy(iter);
		sync_info.queue_create_pend = list_prepend(sync_info.queue_create_pend, n);
	}

	/* Synchronize existing nodes. */
	timeval_now(&now);
	for(iter = sync_info.queue_sync; iter != NULL; iter = next)
	{
		PNode	*n = list_data(iter);

		next = list_next(iter);

		if(timeval_elapsed(&n->sync.last_send, &now) < 0.1)
			continue;
		n->sync.last_send = now;
		if(sync_node(n))
		{
			sync_info.queue_sync = list_unlink(sync_info.queue_sync, iter);
			printf("removing node %u from sync queue, it's in sync\n", n->id);
			nodedb_unref(n);
			list_destroy(iter);
			n->sync.busy = 0;
		}
	}
}