]> Pileus Git - ~andy/csm213a-hw/blob - hw2/main_time.c
Add heuristics for time printing
[~andy/csm213a-hw] / hw2 / main_time.c
1 #include <stdint.h>
2
3 #include "serial_irq.h"
4 #include "main_time.h"
5
6 /*******************
7  * Timer functions *
8  *******************/
9
10 uint64_t time_last_local; // timestamp at last time sync
11 uint64_t time_last_world; // offset at last time sync
12
13 /* Initialization */
14 void time_init(void)
15 {
16         // nothing for now
17 }
18
19 /**
20  * Generate time stamp for an async event:
21  *   time:  drift compensated wall-clock time
22  *   stamp: event timestamp from PIT Module
23  */
24 uint64_t time_to_world(uint64_t local)
25 {
26         uint64_t elapsed = local - time_last_local;
27         return time_last_world + elapsed;
28 }
29
30 uint64_t time_to_local(uint64_t world)
31 {
32         uint64_t elapsed = world - time_last_world;
33         return time_last_local + elapsed;
34 }
35
36 /**
37  * Synchronize the timer internal state with updates
38  * from an external time sync message.
39  *   local: our internal timestamp for the event
40  *   world: reference timestamp from the other device
41  */
42 void time_ext_init(uint64_t local, uint64_t world)
43 {
44         sirq_printf("initialize clocks: %d -> %d\r\n",
45                         (int)(local/NSEC_PER_SEC),
46                         (int)(world/NSEC_PER_SEC));
47
48         time_last_local = local;
49         time_last_world = world;
50 }
51
52 /**
53  * Synchronize the timer internal state with updates
54  * from an external time sync message.
55  *   local: our internal timestamp for the event
56  *   world: reference timestamp from the other device
57  */
58 void time_ext_sync(uint64_t local, uint64_t world)
59 {
60         uint64_t guess = time_to_world(local);
61
62         time_last_local = local;
63         time_last_world = (guess/2) + (world/2);
64         //time_last_world = (guess * 3 / 4) + (world * 1 / 4);
65         //time_last_world =
66         //      (guess - (        guess / 2)) +
67         //      (world - (world - world / 2));
68         //time_last_world =
69         //      (guess - (guess - guess / 4)) +
70         //      (world - (        world / 4));
71
72         world = time_last_world;
73
74 //#ifdef VERBOSE
75 #if 1
76         uint64_t error = world > guess ? world - guess :
77                          guess > world ? guess - world : 0;
78         int      ahead = guess > world;
79         sirq_printf("syncing clocks: %6d=%d.%04u -> %d.%04u (err: %s%ld.%09lu)\r\n",
80                         (int)((local / NSEC_PER_SEC)),
81                         (int)((guess / NSEC_PER_SEC)),
82                         (int)((guess % NSEC_PER_SEC)/(NSEC_PER_SEC/10000)),
83                         (int)((world / NSEC_PER_SEC)),
84                         (int)((world % NSEC_PER_SEC)/(NSEC_PER_SEC/10000)),
85                         ahead ? "-" : " ",
86                         (int32_t )(error / (int64_t)NSEC_PER_SEC),
87                         (uint32_t)(error % (int64_t)NSEC_PER_SEC));
88 #endif
89 //#endif
90 }
91
92 void time_printf(const char *label, uint64_t local)
93 {
94         if (local > 1000000 * NSEC_PER_SEC) {
95                 sirq_printf("%s -- %14s -> %d.%09u\r\n",
96                                 label, "",
97                                 (int)(local / NSEC_PER_SEC),
98                                 (int)(local % NSEC_PER_SEC));
99         } else {
100                 uint64_t world = time_to_world(local);
101                 sirq_printf("%s -- %4d.%09u -> %d.%09u\r\n",
102                                 label,
103                                 (int)(local / NSEC_PER_SEC),
104                                 (int)(local % NSEC_PER_SEC),
105                                 (int)(world / NSEC_PER_SEC),
106                                 (int)(world % NSEC_PER_SEC));
107         }
108 }