Page MenuHomeFreeBSD

D42939.id.diff
No OneTemporary

D42939.id.diff

diff --git a/sys/kern/kern_ffclock.c b/sys/kern/kern_ffclock.c
--- a/sys/kern/kern_ffclock.c
+++ b/sys/kern/kern_ffclock.c
@@ -61,8 +61,11 @@
* 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 ffclock_convert_abs() to differ the conversion of a ffcounter value
- * read earlier.
+ * The DIFF and MONO flags determining FFclock type are processed within
+ * ffclock_last_tick and ffclock_read_counter.
+ * Note that here ffclock_convert_abs() is used to read the FFclock `now', but
+ * the resulting timestamp corresponds to the event timestamped by the raw
+ * ffcounter read made earlier - this is a feature!
*/
void
ffclock_abstime(ffcounter *ffcount, struct bintime *bt,
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -508,9 +508,10 @@
* avoid duplication of hardware access and tc-tick processing overheads.
* However the FFclock code does not alter or interfere with FBclock operation.
*
- * Two forms of the FFclock are supported :
+ * Three forms of the FFclock are supported :
* native [natFFC]: kernel version of the userland FF daemon's clock.
* monotonic [monoFFC]: monotonic version of natFFC (resets aside).
+ * difference [diffFFC]: non-jumping for use as a difference-clock
* Each of these clocks correspond to UTC at the time that the FFclock
* daemon is started. Leap seconds subsequent to that time are added in
* separately.
@@ -527,6 +528,7 @@
struct ffclock_estimate cest; /* natFFC data */
struct bintime tick_time; /* natFFC */
struct bintime tick_time_mono; /* monoFFC */
+ struct bintime tick_time_diff; /* diffFFC */
struct bintime tick_error;
ffcounter tick_ffcount;
uint64_t period_mono;
@@ -626,11 +628,12 @@
/*
* Update the fftimehands. The updated tick state is based on the previous tick.
* If there has been no actionable update in the FFclock parameters during the
- * current tick (ffclock_updated <= 0), then each of the natFFC and monoFFC
- * clocks advance linearly. Otherwise it is based off the updated
+ * current tick (ffclock_updated <= 0), then each of the natFFC, monoFFC, and
+ * diffFFC clocks advance linearly. Otherwise it is based off the updated
* parameters at the time of the update. The native FFclock natFFC will then
- * jump, monoFFC will not (except under special conditions).
- * The linear interpolation parameters of
+ * jump, monoFFC will not (except under special conditions). The diffFFC
+ * will never jump, to ensure its intended use as a difference clock,
+ * used to measure time differences. The linear interpolation parameters of
* monoFFC ({tick_time,period}_mono) are recomputed for the new tick.
*
* The instant defining the start of the new tick is the delta=tc_delta call
@@ -663,15 +666,17 @@
*/
if (ffclock_updated <= 0) {
- /* Update natFFC members {cest, tick_time, tick_error} */
+ /* Update natFFC members {cest, tick_time{_diff}, tick_error} */
memcpy(cest, &fftimehands->cest,sizeof(struct ffclock_estimate));
- ffth->tick_time = fftimehands->tick_time;
+ ffth->tick_time = fftimehands->tick_time;
+ ffth->tick_time_diff = fftimehands->tick_time_diff;
ffclock_convert_delta(ffdelta, cest->period, &bt);
bintime_add(&ffth->tick_time, &bt);
+ bintime_add(&ffth->tick_time_diff, &bt);
bintime_mul(&bt, cest->errb_rate * PS_AS_BINFRAC);
bintime_add(&ffth->tick_error, &bt);
- /* Update monoFFC members {period_mono, tick_time_mono} */
+ /* Update monoFFC members {period_mono, tick_time_mono}. */
ffth->period_mono = fftimehands->period_mono;
ffth->tick_time_mono = fftimehands->tick_time_mono;
ffclock_convert_delta(ffdelta, ffth->period_mono, &bt);
@@ -696,7 +701,7 @@
*/
if (ffclock_updated > 0) {
- /* Update natFFC members {cest, tick_time, tick_error} */
+ /* Update natFFC members {cest, tick_time, tick_error}. */
memcpy(cest, &ffclock_estimate,sizeof(struct ffclock_estimate));
ffdelta = ffth->tick_ffcount - cest->update_ffcount;
ffth->tick_time = cest->update_time;
@@ -706,6 +711,14 @@
bintime_addx(&bt, cest->errb_abs * NS_AS_BINFRAC);
ffth->tick_error = bt;
+ /*
+ * Update diffFFC clock member {tick_time_diff}, ensuring
+ * continuity over ticks.
+ */
+ ffth->tick_time_diff = fftimehands->tick_time_diff;
+ ffclock_convert_delta((ffcounter)delta, cest->period, &bt);
+ bintime_add(&ffth->tick_time_diff, &bt);
+
/*
* Update monoFFC member tick_time_mono, standard case.
* ffclock_updated by ffclock_setto_rtc : re-initialize
@@ -726,7 +739,7 @@
else
forward_jump = 0;
- /* Record magnitude of jump */
+ /* Record magnitude of jump. */
bintime_clear(&gap);
if (forward_jump) { // monoFFC < natFFC
gap = ffth->tick_time;
@@ -870,8 +883,9 @@
cest->status |= FFCLOCK_STA_UNSYNC;
ffth->tick_time = fftimehands->tick_time;
- ffth->tick_time_mono = fftimehands->tick_time_mono;
ffth->tick_error = fftimehands->tick_error;
+ ffth->tick_time_diff = fftimehands->tick_time_diff;
+ ffth->tick_time_mono = fftimehands->tick_time_mono;
ffth->period_mono = cest->period;
/* Do not lock but ignore next update from synchronization daemon. */
@@ -904,6 +918,8 @@
gen = ffth->gen;
if ((flags & FFCLOCK_MONO) == FFCLOCK_MONO)
*bt = ffth->tick_time_mono;
+ else if ((flags & FFCLOCK_DIFF) == FFCLOCK_DIFF)
+ *bt = ffth->tick_time_diff;
else
*bt = ffth->tick_time;
*ffcount = ffth->tick_ffcount;
@@ -912,8 +928,7 @@
/*
* Absolute clock conversion. Low level function to convert ffcounter to
- * bintime. The ffcounter is converted using the current ffclock period estimate
- * or the "interpolated period" to ensure monotonicity.
+ * bintime using the selected FFclock.
* NOTE: this conversion may have been deferred, and the clock updated since the
* hardware counter has been read.
*/
@@ -938,7 +953,10 @@
*bt = ffth->tick_time_mono;
ffclock_convert_delta(ffdelta, ffth->period_mono, &bt2);
} else {
- *bt = ffth->tick_time;
+ if ((flags & FFCLOCK_DIFF) == FFCLOCK_DIFF)
+ *bt = ffth->tick_time_diff;
+ else
+ *bt = ffth->tick_time;
ffclock_convert_delta(ffdelta, ffth->cest.period, &bt2);
}
@@ -1146,7 +1164,6 @@
#endif
delta = 0;
-
do {
th = timehands;
gen = atomic_load_acq_int(&th->th_generation);
@@ -1165,6 +1182,7 @@
ffi = &clock_snap->ff_info;
ffth = fftimehands;
ffi->tick_time = ffth->tick_time;
+ ffi->tick_time_diff = ffth->tick_time_diff;
ffi->tick_time_mono = ffth->tick_time_mono;
ffi->period = ffth->cest.period;
ffi->period_mono = ffth->period_mono;
@@ -1206,7 +1224,14 @@
/*
* Convert a sysclock snapshot into a struct bintime based on the specified
- * clock source and flags.
+ * clock paradigm, and flags. Not all flags combinations are compatible.
+ * The following are enforced for FFclocks:
+ * - UPTIME and MONO each supercede DIFF requests for diffFFC
+ * - UPTIME supercedes MONO
+ * - MONO implies LEAPSEC
+ * Default settings (no flags set):
+ * FBclock: the usual UTC clock (not FAST)
+ * FFclock: the natFFC UTC clock (not FAST)
*/
int
sysclock_snap2bintime(struct sysclock_snap *cs, struct bintime *bt,
@@ -1223,7 +1248,7 @@
*bt = cs->fb_info.tick_time;
/* If snapshot was created with !fast, delta will be >0. */
- if (cs->delta > 0)
+ if (flags & FBCLOCK_FAST && cs->delta > 0)
bintime_addx(bt, cs->fb_info.th_scale * cs->delta);
if ((flags & FBCLOCK_UPTIME) == 0) {
@@ -1237,23 +1262,26 @@
*bt = cs->ff_info.tick_time_mono;
period = cs->ff_info.period_mono;
} else {
- *bt = cs->ff_info.tick_time;
period = cs->ff_info.period;
+ if ((flags & FFCLOCK_DIFF) && !(flags & FFCLOCK_UPTIME))
+ *bt = cs->ff_info.tick_time_diff;
+ else
+ *bt = cs->ff_info.tick_time;
}
/* If snapshot was created with !fast, delta will be >0. */
- if (cs->delta > 0) {
+ if (flags & FFCLOCK_FAST && cs->delta > 0) {
ffclock_convert_delta((ffcounter)cs->delta,period,&bt2);
bintime_add(bt, &bt2);
}
- /* Leap second adjustment. */
- if (flags & FFCLOCK_LEAPSEC)
- bt->sec -= cs->ff_info.leapsec_adjustment;
-
- /* Boot time adjustment, for uptime/monotonic clocks. */
+ /* Add appropriate const for Uptime, UTC, or diffFFC clock. */
if (flags & FFCLOCK_UPTIME)
bintime_sub(bt, &ffclock_boottime);
+ else // UTC
+ if (!(flags & FFCLOCK_DIFF) || flags & FFCLOCK_MONO)
+ bt->sec -= cs->ff_info.leapsec_adjustment;
+ // else Diff
break;
#endif
default:
diff --git a/sys/sys/timeffc.h b/sys/sys/timeffc.h
--- a/sys/sys/timeffc.h
+++ b/sys/sys/timeffc.h
@@ -98,19 +98,20 @@
* Flags for use by sysclock_snap2bintime() and various ffclock_ functions to
* control how the timecounter hardware is read and how the hardware snapshot is
* converted into absolute time.
- * The flags all set independent bits and so are OR-able.
- * {FB|FF}CLOCK_FAST: Do not read the hardware counter, instead using the
- * value at last tick. The time returned has a resolution
- * of the kernel tick timer (1/hz [s]).
- * FFCLOCK_MONO: Linear interpolation of ffclock time to guarantee
- * monotonic time.
- * FFCLOCK_LEAPSEC: Include leap seconds.
- * {FB|FF}CLOCK_UPTIME: Time stamp should be relative to system boot, not epoch.
+ * The flags all set independent bits and so are OR-able. However not
+ * all combinations are compatible with a meaningful clock.
+ * {FB|FF}CLOCK_FAST: Do not read the hardware counter, instead use the
+ * value recorded at the last tc-tick update
+ * FFCLOCK_DIFF: Read diffFFC (natFFC is the default)
+ * FFCLOCK_MONO: Read monoFFC (natFFC is the default)
+ * FFCLOCK_LEAPSEC: Include leap seconds seen since boot
+ * {FB|FF}CLOCK_UPTIME: Uptime since system boot (default is UTC)
*/
#define FFCLOCK_FAST 0x00000001
-#define FFCLOCK_MONO 0x00000002
-#define FFCLOCK_LEAPSEC 0x00000004
-#define FFCLOCK_UPTIME 0x00000008
+#define FFCLOCK_DIFF 0x00000002
+#define FFCLOCK_MONO 0x00000004
+#define FFCLOCK_LEAPSEC 0x00000008
+#define FFCLOCK_UPTIME 0x00000010
#define FFCLOCK_MASK 0x0000ffff
#define FBCLOCK_FAST 0x00010000 /* Currently unused. */

File Metadata

Mime Type
text/plain
Expires
Thu, Jul 23, 2:21 PM (10 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35401713
Default Alt Text
D42939.id.diff (10 KB)

Event Timeline