Example #1
0
/*
 * start_timer()
 *
 * Starts a new timer with given expiration time, callback function,
 * and arguments. Returns a pointer to the new timer, which must be kept
 * to stop the timer later if desired.
 */
void start_timer(timer *tptr, int seconds_to_expiry, timer_callback cb,
                 void *cb_arg)
{
    timer_links *next, *prev;

    /*
     * See if this timer is also running.
     */
    next = tptr->links.next;

    if (next) {
        prev = tptr->links.prev;
        next->prev = prev;
        prev->next = next;

        /*
         * Update stats
         */
        timer_wheel.running_timers--;
    }

    /*
     * Hook up the callback
     */
    tptr->cb      = cb;
    tptr->cb_argument     = cb_arg;
    tptr->duration = seconds_to_expiry;
    insert_timer(tptr);

    timer_wheel.running_timers++;
    return;
}
Example #2
0
File: timers.cpp Project: sos22/SLI
static void
run_timer_event(void)
{
	assert(timers_suspended);

	double n = now();
retry:
	if (nr_timers_pending == 0)
		return;
	double nextFire = pendingTimers[0]->nextDue;
	for (int idx = 0; idx < nr_timers_pending; idx++) {
		Timer *pt = pendingTimers[idx];
		if (!pt->inserted) {
			abort();
		}
		if (pt->nextDue <= n) {
			kill_timer(pt);
			if (pt->interval > 0) {
				pt->nextDue = n + pt->interval;
				insert_timer(pt);
			}

			pt->fired();
			goto retry;
		}
		if (pt->nextDue < nextFire)
			nextFire = pt->nextDue;
	}

	n = now();
	if (n >= nextFire)
		goto retry;
	struct itimerval itv;
	memset(&itv, 0, sizeof(itv));
	itv.it_value.tv_sec = nextFire - n;
	itv.it_value.tv_usec = (nextFire - n - itv.it_value.tv_sec) * 1e6;
	while (itv.it_value.tv_usec >= 1000000) {
		/* Shouldn't really happen, but might conceivably if
		   we're in a funny rounding mode.  Fix it up. */
		itv.it_value.tv_sec++;
		itv.it_value.tv_usec -= 1000000;
	}
	while (itv.it_value.tv_usec < 0) {
		/* Likewise. */
		itv.it_value.tv_sec--;
		itv.it_value.tv_usec += 1000000;
	}

	/* If the timer looks bad, just spin. */
	if (itv.it_value.tv_sec < 0 || /* Another sanity check on FP behaviour */
	    (itv.it_value.tv_sec == 0 && itv.it_value.tv_usec < 100)) { /* Avoid stupidly short timers */
		n = now();
		goto retry;
	}

	setitimer(ITIMER_PROF, &itv, NULL);
}
Example #3
0
static void
set_ptimer_ticks( mtimer_t *t, int ticks )
{
	ullong mark = get_mticks_() + ticks;
	
	t->tbu = mark >> 32;
	t->tbl = mark;
	t->period = ticks;
	insert_timer( t );
}
Example #4
0
File: timers.cpp Project: sos22/SLI
void
Timer::schedule(void)
{
	assert(!inserted);
	assert(nextDue != 0);

	suspend_timers();
	insert_timer(this);
	run_timer_event();
	resume_timers();
}
Example #5
0
/*****************************************************************************
 *    ddekit_add_timer                                                       *
 ****************************************************************************/
int ddekit_add_timer
(void (*fn)(void *), void *args, unsigned long timeout)
{
	struct ddekit_timer_s *t;
	
	t = (struct ddekit_timer_s *) 
	    ddekit_simple_malloc(sizeof(struct ddekit_timer_s ));
	
	t->fn   = fn;
	t->args = args;
	t->exp = (myclock_t) timeout;

	return insert_timer(t);
}
Example #6
0
int
resume_ptimer( int id )
{
	mtimer_t *t;
	int lost=0;

	LOCK;
	if( !(t=dequeue_timer(&ts.inactive, id)) )
		printm("resume_ptimer: bogus timer\n");
	else {
		lost = recalc_ptimer( t );
		insert_timer( t );
	}
	UNLOCK;
	return lost;
}
Example #7
0
static int
abs_timer( uint tbu, uint tbl, timer_func_t *handler, void *usr )
{
	mtimer_t *t;
	int id=0;

	LOCK;
	if( (t=new_timer(handler, usr, 0)) ) {
		id = t->id;
		t->tbu = tbu;
		t->tbl = tbl;
		insert_timer( t );
	}
	UNLOCK;
	return id;
}
Example #8
0
static int
rvec_timer( int dummy )
{
	timer_func_t *handler;
	mtimer_t *t;
	void *usr;
	int id, info;

	LOCK;
	while( (t=ts.head) ) {
		info = get_tbl() - t->tbl;

		if( info < 0 || (t->flags & TF_OVERFLOW) )
			break;

		/* printm("Latency: %d\n", info ); */

		handler= t->handler;
		usr = t->usr;
		id = t->id;
		ts.head = t->next;

		if( t->flags & TF_PERIODIC ) {
			if( t->flags & TF_AUTORESUME ) {
				info = recalc_ptimer( t );
				insert_timer( t );
			} else {
				t->next = ts.inactive;
				ts.inactive = t;
			}
		} else {
			t->next = ts.free;
			ts.free = t;
		}
		UNLOCK;
		/* info is either latency or lost ticks */
		(*handler)( id, usr, info );
		LOCK;
	}
	mregs->timer_stamp = t->tbl;
	__recalc_timer = 0;
	UNLOCK;

	/* flag a kernel recalculation of mol-DEC */
	mregs->flag_bits |= fb_RecalcDecInt;
	return 0;
}
Example #9
0
int
iu_adjust_timer(iu_tq_t *tq, iu_timer_id_t timer_id, uint32_t sec)
{
	iu_timer_node_t	*node;

	if (timer_id == -1)
		return (0);

	for (node = tq->iutq_head; node != NULL; node = node->iutn_next) {
		if (node->iutn_timer_id == timer_id) {
			remove_timer(tq, node);
			insert_timer(tq, node, sec * MILLISEC);
			return (1);
		}
	}
	return (0);
}
Example #10
0
/*
 * iu_schedule_ms_timer(): creates and inserts a timer in the tq's timer list,
 *			   using millisecond granularity
 *
 *   input: iu_tq_t *: the timer queue
 *	    uint64_t: the number of milliseconds before this timer fires
 *	    iu_tq_callback_t *: the function to call when the timer fires
 *	    void *: an argument to pass to the called back function
 *  output: iu_timer_id_t: the new timer's timer id on success, -1 on failure
 */
iu_timer_id_t
iu_schedule_timer_ms(iu_tq_t *tq, uint64_t ms, iu_tq_callback_t *callback,
    void *arg)
{
	iu_timer_node_t	*node = calloc(1, sizeof (iu_timer_node_t));

	if (node == NULL)
		return (-1);

	node->iutn_callback	= callback;
	node->iutn_arg	= arg;
	node->iutn_timer_id	= get_timer_id(tq);
	if (node->iutn_timer_id == -1) {
		free(node);
		return (-1);
	}

	insert_timer(tq, node, ms);

	return (node->iutn_timer_id);
}
Example #11
0
File: time.c Project: 1153/otp
void
erts_set_timer(ErlTimer* p, ErlTimeoutProc timeout, ErlCancelProc cancel,
	      void* arg, Uint t)
{

    erts_deliver_time();
    erts_smp_mtx_lock(&tiw_lock);
    if (p->active) { /* XXX assert ? */
	erts_smp_mtx_unlock(&tiw_lock);
	return;
    }
    p->timeout = timeout;
    p->cancel = cancel;
    p->arg = arg;
    p->active = 1;
    insert_timer(p, t);
    erts_smp_mtx_unlock(&tiw_lock);
#if defined(ERTS_SMP)
    if (t <= (Uint) ERTS_SHORT_TIME_T_MAX)
	erts_sys_schedule_interrupt_timed(1, (erts_short_time_t) t);
#endif
}
Example #12
0
static void
overflow_handler( int id, void *dummy, int lost_ticks )
{
	mtimer_t *t, **tp, *chain = NULL;
	
	LOCK;
	for( tp=&ts.head; (t=*tp) ; ) {
		if( !(t->flags & TF_OVERFLOW) ) {
			tp = &t->next;
		} else {
			*tp = t->next;
			t->next = chain;
			chain = t;
		}
	}
	while( (t=chain) ) {
		t->flags &= ~TF_OVERFLOW;
		chain = t->next;
		insert_timer( t );
	}
	UNLOCK;
}
Example #13
0
void
set_ptimer( int id, uint uperiod )
{
	mtimer_t *t;

	if( uperiod <= 10 ) {
		printm("uperiod too small\n");
		uperiod = 2000;
	}

	LOCK;
	if( !(t=dequeue_timer(&ts.inactive, id)) && !(t=dequeue_timer(&ts.head, id)) )
		printm("bogus timer\n");
	else {
		ullong mark = usecs_to_mticks_( uperiod );
		t->period = mark;
		mark += get_mticks_();

		t->tbu = mark >> 32;
		t->tbl = mark;
		insert_timer( t );
	}
	UNLOCK;
}
Example #14
0
int main(int argc, char **argv)
{
	const char *b, *e, *p;
	const char *output_file = NULL;
	int f, tot, last, linenum, err, parse_err;
	struct timer *t = NULL, *t2;
	struct eb32_node *n;
	int val, test;
	int array[5];
	int filter_acc_delay = 0, filter_acc_count = 0;
	int filter_time_resp = 0;
	int skip_fields = 1;

	argc--; argv++;
	while (argc > 0) {
		if (*argv[0] != '-')
			break;

		if (strcmp(argv[0], "-ad") == 0) {
			if (argc < 2) die("missing option for -ad");
			argc--; argv++;
			filter |= FILT_ACC_DELAY;
			filter_acc_delay = atol(*argv);
		}
		else if (strcmp(argv[0], "-ac") == 0) {
			if (argc < 2) die("missing option for -ac");
			argc--; argv++;
			filter |= FILT_ACC_COUNT;
			filter_acc_count = atol(*argv);
		}
		else if (strcmp(argv[0], "-rt") == 0) {
			if (argc < 2) die("missing option for -rt");
			argc--; argv++;
			filter |= FILT_TIME_RESP;
			filter_time_resp = atol(*argv);
		}
		else if (strcmp(argv[0], "-RT") == 0) {
			if (argc < 2) die("missing option for -RT");
			argc--; argv++;
			filter |= FILT_TIME_RESP | FILT_INVERT_TIME_RESP;
			filter_time_resp = atol(*argv);
		}
		else if (strcmp(argv[0], "-s") == 0) {
			if (argc < 2) die("missing option for -s");
			argc--; argv++;
			skip_fields = atol(*argv);
		}
		else if (strcmp(argv[0], "-e") == 0)
			filter |= FILT_ERRORS_ONLY;
		else if (strcmp(argv[0], "-E") == 0)
			filter |= FILT_ERRORS_ONLY | FILT_INVERT_ERRORS;
		else if (strcmp(argv[0], "-c") == 0)
			filter |= FILT_COUNT_ONLY;
		else if (strcmp(argv[0], "-q") == 0)
			filter |= FILT_QUIET;
		else if (strcmp(argv[0], "-v") == 0)
			filter_invert = !filter_invert;
		else if (strcmp(argv[0], "-gt") == 0)
			filter |= FILT_GRAPH_TIMERS;
		else if (strcmp(argv[0], "-pct") == 0)
			filter |= FILT_PERCENTILE;
		else if (strcmp(argv[0], "-o") == 0) {
			if (output_file)
				die("Fatal: output file name already specified.\n");
			if (argc < 2)
				die("Fatal: missing output file name.\n");
			output_file = argv[1];
		}
		argc--;
		argv++;
	}

	if (!filter)
		die("No action specified.\n");

	if (filter & FILT_ACC_COUNT && !filter_acc_count)
		filter_acc_count=1;

	if (filter & FILT_ACC_DELAY && !filter_acc_delay)
		filter_acc_delay = 1;

	linenum = 0;
	tot = 0;
	parse_err = 0;

	while ((line = fgets2(stdin)) != NULL) {
		linenum++;

		test = 1;
		if (filter & FILT_TIME_RESP) {
			int tps;

			/* only report lines with response times larger than filter_time_resp */
			b = field_start(line, TIME_FIELD + skip_fields);
			if (!*b) {
				truncated_line(linenum, line);
				continue;
			}

			e = field_stop(b + 1);
			/* we have field TIME_FIELD in [b]..[e-1] */

			p = b;
			err = 0;
			for (f = 0; f < 4 && *p; f++) {
				tps = str2ic(p);
				if (tps < 0) {
					tps = -1;
					err = 1;
				}

				SKIP_CHAR(p, '/');
			}

			if (f < 4) {
				parse_err++;
				continue;
			}

			test &= (tps >= filter_time_resp) ^ !!(filter & FILT_INVERT_TIME_RESP);
		}

		if (filter & FILT_ERRORS_ONLY) {
			/* only report erroneous status codes */
			b = field_start(line, STATUS_FIELD + skip_fields);
			if (!*b) {
				truncated_line(linenum, line);
				continue;
			}
			if (*b == '-') {
				test &= !!(filter & FILT_INVERT_ERRORS);
			} else {
				val = strl2ui(b, 3);
				test &= (val >= 500 && val <= 599) ^ !!(filter & FILT_INVERT_ERRORS);
			}
		}

		if (filter & (FILT_ACC_COUNT|FILT_ACC_DELAY)) {
			b = field_start(line, ACCEPT_FIELD + skip_fields);
			if (!*b) {
				truncated_line(linenum, line);
				continue;
			}

			tot++;
			val = convert_date(b);
			//printf("date=%s => %d\n", b, val);
			if (val < 0) {
				parse_err++;
				continue;
			}

			t2 = insert_value(&timers[0], &t, val);
			t2->count++;
			continue;
		}

		if (filter & (FILT_GRAPH_TIMERS|FILT_PERCENTILE)) {
			int f;

			b = field_start(line, TIME_FIELD + skip_fields);
			if (!*b) {
				truncated_line(linenum, line);
				continue;
			}

			e = field_stop(b + 1);
			/* we have field TIME_FIELD in [b]..[e-1] */

			p = b;
			err = 0;
			for (f = 0; f < 5 && *p; f++) {
				array[f] = str2ic(p);
				if (array[f] < 0) {
					array[f] = -1;
					err = 1;
				}

				SKIP_CHAR(p, '/');
			}

			if (f < 5) {
				parse_err++;
				continue;
			}

			/* if we find at least one negative time, we count one error
			 * with a time equal to the total session time. This will
			 * emphasize quantum timing effects associated to known
			 * timeouts. Note that on some buggy machines, it is possible
			 * that the total time is negative, hence the reason to reset
			 * it.
			 */

			if (filter & FILT_GRAPH_TIMERS) {
				if (err) {
					if (array[4] < 0)
						array[4] = -1;
					t2 = insert_timer(&timers[0], &t, array[4]);  // total time
					t2->count++;
				} else {
					int v;

					t2 = insert_timer(&timers[1], &t, array[0]); t2->count++;  // req
					t2 = insert_timer(&timers[2], &t, array[2]); t2->count++;  // conn
					t2 = insert_timer(&timers[3], &t, array[3]); t2->count++;  // resp

					v = array[4] - array[0] - array[1] - array[2] - array[3]; // data time
					if (v < 0 && !(filter & FILT_QUIET))
						fprintf(stderr, "ERR: %s (%d %d %d %d %d => %d)\n",
							line, array[0], array[1], array[2], array[3], array[4], v);
					t2 = insert_timer(&timers[4], &t, v); t2->count++;
					tot++;
				}
			} else { /* percentile */
				if (err) {
					if (array[4] < 0)
						array[4] = -1;
					t2 = insert_value(&timers[0], &t, array[4]);  // total time
					t2->count++;
				} else {
					int v;

					t2 = insert_value(&timers[1], &t, array[0]); t2->count++;  // req
					t2 = insert_value(&timers[2], &t, array[2]); t2->count++;  // conn
					t2 = insert_value(&timers[3], &t, array[3]); t2->count++;  // resp

					v = array[4] - array[0] - array[1] - array[2] - array[3]; // data time
					if (v < 0 && !(filter & FILT_QUIET))
						fprintf(stderr, "ERR: %s (%d %d %d %d %d => %d)\n",
							line, array[0], array[1], array[2], array[3], array[4], v);
					t2 = insert_value(&timers[4], &t, v); t2->count++;
					tot++;
				}
			}
			continue;
		}

		test ^= filter_invert;
		if (!test)
			continue;

		/* all other cases mean we just want to count lines */
		tot++;
		if (!(filter & FILT_COUNT_ONLY))
			puts(line);
	}

	if (t)
		free(t);

	if (filter & FILT_COUNT_ONLY) {
		printf("%d\n", tot);
		exit(0);
	}

	if (filter & FILT_ERRORS_ONLY)
		exit(0);

	if (filter & (FILT_ACC_COUNT|FILT_ACC_DELAY)) {
		/* sort and count all timers. Output will look like this :
		 * <accept_date> <delta_ms from previous one> <nb entries>
		 */
		n = eb32_first(&timers[0]);

		if (n)
			last = n->key;
		while (n) {
			unsigned int d, h, m, s, ms;

			t = container_of(n, struct timer, node);
			h = n->key;
			d = h - last;
			last = h;

			if (d >= filter_acc_delay && t->count >= filter_acc_count) {
				ms = h % 1000; h = h / 1000;
				s = h % 60; h = h / 60;
				m = h % 60; h = h / 60;
				tot++;
				printf("%02d:%02d:%02d.%03d %d %d %d\n", h, m, s, ms, last, d, t->count);
			}
			n = eb32_next(n);
		}
	}