docs: say that HrtRateFit::toSeconds returns producer-epoch, not wall, seconds
The fit keeps the slope and discards the intercept, so the result counts from the producer's boot. Tasks 4 and 7 compose it with ClockOffset::map, which is correct, but the bare name invites passing it straight to a plot axis. Also unwrapped the stalled-clock assertion from behind `if (fit.ready())` — that branch never runs, so the test confirmed nothing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e4817dd284
commit
c89decef8e
@@ -63,6 +63,15 @@ public:
|
|||||||
void add(uint64_t hrt, double wallSec);
|
void add(uint64_t hrt, double wallSec);
|
||||||
bool ready() const { return n_ >= kMinSamples && rate_ > 0.0; }
|
bool ready() const { return n_ >= kMinSamples && rate_ > 0.0; }
|
||||||
double ticksPerSecond() const { return rate_; }
|
double ticksPerSecond() const { return rate_; }
|
||||||
|
/**
|
||||||
|
* @brief Converts a tick count to seconds on the PRODUCER's own epoch.
|
||||||
|
*
|
||||||
|
* The fit recovers the slope only and discards the intercept, so this is
|
||||||
|
* `hrt / ticksPerSecond()` — not a wall-clock time. A producer's hrt counts
|
||||||
|
* from its own boot, not from the Unix epoch. Pass the result to
|
||||||
|
* ClockOffset::map() to land it on the wall clock; latching that arbitrary
|
||||||
|
* epoch difference is precisely what ClockOffset is for.
|
||||||
|
*/
|
||||||
double toSeconds(uint64_t hrt) const;
|
double toSeconds(uint64_t hrt) const;
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
|||||||
@@ -102,10 +102,12 @@ TEST(HrtRateFit, SurvivesAStalledClock) {
|
|||||||
for (int i = 0; i < 64; i++) {
|
for (int i = 0; i < 64; i++) {
|
||||||
fit.add(12345u, 1000.0 + i * 0.01); /* hrt never advances */
|
fit.add(12345u, 1000.0 + i * 0.01); /* hrt never advances */
|
||||||
}
|
}
|
||||||
/* A degenerate fit must not produce a rate that would divide by zero. */
|
/* A degenerate fit must not produce a rate that would divide by zero, so it
|
||||||
if (fit.ready()) {
|
* must decline to be ready at all. Guarding this behind `if (fit.ready())`
|
||||||
EXPECT_GT(fit.ticksPerSecond(), 0.0);
|
* would make the test vacuous: the branch never runs and a fit that
|
||||||
}
|
* declared itself ready with a rate of 0 or NaN would pass unnoticed. */
|
||||||
|
EXPECT_FALSE(fit.ready());
|
||||||
|
EXPECT_DOUBLE_EQ(fit.ticksPerSecond(), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TimeSignalScale, UsesNanosecondsForUint64AndMicrosecondsOtherwise) {
|
TEST(TimeSignalScale, UsesNanosecondsForUint64AndMicrosecondsOtherwise) {
|
||||||
|
|||||||
Reference in New Issue
Block a user