URI:
       ttime.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       ttime.c (1934B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <thread.h>
            5 #include <cursor.h>
            6 #include <mouse.h>
            7 #include <keyboard.h>
            8 #include <frame.h>
            9 #include <fcall.h>
           10 #include <plumb.h>
           11 #include <libsec.h>
           12 #include "dat.h"
           13 #include "fns.h"
           14 
           15 static Channel*        ctimer;        /* chan(Timer*)[100] */
           16 static Timer *timer;
           17 
           18 static
           19 uint
           20 msec(void)
           21 {
           22         return nsec()/1000000;
           23 }
           24 
           25 void
           26 timerstop(Timer *t)
           27 {
           28         t->next = timer;
           29         timer = t;
           30 }
           31 
           32 void
           33 timercancel(Timer *t)
           34 {
           35         t->cancel = TRUE;
           36 }
           37 
           38 static
           39 void
           40 timerproc(void *v)
           41 {
           42         int i, nt, na, dt, del;
           43         Timer **t, *x;
           44         uint old, new;
           45 
           46         USED(v);
           47         threadsetname("timerproc");
           48         rfork(RFFDG);
           49         t = nil;
           50         na = 0;
           51         nt = 0;
           52         old = msec();
           53         for(;;){
           54                 sleep(10);        /* longer sleeps here delay recv on ctimer, but 10ms should not be noticeable */
           55                 new = msec();
           56                 dt = new-old;
           57                 old = new;
           58                 if(dt < 0)        /* timer wrapped; go around, losing a tick */
           59                         continue;
           60                 for(i=0; i<nt; i++){
           61                         x = t[i];
           62                         x->dt -= dt;
           63                         del = FALSE;
           64                         if(x->cancel){
           65                                 timerstop(x);
           66                                 del = TRUE;
           67                         }else if(x->dt <= 0){
           68                                 /*
           69                                  * avoid possible deadlock if client is
           70                                  * now sending on ctimer
           71                                  */
           72                                 if(nbsendul(x->c, 0) > 0)
           73                                         del = TRUE;
           74                         }
           75                         if(del){
           76                                 memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]);
           77                                 --nt;
           78                                 --i;
           79                         }
           80                 }
           81                 if(nt == 0){
           82                         x = recvp(ctimer);
           83         gotit:
           84                         if(nt == na){
           85                                 na += 10;
           86                                 t = realloc(t, na*sizeof(Timer*));
           87                                 if(t == nil)
           88                                         error("timer realloc failed");
           89                         }
           90                         t[nt++] = x;
           91                         old = msec();
           92                 }
           93                 if(nbrecv(ctimer, &x) > 0)
           94                         goto gotit;
           95         }
           96 }
           97 
           98 void
           99 timerinit(void)
          100 {
          101         ctimer = chancreate(sizeof(Timer*), 100);
          102         chansetname(ctimer, "ctimer");
          103         proccreate(timerproc, nil, STACK);
          104 }
          105 
          106 Timer*
          107 timerstart(int dt)
          108 {
          109         Timer *t;
          110 
          111         t = timer;
          112         if(t)
          113                 timer = timer->next;
          114         else{
          115                 t = emalloc(sizeof(Timer));
          116                 t->c = chancreate(sizeof(int), 0);
          117                 chansetname(t->c, "tc%p", t->c);
          118         }
          119         t->next = nil;
          120         t->dt = dt;
          121         t->cancel = FALSE;
          122         sendp(ctimer, t);
          123         return t;
          124 }