1 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
2 6f4d00ee 2013-09-23 0intro #include "dat.h"
3 6f4d00ee 2013-09-23 0intro #include "fns.h"
4 6f4d00ee 2013-09-23 0intro #include "error.h"
6 6f4d00ee 2013-09-23 0intro struct Periodic {
8 6f4d00ee 2013-09-23 0intro int die; /* flag: quit if set */
9 6f4d00ee 2013-09-23 0intro void (*f)(void*); /* call this each period */
10 6f4d00ee 2013-09-23 0intro void *a; /* argument to f */
11 6f4d00ee 2013-09-23 0intro int msec; /* period */
14 6f4d00ee 2013-09-23 0intro static void periodicThread(void *a);
16 6f4d00ee 2013-09-23 0intro Periodic *
17 6f4d00ee 2013-09-23 0intro periodicAlloc(void (*f)(void*), void *a, int msec)
19 6f4d00ee 2013-09-23 0intro Periodic *p;
21 4b576658 2013-09-23 0intro p = vtmallocz(sizeof(Periodic));
24 6f4d00ee 2013-09-23 0intro p->msec = msec;
25 6f4d00ee 2013-09-23 0intro if(p->msec < 10)
26 6f4d00ee 2013-09-23 0intro p->msec = 10;
28 4b576658 2013-09-23 0intro proccreate(periodicThread, p, STACK);
33 6f4d00ee 2013-09-23 0intro periodicKill(Periodic *p)
35 6f4d00ee 2013-09-23 0intro if(p == nil)
37 4b576658 2013-09-23 0intro qlock(&p->lk);
38 6f4d00ee 2013-09-23 0intro p->die = 1;
39 4b576658 2013-09-23 0intro qunlock(&p->lk);
42 6f4d00ee 2013-09-23 0intro static void
43 6f4d00ee 2013-09-23 0intro periodicFree(Periodic *p)
45 4b576658 2013-09-23 0intro vtfree(p);
48 6f4d00ee 2013-09-23 0intro static void
49 6f4d00ee 2013-09-23 0intro periodicThread(void *a)
51 6f4d00ee 2013-09-23 0intro Periodic *p = a;
52 6f4d00ee 2013-09-23 0intro vlong t, ct, ts; /* times in ms. */
54 4b576658 2013-09-23 0intro threadsetname("periodic");
56 6f4d00ee 2013-09-23 0intro ct = nsec() / 1000000;
57 6f4d00ee 2013-09-23 0intro t = ct + p->msec; /* call p->f at or after this time */
60 6f4d00ee 2013-09-23 0intro ts = t - ct; /* ms. to next cycle's start */
61 6f4d00ee 2013-09-23 0intro if(ts > 1000)
62 6f4d00ee 2013-09-23 0intro ts = 1000; /* bound sleep duration */
63 6f4d00ee 2013-09-23 0intro if(ts > 0)
64 6f4d00ee 2013-09-23 0intro sleep(ts); /* wait for cycle's start */
66 4b576658 2013-09-23 0intro qlock(&p->lk);
67 6f4d00ee 2013-09-23 0intro if(p->die){
68 4b576658 2013-09-23 0intro qunlock(&p->lk);
71 6f4d00ee 2013-09-23 0intro ct = nsec() / 1000000;
72 6f4d00ee 2013-09-23 0intro if(t <= ct){ /* due to call p->f? */
73 6f4d00ee 2013-09-23 0intro p->f(p->a);
74 6f4d00ee 2013-09-23 0intro ct = nsec() / 1000000;
75 6f4d00ee 2013-09-23 0intro while(t <= ct) /* advance t to future cycle start */
76 6f4d00ee 2013-09-23 0intro t += p->msec;
78 4b576658 2013-09-23 0intro qunlock(&p->lk);
80 6f4d00ee 2013-09-23 0intro periodicFree(p);