Page MenuHomeFreeBSD

D46268.diff
No OneTemporary

D46268.diff

diff --git a/lib/libsys/_umtx_op.2 b/lib/libsys/_umtx_op.2
--- a/lib/libsys/_umtx_op.2
+++ b/lib/libsys/_umtx_op.2
@@ -210,6 +210,8 @@
.It
.Dv CLOCK_SECOND
.It
+.Dv CLOCK_TAI
+.It
.Dv CLOCK_UPTIME
.It
.Dv CLOCK_UPTIME_FAST
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,11 +99,20 @@
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
.Dv CLOCK_BOOTTIME ,
.Dv CLOCK_REALTIME ,
+.Dv CLOCK_TAI ,
.Dv CLOCK_MONOTONIC ,
and
.Dv CLOCK_UPTIME
@@ -202,7 +211,8 @@
.Dv CLOCK_MONOTONIC_PRECISE ,
.Dv CLOCK_REALTIME_FAST ,
.Dv CLOCK_REALTIME_PRECISE ,
-.Dv CLOCK_SECOND
+.Dv CLOCK_SECOND ,
+.Dv CLOCK_TAI ,
.Dv CLOCK_UPTIME ,
.Dv CLOCK_UPTIME_FAST ,
and
diff --git a/lib/libsys/nanosleep.2 b/lib/libsys/nanosleep.2
--- a/lib/libsys/nanosleep.2
+++ b/lib/libsys/nanosleep.2
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 3, 2022
+.Dd August 10, 2024
.Dt NANOSLEEP 2
.Os
.Sh NAME
@@ -124,6 +124,8 @@
.It
CLOCK_SECOND
.It
+CLOCK_TAI
+.It
CLOCK_UPTIME
.It
CLOCK_UPTIME_FAST
diff --git a/lib/libthr/thread/thr_condattr.c b/lib/libthr/thread/thr_condattr.c
--- a/lib/libthr/thread/thr_condattr.c
+++ b/lib/libthr/thread/thr_condattr.c
@@ -94,6 +94,7 @@
if (attr == NULL || *attr == NULL)
return (EINVAL);
if (clock_id != CLOCK_REALTIME &&
+ clock_id != CLOCK_TAI &&
clock_id != CLOCK_VIRTUAL &&
clock_id != CLOCK_PROF &&
clock_id != CLOCK_MONOTONIC) {
diff --git a/share/man/man3/pthread_condattr.3 b/share/man/man3/pthread_condattr.3
--- a/share/man/man3/pthread_condattr.3
+++ b/share/man/man3/pthread_condattr.3
@@ -85,7 +85,8 @@
.Xr pthread_cond_timedwait 3
and may be set to
.Dv CLOCK_REALTIME
-(default)
+(default),
+.Dv CLOCK_TAI ,
or
.Dv CLOCK_MONOTONIC .
.Pp
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);
@@ -451,6 +463,7 @@
case CLOCK_REALTIME:
case CLOCK_REALTIME_FAST:
case CLOCK_REALTIME_PRECISE:
+ case CLOCK_TAI:
case CLOCK_MONOTONIC:
case CLOCK_MONOTONIC_FAST:
case CLOCK_MONOTONIC_PRECISE:
@@ -515,6 +528,7 @@
case CLOCK_REALTIME_PRECISE:
case CLOCK_REALTIME_FAST:
case CLOCK_SECOND:
+ case CLOCK_TAI:
is_abs_real = (flags & TIMER_ABSTIME) != 0;
break;
case CLOCK_MONOTONIC:
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -686,6 +686,7 @@
timo->is_abs_real = clockid == CLOCK_REALTIME ||
clockid == CLOCK_REALTIME_FAST ||
clockid == CLOCK_REALTIME_PRECISE ||
+ clockid == CLOCK_TAI ||
clockid == CLOCK_SECOND;
}
}
@@ -780,6 +781,7 @@
case CLOCK_PROF:
case CLOCK_THREAD_CPUTIME_ID:
case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_TAI: /* Boot time is not necessarily stable in TAI */
default:
kern_clock_gettime(curthread, timo->clockid, &timo->cur);
if (timespeccmp(&timo->end, &timo->cur, <=))
@@ -2944,8 +2946,9 @@
umtx_key_release(&uq->uq_key);
return (EFAULT);
}
- if (clockid < CLOCK_REALTIME ||
- clockid >= CLOCK_THREAD_CPUTIME_ID) {
+ if ((clockid < CLOCK_REALTIME ||
+ clockid >= CLOCK_THREAD_CPUTIME_ID) &&
+ clockid != CLOCK_TAI) {
/* hmm, only HW clock id will work. */
umtx_key_release(&uq->uq_key);
return (EINVAL);
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
Tue, Nov 19, 5:31 AM (21 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14711140
Default Alt Text
D46268.diff (8 KB)

Event Timeline