Skip to content

Commit

Permalink
ts2phc: Don't switch system clock to nanosecond mode.
Browse files Browse the repository at this point in the history
ts2phc is not synchronizing the system clock and should not switch the
clock to the nanosecond mode with adjtimex(modes=ADJ_NANO) or make any
other modifications to it. The process that is controlling the clock
(e.g. an NTP client) might not be using the nanosecond mode.

There are two instances of the adjtimex() call in the code. One is used
only to read the clock and can be replaced with faster clock_gettime().
The other instance is also reading the TAI offset. Instead of switching
to the nanosecond mode, change the timestamp conversion to handle both
microsecond and nanosecond modes according to the current clock status.

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
  • Loading branch information
mlichvar authored and richardcochran committed Feb 19, 2024
1 parent 17195fd commit f271257
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 9 deletions.
6 changes: 4 additions & 2 deletions ts2phc_generic_pps_source.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ static int get_ntx(struct timex *ntx)
return -1;

memset(ntx, 0, sizeof(*ntx));
ntx->modes = ADJ_NANO;
code = adjtimex(ntx);
if (code == -1) {
pr_err("adjtimex failed: %m");
Expand Down Expand Up @@ -93,7 +92,10 @@ static int ts2phc_generic_pps_source_getppstime(struct ts2phc_pps_source *src,
}

ts->tv_sec = ntx.time.tv_sec + tai_offset;
ts->tv_nsec = ntx.time.tv_usec;
if (ntx.status & STA_NANO)
ts->tv_nsec = ntx.time.tv_usec;
else
ts->tv_nsec = ntx.time.tv_usec * 1000;

return 0;
}
Expand Down
10 changes: 3 additions & 7 deletions ts2phc_nmea_pps_source.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,13 @@ static int open_nmea_connection(const char *host, const char *port,

static void *monitor_nmea_status(void *arg)
{
struct timespec rxtime, rxtime_rt, tmo = { 2, 0 };
struct nmea_parser *np = nmea_parser_create();
struct pollfd pfd = { -1, POLLIN | POLLPRI };
char *host, input[256], *port, *ptr, *uart;
struct ts2phc_nmea_pps_source *s = arg;
struct timespec rxtime, tmo = { 2, 0 };
int cnt, num, parsed, baud;
struct nmea_rmc rmc;
struct timex ntx;

if (!np) {
pr_err("failed to create NMEA parser");
Expand All @@ -79,8 +78,6 @@ static void *monitor_nmea_status(void *arg)
port = config_get_string(s->config, NULL, "ts2phc.nmea_remote_port");
uart = config_get_string(s->config, NULL, "ts2phc.nmea_serialport");
baud = config_get_int(s->config, NULL, "ts2phc.nmea_baudrate");
memset(&ntx, 0, sizeof(ntx));
ntx.modes = ADJ_NANO;

while (is_running()) {
if (pfd.fd == -1) {
Expand All @@ -92,7 +89,7 @@ static void *monitor_nmea_status(void *arg)
}
num = poll(&pfd, 1, NMEA_TMO);
clock_gettime(CLOCK_MONOTONIC, &rxtime);
adjtimex(&ntx);
clock_gettime(CLOCK_REALTIME, &rxtime_rt);
if (num < 0) {
pr_err("poll failed");
break;
Expand Down Expand Up @@ -124,8 +121,7 @@ static void *monitor_nmea_status(void *arg)
if (!nmea_parse(np, ptr, cnt, &rmc, &parsed)) {
pthread_mutex_lock(&s->mutex);
s->local_monotime = rxtime;
s->local_utctime.tv_sec = ntx.time.tv_sec;
s->local_utctime.tv_nsec = ntx.time.tv_usec;
s->local_utctime = rxtime_rt;
s->rmc_utctime = rmc.ts;
s->rmc_fix_valid = rmc.fix_valid;
pthread_mutex_unlock(&s->mutex);
Expand Down

0 comments on commit f271257

Please sign in to comment.