1 #include "stdinc.h" 2 #include "dat.h" 3 #include "fns.h" 4 #include "error.h" 5 6 struct Periodic { 7 VtLock *lk; 8 int die; 9 void (*f)(void*); 10 void *a; 11 int msec; 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 = vtMemAllocZ(sizeof(Periodic)); 22 p->lk = vtLockAlloc(); 23 p->f = f; 24 p->a = a; 25 p->msec = msec; 26 if(p->msec < 10) 27 p->msec = 10; 28 29 vtThread(periodicThread, p); 30 return p; 31 } 32 33 void 34 periodicKill(Periodic *p) 35 { 36 if(p == nil) 37 return; 38 vtLock(p->lk); 39 p->die = 1; 40 vtUnlock(p->lk); 41 } 42 43 static void 44 periodicFree(Periodic *p) 45 { 46 vtLockFree(p->lk); 47 vtMemFree(p); 48 } 49 50 static void 51 periodicThread(void *a) 52 { 53 Periodic *p = a; 54 double t, ct, ts; 55 56 vtThreadSetName("periodic"); 57 58 ct = nsec()*1e-6; 59 t = ct + p->msec; 60 61 for(;;){ 62 /* skip missed */ 63 while(t <= ct) 64 t += p->msec; 65 66 ts = t - ct; 67 if(ts > 1000) 68 ts = 1000; 69 sleep(ts); 70 ct = nsec()*1e-6; 71 vtLock(p->lk); 72 if(p->die){ 73 vtUnlock(p->lk); 74 break; 75 } 76 if(t <= ct){ 77 p->f(p->a); 78 t += p->msec; 79 } 80 vtUnlock(p->lk); 81 } 82 periodicFree(p); 83 } 84 85