URI: 
       tperiodic.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
       ---
       tperiodic.c (1355B)
       ---
            1 #include "stdinc.h"
            2 #include "dat.h"
            3 #include "fns.h"
            4 #include "error.h"
            5 
            6 struct Periodic {
            7         QLock lk;
            8         int die;                /* flag: quit if set */
            9         void (*f)(void*);        /* call this each period */
           10         void *a;                /* argument to f */
           11         int msec;                /* period */
           12 };
           13 
           14 static void periodicThread(void *a);
           15 
           16 Periodic *
           17 periodicAlloc(void (*f)(void*), void *a, int msec)
           18 {
           19         Periodic *p;
           20 
           21         p = vtmallocz(sizeof(Periodic));
           22         p->f = f;
           23         p->a = a;
           24         p->msec = msec;
           25         if(p->msec < 10)
           26                 p->msec = 10;
           27 
           28         proccreate(periodicThread, p, STACK);
           29         return p;
           30 }
           31 
           32 void
           33 periodicKill(Periodic *p)
           34 {
           35         if(p == nil)
           36                 return;
           37         qlock(&p->lk);
           38         p->die = 1;
           39         qunlock(&p->lk);
           40 }
           41 
           42 static void
           43 periodicFree(Periodic *p)
           44 {
           45         vtfree(p);
           46 }
           47 
           48 static void
           49 periodicThread(void *a)
           50 {
           51         Periodic *p = a;
           52         vlong t, ct, ts;                /* times in ms. */
           53 
           54         threadsetname("periodic");
           55 
           56         ct = nsec() / 1000000;
           57         t = ct + p->msec;                /* call p->f at or after this time */
           58 
           59         for(;;){
           60                 ts = t - ct;                /* ms. to next cycle's start */
           61                 if(ts > 1000)
           62                         ts = 1000;        /* bound sleep duration */
           63                 if(ts > 0)
           64                         sleep(ts);        /* wait for cycle's start */
           65 
           66                 qlock(&p->lk);
           67                 if(p->die){
           68                         qunlock(&p->lk);
           69                         break;
           70                 }
           71                 ct = nsec() / 1000000;
           72                 if(t <= ct){                /* due to call p->f? */
           73                         p->f(p->a);
           74                         ct = nsec() / 1000000;
           75                         while(t <= ct)        /* advance t to future cycle start */
           76                                 t += p->msec;
           77                 }
           78                 qunlock(&p->lk);
           79         }
           80         periodicFree(p);
           81 }