* Feed-forward clock absolute time. This should be the preferred way to read * the feed-forward clock for "wall-clock" type time. The flags allow to compose * various flavours of absolute time (e.g. with or without leap seconds taken * into account). If valid pointers are provided, the ffcounter value and an * upper bound on clock error associated with the bintime are provided. * NOTE: use ff
| 68 | * read earlier. |
| 69 | */ |
| 70 | void |
| 71 | ffclock_abstime(ffcounter *ffcount, struct bintime *bt, |
| 72 | struct bintime *error_bound, uint32_t flags) |
| 73 | { |
| 74 | struct ffclock_estimate cest; |
| 75 | ffcounter ffc; |
| 76 | ffcounter update_ffcount; |
| 77 | ffcounter ffdelta_error; |
| 78 | |
| 79 | /* Get counter and corresponding time. */ |
| 80 | if ((flags & FFCLOCK_FAST) == FFCLOCK_FAST) |
| 81 | ffclock_last_tick(&ffc, bt, flags); |
| 82 | else { |
| 83 | ffclock_read_counter(&ffc); |
| 84 | ffclock_convert_abs(ffc, bt, flags); |
| 85 | } |
| 86 | |
| 87 | /* Current ffclock estimate, use update_ffcount as generation number. */ |
| 88 | do { |
| 89 | update_ffcount = ffclock_estimate.update_ffcount; |
| 90 | bcopy(&ffclock_estimate, &cest, sizeof(struct ffclock_estimate)); |
| 91 | } while (update_ffcount != ffclock_estimate.update_ffcount); |
| 92 | |
| 93 | /* |
| 94 | * Leap second adjustment. Total as seen by synchronisation algorithm |
| 95 | * since it started. cest.leapsec_next is the ffcounter prediction of |
| 96 | * when the next leapsecond occurs. |
| 97 | */ |
| 98 | if ((flags & FFCLOCK_LEAPSEC) == FFCLOCK_LEAPSEC) { |
| 99 | bt->sec -= cest.leapsec_total; |
| 100 | if (ffc > cest.leapsec_next) |
| 101 | bt->sec -= cest.leapsec; |
| 102 | } |
| 103 | |
| 104 | /* Boot time adjustment, for uptime/monotonic clocks. */ |
| 105 | if ((flags & FFCLOCK_UPTIME) == FFCLOCK_UPTIME) { |
| 106 | bintime_sub(bt, &ffclock_boottime); |
| 107 | } |
| 108 | |
| 109 | /* Compute error bound if a valid pointer has been passed. */ |
| 110 | if (error_bound) { |
| 111 | ffdelta_error = ffc - cest.update_ffcount; |
| 112 | ffclock_convert_diff(ffdelta_error, error_bound); |
| 113 | /* 18446744073709 = int(2^64/1e12), err_bound_rate in [ps/s] */ |
| 114 | bintime_mul(error_bound, cest.errb_rate * |
| 115 | (uint64_t)18446744073709LL); |
| 116 | /* 18446744073 = int(2^64 / 1e9), since err_abs in [ns] */ |
| 117 | bintime_addx(error_bound, cest.errb_abs * |
| 118 | (uint64_t)18446744073LL); |
| 119 | } |
| 120 | |
| 121 | if (ffcount) |
| 122 | *ffcount = ffc; |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | * Feed-forward difference clock. This should be the preferred way to convert a |
no test coverage detected