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 (1841B)
       ---
            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 "dat.h"
           11 #include "fns.h"
           12 
           13 static Channel*        ctimer;        /* chan(Timer*)[100] */
           14 static Timer *timer;
           15 
           16 static
           17 uint
           18 msec(void)
           19 {
           20         return nsec()/1000000;
           21 }
           22 
           23 void
           24 timerstop(Timer *t)
           25 {
           26         t->next = timer;
           27         timer = t;
           28 }
           29 
           30 void
           31 timercancel(Timer *t)
           32 {
           33         t->cancel = TRUE;
           34 }
           35 
           36 static
           37 void
           38 timerproc(void *a)
           39 {
           40         int i, nt, na, dt, del;
           41         Timer **t, *x;
           42         uint old, new;
           43 
           44         USED(a);
           45         rfork(RFFDG);
           46         threadsetname("TIMERPROC");
           47         t = nil;
           48         na = 0;
           49         nt = 0;
           50         old = msec();
           51         for(;;){
           52                 sleep(1);        /* will sleep minimum incr */
           53                 new = msec();
           54                 dt = new-old;
           55                 old = new;
           56                 if(dt < 0)        /* timer wrapped; go around, losing a tick */
           57                         continue;
           58                 for(i=0; i<nt; i++){
           59                         x = t[i];
           60                         x->dt -= dt;
           61                         del = 0;
           62                         if(x->cancel){
           63                                 timerstop(x);
           64                                 del = 1;
           65                         }else if(x->dt <= 0){
           66                                 /*
           67                                  * avoid possible deadlock if client is
           68                                  * now sending on ctimer
           69                                  */
           70                                 if(nbsendul(x->c, 0) > 0)
           71                                         del = 1;
           72                         }
           73                         if(del){
           74                                 memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]);
           75                                 --nt;
           76                                 --i;
           77                         }
           78                 }
           79                 if(nt == 0){
           80                         x = recvp(ctimer);
           81         gotit:
           82                         if(nt == na){
           83                                 na += 10;
           84                                 t = realloc(t, na*sizeof(Timer*));
           85                                 if(t == nil)
           86                                         abort();
           87                         }
           88                         t[nt++] = x;
           89                         old = msec();
           90                 }
           91                 if(nbrecv(ctimer, &x) > 0)
           92                         goto gotit;
           93         }
           94 }
           95 
           96 void
           97 timerinit(void)
           98 {
           99         ctimer = chancreate(sizeof(Timer*), 100);
          100         proccreate(timerproc, nil, STACK);
          101 }
          102 
          103 /*
          104  * timeralloc() and timerfree() don't lock, so can only be
          105  * called from the main proc.
          106  */
          107 
          108 Timer*
          109 timerstart(int dt)
          110 {
          111         Timer *t;
          112 
          113         t = timer;
          114         if(t)
          115                 timer = timer->next;
          116         else{
          117                 t = emalloc(sizeof(Timer));
          118                 t->c = chancreate(sizeof(int), 0);
          119         }
          120         t->next = nil;
          121         t->dt = dt;
          122         t->cancel = FALSE;
          123         sendp(ctimer, t);
          124         return t;
          125 }