On Tue, Jul 15, 2003 at 04:48:56PM +0200, Leopold Toetsch wrote:
Attached is a test program, showing an implementations for multiple
It didn't arrive. Did you attach it, or did its name end .t ?
No extension was .c. Attachment was there:
$ mailq
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
8CDB611802A 6908 Tue Jul 15 16:48:56 [EMAIL PROTECTED]
(deferred transport)
[EMAIL PROTECTED]
-- 6 Kbytes in 1 Request.
so it must have been stripped elsewhere.
Anyway - renamed to timer_c.txt
Nicholas Clark
leo
/* * itimer test */ #include <sys/time.h> #include <signal.h> #include <stdio.h> #include <malloc.h> #include <math.h>
volatile sig_atomic_t got_alarm = 0; typedef struct timer_t { int ticks; int value; int repeat; int run; int nr; struct timer_t *next; struct timer_t *prev; } timer; timer *rtimer = 0; void add_timer(timer *t) { timer *next = rtimer; rtimer = t; t->next = next; if (next) { t->nr = next->nr + 1; next->prev = t; } else t->nr = 1; } void del_timer(timer *t) { timer *next = t->next; timer *prev = t->prev; if (prev) prev->next = next; else rtimer = next; if (next) next->prev = prev; free(t); } timer * new_timer(void) { timer *t = calloc(1, sizeof(timer)); add_timer(t); return t; } typedef unsigned int UINTVAL; typedef double FLOATVAL; UINTVAL gcd(UINTVAL a, UINTVAL b) { UINTVAL q = 0; UINTVAL c = 0; while (b != 0) { q = (UINTVAL)floor( (FLOATVAL)a/b ); c = a - b*q; a = b; b = c; } return a; } void sig_alarm_handler(int i) { got_alarm = 1; } /* platform interface */ void start_sys_timer_ms(void *handle, int ms) { struct itimerval its; memset(&its, 0, sizeof(its)); if (ms) { its.it_interval.tv_sec = its.it_value.tv_sec = ms/1000; its.it_interval.tv_usec = its.it_value.tv_usec = 1000 *(ms%1000); } setitimer(ITIMER_REAL, &its, NULL); printf("new val = %ld:%ld ms = %d\n", its.it_value.tv_sec, its.it_value.tv_usec, ms); } void stop_sys_timer_ms(void *handle) { start_sys_timer_ms(handle, 0); } int get_sys_timer_ms(void *handle) { struct itimerval ots; getitimer(ITIMER_REAL, &ots); return ots.it_interval.tv_sec * 1000 + ots.it_interval.tv_usec/1000; } void * new_sys_timer_ms() {return 0; } /* end platform interface */ void recalc_ticks(void); void *handle; void do_alarm_handler() { timer *t; UINTVAL ms; int recalc = 0; ms = get_sys_timer_ms(handle); for (t = rtimer; t; t= t->next) { if (!--t->ticks) { t->run = 1; if (t->repeat) { t->ticks = t->value/ms; if (t->repeat != -1) t->repeat--; } } } again: for (t = rtimer; t; t= t->next) { if (t->run == 1) { t->run = 0; printf("alarm %d\n", t->nr); /* code run here may add timers, these have t->run = 2 */ goto again; } if (!t->ticks && !t->repeat) { printf("del_timer %d\n", t->nr); del_timer(t); recalc = 1; goto again; } } if (recalc) recalc_ticks(); } void p_add_timer(UINTVAL msecs, int repeat) { timer *t; if (!msecs) return; t = new_timer(); t->repeat = repeat; t->value = msecs; t->run = 2; recalc_ticks(); } void p_del_timer(timer *t) { del_timer(t); recalc_ticks(); } void recalc_ticks() { UINTVAL ms, oms; timer *t; oms = get_sys_timer_ms(handle); printf("gettimer oms = %d\n", oms); t = rtimer; if (t) { t->run = 0; if (oms && t->ticks) ms = oms*t->ticks; /* time left */ else ms = t->value; if (t->next) { for (t = t->next; t; t = t->next) { t->run = 0; if (oms && t->ticks) { ms = gcd(oms*t->ticks, ms); } else ms = gcd(t->value, ms); } } printf("new ms %d\n", ms); again: for (t = rtimer; t; t= t->next) { int ot = t->ticks; printf("t%d oticks %d => ", t->nr, t->ticks); if (oms && ot) t->ticks = t->ticks * ((double)oms / (double)ms); else t->ticks = t->value / ms; if (!t->ticks) { ms = oms; t->ticks = ot; goto again; } printf("ticks %d value %d\n", t->ticks, t->value); } } else ms = 0; if (ms) start_sys_timer_ms(handle, ms); else stop_sys_timer_ms(handle); } int main(int argc, char **argv) { handle = new_sys_timer_ms(); signal(SIGALRM, sig_alarm_handler); p_add_timer(3000, 1); p_add_timer(2000, 3); p_add_timer(500, 1); while (rtimer) { if (got_alarm) { /* CHECK_EVENTS */ got_alarm = 0; do_alarm_handler(); } } return 0; }