]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Add SHM refclock driver
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 5 May 2009 07:17:38 +0000 (09:17 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 5 May 2009 21:06:04 +0000 (23:06 +0200)
Makefile.in
refclock.c
refclock_shm.c [new file with mode: 0644]

index 8058648f0d30d7369963c175c93dfa4c7a976f02..cd6a3f02571cb6bd90e2a52bad9ecbca5085cfcb 100644 (file)
@@ -41,7 +41,7 @@ OBJS = util.o sched.o regress.o local.o \
        logging.o conf.o cmdmon.o md5.o keys.o \
        nameserv.o acquire.o manual.o addrfilt.o \
        cmdparse.o mkdirpp.o rtc.o pktlength.o clientlog.o \
-       broadcast.o refclock.o
+       broadcast.o refclock.o refclock_shm.o
 
 EXTRA_OBJS=@EXTRA_OBJECTS@
 
index 372767a48e1f155ee19b2ece730258d4853ad567..3b1f9519a8d3c573199a19ba68f755f2d22bbca0 100644 (file)
@@ -33,6 +33,9 @@
 #include "logging.h"
 #include "sched.h"
 
+/* list of refclock drivers */
+extern RefclockDriver RCL_SHM_driver;
+
 struct RCL_Instance_Record {
   RefclockDriver *driver;
   void *data;
@@ -79,7 +82,8 @@ RCL_AddRefclock(RefclockParameters *params)
   if (n_sources == MAX_RCL_SOURCES)
     return 0;
 
-  if (0) {
+  if (strncmp(params->driver_name, "SHM", 4) == 0) {
+    inst->driver = &RCL_SHM_driver;
   } else {
     LOG_FATAL(LOGF_Refclock, "unknown refclock driver %s", params->driver_name);
     return 0;
diff --git a/refclock_shm.c b/refclock_shm.c
new file mode 100644 (file)
index 0000000..116c8d0
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+  chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Richard P. Curnow  2009
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * 
+ **********************************************************************
+
+  =======================================================================
+
+  SHM refclock driver.
+
+  */
+
+#include "refclock.h"
+#include "logging.h"
+#include "util.h"
+
+#include <sys/types.h>
+#include <sys/shm.h>
+
+#define SHMKEY 0x4e545030
+
+struct shmTime {
+  int    mode; /* 0 - if valid set
+                *       use values, 
+                *       clear valid
+                * 1 - if valid set 
+                *       if count before and after read of values is equal,
+                *         use values 
+                *       clear valid
+                */
+  int    count;
+  time_t clockTimeStampSec;
+  int    clockTimeStampUSec;
+  time_t receiveTimeStampSec;
+  int    receiveTimeStampUSec;
+  int    leap;
+  int    precision;
+  int    nsamples;
+  int    valid;
+  int    dummy[10]; 
+};
+
+static int shm_initialise(RCL_Instance instance) {
+  int id, param;
+  struct shmTime *shm;
+
+  param = RCL_GetDriverParameter(instance);
+
+  id = shmget(SHMKEY + param, sizeof (struct shmTime), IPC_CREAT | 0700);
+  if (id == -1) {
+    LOG_FATAL(LOGF_Refclock, "shmget() failed");
+    return 0;
+  }
+   
+  shm = (struct shmTime *)shmat(id, 0, 0);
+  if ((long)shm == -1) {
+    LOG_FATAL(LOGF_Refclock, "shmat() failed");
+    return 0;
+  }
+
+  RCL_SetDriverData(instance, shm);
+  return 1;
+}
+
+static void shm_finalise(RCL_Instance instance)
+{
+  shmdt(RCL_GetDriverData(instance));
+}
+
+static int shm_poll(RCL_Instance instance)
+{
+  struct timeval tv1, tv2;
+  struct shmTime t, *shm;
+  double offset;
+
+  shm = (struct shmTime *)RCL_GetDriverData(instance);
+
+  t = *shm;
+  
+  if ((t.mode == 1 && t.count != shm->count) ||
+    !(t.mode == 0 || t.mode == 1) || !t.valid) {
+#if 0
+    LOG(LOGS_INFO, LOGF_Refclock, "sample ignored mode: %d count: %d valid: %d", t.mode, t.count, t.valid);
+#endif
+    return 0;
+  }
+
+  shm->valid = 0;
+
+  tv1.tv_sec = t.receiveTimeStampSec;
+  tv1.tv_usec = t.receiveTimeStampUSec;
+  tv2.tv_sec = t.clockTimeStampSec;
+  tv2.tv_usec = t.clockTimeStampUSec;
+
+  UTI_DiffTimevalsToDouble(&offset, &tv2, &tv1);
+  return RCL_AddSample(instance, &tv1, offset, t.leap);
+}
+
+RefclockDriver RCL_SHM_driver = {
+  shm_initialise,
+  shm_finalise,
+  shm_poll
+};