diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/acme/time.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/acme/time.b')
| -rw-r--r-- | appl/acme/time.b | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/appl/acme/time.b b/appl/acme/time.b new file mode 100644 index 00000000..b5edda74 --- /dev/null +++ b/appl/acme/time.b @@ -0,0 +1,129 @@ +implement Timerm; + +include "common.m"; + +sys : Sys; +acme : Acme; +utils : Utils; +dat : Dat; + +millisec : import sys; +Timer : import dat; + +init(mods : ref Dat->Mods) +{ + sys = mods.sys; + acme = mods.acme; + utils = mods.utils; + dat = mods.dat; +} + +ctimer : chan of ref Timer; + +timeproc() +{ + i, nt, na, dt : int; + x : ref Timer; + t : array of ref Timer; + old, new : int; + + acme->timerpid = sys->pctl(0, nil); + sys->pctl(Sys->FORKFD, nil); + t = array[10] of ref Timer; + na = 10; + nt = 0; + old = millisec(); + for(;;){ + if (nt == 0) { # don't waste cpu time + x = <-ctimer; + t[nt++] = x; + old = millisec(); + } + sys->sleep(1); # will sleep minimum incr + new = millisec(); + 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; + if(x.dt <= 0){ + # + # avoid possible deadlock if client is + # now sending on ctimer + # + + alt { + x.c <-= 0 => + t[i:] = t[i+1:nt]; + t[nt-1] = nil; + nt--; + i--; + * => + ; + } + } + } + gotone := 1; + while (gotone) { + alt { + x = <-ctimer => + if (nt == na) { + ot := t; + t = array[na+10] of ref Timer; + t[0:] = ot[0:na]; + ot = nil; + na += 10; + } + t[nt++] = x; + old = millisec(); + * => + gotone = 0; + } + } + } +} + +timerinit() +{ + ctimer = chan of ref Timer; + spawn timeproc(); +} + +# +# timeralloc() and timerfree() don't lock, so can only be +# called from the main proc. +# + + +timer : ref Timer; + +timerstart(dt : int) : ref Timer +{ + t : ref Timer; + + t = timer; + if(t != nil) + timer = timer.next; + else{ + t = ref Timer; + t.c = chan of int; + } + t.next = nil; + t.dt = dt; + ctimer <-= t; + return t; +} + +timerstop(t : ref Timer) +{ + t.next = timer; + timer = t; +} + +timerwaittask(timer : ref Timer) +{ + <-(timer.c); + timerstop(timer); +} |
