Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102868974
D46268.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D46268.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D46268: Implement CLOCK_TAI
Attached
Detach File
Event Timeline
Log In to Comment