Blame


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"
5 6f4d00ee 2013-09-23 0intro
6 6f4d00ee 2013-09-23 0intro struct Periodic {
7 4b576658 2013-09-23 0intro QLock lk;
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 */
12 6f4d00ee 2013-09-23 0intro };
13 6f4d00ee 2013-09-23 0intro
14 6f4d00ee 2013-09-23 0intro static void periodicThread(void *a);
15 6f4d00ee 2013-09-23 0intro
16 6f4d00ee 2013-09-23 0intro Periodic *
17 6f4d00ee 2013-09-23 0intro periodicAlloc(void (*f)(void*), void *a, int msec)
18 6f4d00ee 2013-09-23 0intro {
19 6f4d00ee 2013-09-23 0intro Periodic *p;
20 6f4d00ee 2013-09-23 0intro
21 4b576658 2013-09-23 0intro p = vtmallocz(sizeof(Periodic));
22 6f4d00ee 2013-09-23 0intro p->f = f;
23 6f4d00ee 2013-09-23 0intro p->a = a;
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;
27 6f4d00ee 2013-09-23 0intro
28 4b576658 2013-09-23 0intro proccreate(periodicThread, p, STACK);
29 6f4d00ee 2013-09-23 0intro return p;
30 6f4d00ee 2013-09-23 0intro }
31 6f4d00ee 2013-09-23 0intro
32 6f4d00ee 2013-09-23 0intro void
33 6f4d00ee 2013-09-23 0intro periodicKill(Periodic *p)
34 6f4d00ee 2013-09-23 0intro {
35 6f4d00ee 2013-09-23 0intro if(p == nil)
36 6f4d00ee 2013-09-23 0intro return;
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);
40 6f4d00ee 2013-09-23 0intro }
41 6f4d00ee 2013-09-23 0intro
42 6f4d00ee 2013-09-23 0intro static void
43 6f4d00ee 2013-09-23 0intro periodicFree(Periodic *p)
44 6f4d00ee 2013-09-23 0intro {
45 4b576658 2013-09-23 0intro vtfree(p);
46 6f4d00ee 2013-09-23 0intro }
47 6f4d00ee 2013-09-23 0intro
48 6f4d00ee 2013-09-23 0intro static void
49 6f4d00ee 2013-09-23 0intro periodicThread(void *a)
50 6f4d00ee 2013-09-23 0intro {
51 6f4d00ee 2013-09-23 0intro Periodic *p = a;
52 6f4d00ee 2013-09-23 0intro vlong t, ct, ts; /* times in ms. */
53 6f4d00ee 2013-09-23 0intro
54 4b576658 2013-09-23 0intro threadsetname("periodic");
55 6f4d00ee 2013-09-23 0intro
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 */
58 6f4d00ee 2013-09-23 0intro
59 6f4d00ee 2013-09-23 0intro for(;;){
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 */
65 6f4d00ee 2013-09-23 0intro
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);
69 6f4d00ee 2013-09-23 0intro break;
70 6f4d00ee 2013-09-23 0intro }
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;
77 6f4d00ee 2013-09-23 0intro }
78 4b576658 2013-09-23 0intro qunlock(&p->lk);
79 6f4d00ee 2013-09-23 0intro }
80 6f4d00ee 2013-09-23 0intro periodicFree(p);
81 6f4d00ee 2013-09-23 0intro }