diff options
author | rsc <devnull@localhost> | 2005-11-06 22:16:48 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-11-06 22:16:48 +0000 |
commit | e830a908498c8f0270948fd08c50f6d773315880 (patch) | |
tree | a16fe62419a4e3a95ab2d8d3a70f1a870d0bb55c /src/cmd/9term/time.c | |
parent | a6c0ff35ee294c0a808e1792eb4f43820fed8f16 (diff) | |
download | plan9port-e830a908498c8f0270948fd08c50f6d773315880.tar.gz plan9port-e830a908498c8f0270948fd08c50f6d773315880.tar.bz2 plan9port-e830a908498c8f0270948fd08c50f6d773315880.zip |
New 9term using rio sources more directly.
Diffstat (limited to 'src/cmd/9term/time.c')
-rw-r--r-- | src/cmd/9term/time.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/cmd/9term/time.c b/src/cmd/9term/time.c new file mode 100644 index 00000000..5dedf144 --- /dev/null +++ b/src/cmd/9term/time.c @@ -0,0 +1,125 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <thread.h> +#include <cursor.h> +#include <mouse.h> +#include <keyboard.h> +#include <frame.h> +#include <fcall.h> +#include "dat.h" +#include "fns.h" + +static Channel* ctimer; /* chan(Timer*)[100] */ +static Timer *timer; + +static +uint +msec(void) +{ + return nsec()/1000000; +} + +void +timerstop(Timer *t) +{ + t->next = timer; + timer = t; +} + +void +timercancel(Timer *t) +{ + t->cancel = TRUE; +} + +static +void +timerproc(void *a) +{ + int i, nt, na, dt, del; + Timer **t, *x; + uint old, new; + + USED(a); + rfork(RFFDG); + threadsetname("TIMERPROC"); + t = nil; + na = 0; + nt = 0; + old = msec(); + for(;;){ + sleep(1); /* will sleep minimum incr */ + new = msec(); + dt = new-old; + old = new; + if(dt < 0) /* timer wrapped; go around, losing a tick */ + continue; + for(i=0; i<nt; i++){ + x = t[i]; + x->dt -= dt; + del = 0; + if(x->cancel){ + timerstop(x); + del = 1; + }else if(x->dt <= 0){ + /* + * avoid possible deadlock if client is + * now sending on ctimer + */ + if(nbsendul(x->c, 0) > 0) + del = 1; + } + if(del){ + memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]); + --nt; + --i; + } + } + if(nt == 0){ + x = recvp(ctimer); + gotit: + if(nt == na){ + na += 10; + t = realloc(t, na*sizeof(Timer*)); + if(t == nil) + abort(); + } + t[nt++] = x; + old = msec(); + } + if(nbrecv(ctimer, &x) > 0) + goto gotit; + } +} + +void +timerinit(void) +{ + ctimer = chancreate(sizeof(Timer*), 100); + proccreate(timerproc, nil, STACK); +} + +/* + * timeralloc() and timerfree() don't lock, so can only be + * called from the main proc. + */ + +Timer* +timerstart(int dt) +{ + Timer *t; + + t = timer; + if(t) + timer = timer->next; + else{ + t = emalloc(sizeof(Timer)); + t->c = chancreate(sizeof(int), 0); + } + t->next = nil; + t->dt = dt; + t->cancel = FALSE; + sendp(ctimer, t); + return t; +} |