Page MenuHomeFreeBSD

D46268.id141979.diff
No OneTemporary

D46268.id141979.diff

diff --git a/lib/libsys/clock_gettime.2 b/lib/libsys/clock_gettime.2
--- a/lib/libsys/clock_gettime.2
+++ b/lib/libsys/clock_gettime.2
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd June 28, 2024
+.Dd August 10, 2024
.Dt CLOCK_GETTIME 2
.Os
.Sh NAME
@@ -99,6 +99,14 @@
Returns the execution time of the calling process.
.It Dv CLOCK_THREAD_CPUTIME_ID
Returns the execution time of the calling thread.
+.It Dv CLOCK_TAI
+Increments in SI seconds like a wall clock.
+It uses a 1970 epoch and implements the TAI timescale.
+Similar to CLOCK_REALTIME, except does not include leap seconds and will
+increase monotonically during a leap second.
+Will return EINVAL if the current offset between TAI and UTC is not known,
+which may be the case early in boot before NTP or other time daemon has
+synchronized.
.El
.Pp
The clock IDs
diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c
--- a/sys/kern/kern_ntptime.c
+++ b/sys/kern/kern_ntptime.c
@@ -154,6 +154,7 @@
static int time_state = TIME_OK; /* clock state */
int time_status = STA_UNSYNC; /* clock status bits */
static long time_tai; /* TAI offset (s) */
+bool time_tai_set = false; /* Whether time_tai has been set */
static long time_monitor; /* last time offset scaled (ns) */
static long time_constant; /* poll interval (shift) (s) */
static long time_precision = 1; /* clock precision (ns) */
@@ -388,8 +389,10 @@
time_constant = ntv->constant;
}
if (modes & MOD_TAI) {
- if (ntv->constant > 0) /* XXX zero & negative numbers ? */
+ if (ntv->constant > 0) { /* XXX zero & negative numbers ? */
time_tai = ntv->constant;
+ time_tai_set = true;
+ }
}
#ifdef PPS_SYNC
if (modes & MOD_PPSMAX) {
@@ -504,7 +507,7 @@
* simulation.
*/
void
-ntp_update_second(int64_t *adjustment, time_t *newsec)
+ntp_update_second(int64_t *adjustment, time_t *newsec, long *tai_off)
{
int tickrate;
l_fp ftemp; /* 32/64-bit temporary */
@@ -624,6 +627,7 @@
L_ADD(time_adj, ftemp);
}
*adjustment = time_adj;
+ *tai_off = time_tai;
#ifdef PPS_SYNC
if (pps_valid > 0)
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
@@ -72,6 +72,7 @@
uint64_t th_scale;
u_int th_large_delta;
u_int th_offset_count;
+ long th_tai_offset;
struct bintime th_offset;
struct bintime th_bintime;
struct timeval th_microtime;
@@ -1038,6 +1039,7 @@
/* Internal NTP status and error estimates. */
extern int time_status;
extern long time_esterror;
+extern bool time_tai_set;
/*
* Take a snapshot of sysclock data which can be used to compare system clocks
@@ -1066,6 +1068,7 @@
th = timehands;
gen = atomic_load_acq_int(&th->th_generation);
fbi->th_scale = th->th_scale;
+ fbi->th_tai_offset = th->th_tai_offset;
fbi->tick_time = th->th_offset;
#ifdef FFCLOCK
ffth = fftimehands;
@@ -1139,6 +1142,11 @@
getboottimebin(&boottimebin);
bintime_add(bt, &boottimebin);
}
+ if (!(flags & FBCLOCK_LEAPSEC)) {
+ if (!time_tai_set)
+ return (EINVAL);
+ bt->sec += cs->fb_info.th_tai_offset;
+ }
break;
#ifdef FFCLOCK
case SYSCLOCK_FFWD:
@@ -1433,7 +1441,8 @@
do {
t = bt.sec;
- ntp_update_second(&th->th_adjustment, &bt.sec);
+ ntp_update_second(&th->th_adjustment, &bt.sec,
+ &th->th_tai_offset);
if (bt.sec != t)
th->th_boottime.sec += bt.sec - t;
--i;
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -49,6 +49,7 @@
#include <sys/proc.h>
#include <sys/posix4.h>
#include <sys/time.h>
+#include <sys/timeffc.h>
#include <sys/timers.h>
#include <sys/timetc.h>
#include <sys/vnode.h>
@@ -318,7 +319,10 @@
kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats)
{
struct timeval sys, user;
+ struct sysclock_snap clk;
+ struct bintime bt;
struct proc *p;
+ int err;
p = td->td_proc;
switch (clock_id) {
@@ -329,6 +333,14 @@
case CLOCK_REALTIME_FAST:
getnanotime(ats);
break;
+ case CLOCK_TAI:
+ sysclock_getsnapshot(&clk, 0);
+ err = sysclock_snap2bintime(&clk, &bt, clk.sysclock_active,
+ (clk.sysclock_active == SYSCLOCK_FFWD) ? FFCLOCK_LERP : 0);
+ if (err)
+ return (err);
+ bintime2timespec(&bt, ats);
+ break;
case CLOCK_VIRTUAL:
PROC_LOCK(p);
PROC_STATLOCK(p);
diff --git a/sys/sys/_clock_id.h b/sys/sys/_clock_id.h
--- a/sys/sys/_clock_id.h
+++ b/sys/sys/_clock_id.h
@@ -74,6 +74,10 @@
#define CLOCK_PROCESS_CPUTIME_ID 15
#endif /* __POSIX_VISIBLE >= 199309 */
+#ifdef __BSD_VISIBLE
+#define CLOCK_TAI 16
+#endif
+
/*
* Linux compatible names.
*/
diff --git a/sys/sys/timeffc.h b/sys/sys/timeffc.h
--- a/sys/sys/timeffc.h
+++ b/sys/sys/timeffc.h
@@ -89,7 +89,7 @@
* of the kernel tick timer (1/hz [s]).
* FFCLOCK_LERP: Linear interpolation of ffclock time to guarantee
* monotonic time.
- * FFCLOCK_LEAPSEC: Include leap seconds.
+ * {FB|FF}CLOCK_LEAPSEC: Include leap seconds.
* {FB|FF}CLOCK_UPTIME: Time stamp should be relative to system boot, not epoch.
*/
#define FFCLOCK_FAST 0x00000001
@@ -100,6 +100,7 @@
#define FBCLOCK_FAST 0x00010000 /* Currently unused. */
#define FBCLOCK_UPTIME 0x00020000
+#define FBCLOCK_LEAPSEC 0x00040000
#define FBCLOCK_MASK 0xffff0000
/*
@@ -111,6 +112,7 @@
struct bintime error;
struct bintime tick_time;
uint64_t th_scale;
+ long th_tai_offset;
int status;
};
diff --git a/sys/sys/timex.h b/sys/sys/timex.h
--- a/sys/sys/timex.h
+++ b/sys/sys/timex.h
@@ -154,7 +154,7 @@
#ifdef __FreeBSD__
#ifdef _KERNEL
-void ntp_update_second(int64_t *adjustment, time_t *newsec);
+void ntp_update_second(int64_t *adjustment, time_t *newsec, long *tai_off);
#else /* !_KERNEL */
#include <sys/cdefs.h>

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 16, 11:08 PM (18 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28792992
Default Alt Text
D46268.id141979.diff (5 KB)

Event Timeline