1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- /*
- * ntpshmwrite.c - put time information in SHM segment for ntpd
- *
- * This file is Copyright (c)2010-2018 by the GPSD project
- * SPDX-License-Identifier: BSD-2-clause
- */
- #include "gpsd_config.h" /* must be before all includes */
- #include <errno.h>
- #include <libgen.h>
- #include <math.h>
- #include <stdbool.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <unistd.h>
- #include "ntpshm.h"
- #include "compiler.h"
- #include "timespec.h"
- #define LEAP_NOWARNING 0x0 /* normal, no leap second warning */
- void ntp_write(volatile struct shmTime *shmseg,
- struct timedelta_t *td, int precision, int leap_notify)
- /* put a received fix time into shared memory for NTP */
- {
- struct tm tm;
- /*
- * insist that leap seconds only happen in june and december
- * GPS emits leap pending for 3 months prior to insertion
- * NTP expects leap pending for only 1 month prior to insertion
- * Per http://bugs.ntp.org/1090
- *
- * ITU-R TF.460-6, Section 2.1, says laep seconds can be primarily
- * in Jun/Dec but may be in March or September
- */
- (void)gmtime_r( &(td->real.tv_sec), &tm);
- if ( 5 != tm.tm_mon && 11 != tm.tm_mon ) {
- /* Not june, not December, no way */
- leap_notify = LEAP_NOWARNING;
- }
- /* we use the shmTime mode 1 protocol
- *
- * ntpd does this:
- *
- * reads valid.
- * IFF valid is 1
- * reads count
- * reads values
- * reads count
- * IFF count unchanged
- * use values
- * clear valid
- *
- */
- // should not be needed, but sometimes is...
- TS_NORM(&td->real);
- TS_NORM(&td->clock);
- shmseg->valid = 0;
- shmseg->count++;
- /* We need a memory barrier here to prevent write reordering by
- * the compiler or CPU cache */
- memory_barrier();
- shmseg->clockTimeStampSec = (time_t)td->real.tv_sec;
- shmseg->clockTimeStampUSec = (int)(td->real.tv_nsec/1000);
- shmseg->clockTimeStampNSec = (unsigned)td->real.tv_nsec;
- shmseg->receiveTimeStampSec = (time_t)td->clock.tv_sec;
- shmseg->receiveTimeStampUSec = (int)(td->clock.tv_nsec/1000);
- shmseg->receiveTimeStampNSec = (unsigned)td->clock.tv_nsec;
- shmseg->leap = leap_notify;
- shmseg->precision = precision;
- memory_barrier();
- shmseg->count++;
- shmseg->valid = 1;
- }
- /* end */
|