]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
sys: MacOS X driver ported from NetBSD
authorBryan Christianson <bryan@whatroute.net>
Fri, 12 Jun 2015 19:56:39 +0000 (07:56 +1200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Mon, 15 Jun 2015 12:40:54 +0000 (14:40 +0200)
.gitignore
Makefile.in
configure
logging.h
sys.c
sys_macosx.c [new file with mode: 0644]
sys_macosx.h [new file with mode: 0644]
sysincl.h

index fb24b5808d68aa7d84aafbffa0e347697d2c2d07..9c425529e7d39b0c4fbd9e271aa937a60cc9886d 100644 (file)
@@ -2,6 +2,8 @@
 .vimrc
 *.o
 *.swp
+*.dSYM
+*.DS_Store
 RELEASES
 Makefile
 chrony.conf.5
index 557e2f41b17885a7d4410a320e7c915c55fff076..a031ba33cf10d19d7d906e4f1981bb1e40bdd819 100644 (file)
@@ -73,12 +73,14 @@ $(HASH_OBJ) : $(patsubst %.o,%.c,$(HASH_OBJ))
        $(CC) $(CFLAGS) $(CPPFLAGS) @HASH_COMPILE@ -c $<
 
 distclean : clean
+       -rm -f .DS_Store
        -rm -f Makefile
        -rm -f chrony.conf.5 chrony.texi chronyc.1 chronyd.8
 
 clean :
        -rm -f *.o *.s chronyc chronyd core *~ chrony.info chrony.html chrony.txt
        -rm -rf .deps
+       -rm -rf *.dSYM
 
 getdate.c :
        bison -o getdate.c getdate.y
index b05b32bd5663b6486e94d8876ec95b7cc0b26c82..d069c658db8d4e2f41c4e753caad1144b0d27f39 100755 (executable)
--- a/configure
+++ b/configure
@@ -404,6 +404,13 @@ case $SYSTEM in
         SYSDEFS=""
         echo "Configuring for $SYSTEM"
     ;;
+    Darwin-* )
+        EXTRA_OBJECTS="sys_macosx.o"
+        EXTRA_LIBS="-lresolv"
+        EXTRA_CLI_LIBS="-lresolv"
+        add_def MACOSX
+        echo "Configuring for MacOS X (" $SYSTEM "MacOS X version" $VERSION ")"
+    ;;
     SunOS-i86pc* )                                          
         # Doug Woodward <dougw@whistler.com> reported that this configuration
         # works for Solaris 2.8 / SunOS 5.8 on x86 platforms
index 6dfb7740bc06c8e6015792d8c847edb92c8836b0..b4b4d18f7efa0dcae1f039eff6166ded44fdc75f 100644 (file)
--- a/logging.h
+++ b/logging.h
@@ -94,6 +94,7 @@ typedef enum {
   LOGF_Sys,
   LOGF_SysGeneric,
   LOGF_SysLinux,
+  LOGF_SysMacOSX,
   LOGF_SysNetBSD,
   LOGF_SysSolaris,
   LOGF_SysSunOS,
diff --git a/sys.c b/sys.c
index 6b6aff4191a10bdc27d6fbd5a7b204b68dd529cb..f0c81df654cff1c4fd5e03fa87fb6255e5d0319f 100644 (file)
--- a/sys.c
+++ b/sys.c
 #include "sys_netbsd.h"
 #endif
 
+#if defined (MACOSX)
+#include "sys_macosx.h"
+#endif
+
 /* ================================================== */
 
 void
@@ -68,6 +72,10 @@ SYS_Initialise(void)
   SYS_NetBSD_Initialise();
 #endif
 
+#if defined(MACOSX)
+  SYS_MacOSX_Initialise();
+#endif
+
 }
 
 /* ================================================== */
@@ -91,6 +99,10 @@ SYS_Finalise(void)
 #if defined(__NetBSD__)
   SYS_NetBSD_Finalise();
 #endif
+
+#if defined(MACOSX)
+  SYS_MacOSX_Finalise();
+#endif
 }
 
 /* ================================================== */
diff --git a/sys_macosx.c b/sys_macosx.c
new file mode 100644 (file)
index 0000000..30945a4
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+  chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Richard P. Curnow  1997-2001
+ * Copyright (C) J. Hannken-Illjes  2001
+ * Copyright (C) Bryan Christianson 2015
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ **********************************************************************
+
+  =======================================================================
+
+  Driver file for the MacOS X operating system.
+
+  */
+
+#include "config.h"
+
+#ifdef MACOSX
+
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <nlist.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <signal.h>
+
+#include "sys_macosx.h"
+#include "localp.h"
+#include "logging.h"
+#include "util.h"
+
+/* ================================================== */
+
+/* This register contains the number of seconds by which the local
+   clock was estimated to be fast of reference time at the epoch when
+   gettimeofday() returned T0 */
+
+static double offset_register;
+
+/* This register contains the epoch to which the offset is referenced */
+
+static struct timeval T0;
+
+/* This register contains the current estimate of the system
+   frequency, in absolute (NOT ppm) */
+
+static double current_freq;
+
+/* This register contains the number of seconds of adjustment that
+   were passed to adjtime last time it was called. */
+
+static double adjustment_requested;
+
+/* Kernel parameters to calculate adjtime error. */
+
+static int kern_tickadj;
+static long kern_bigadj;
+
+/* ================================================== */
+
+static void
+clock_initialise(void)
+{
+  struct timeval newadj, oldadj;
+
+  offset_register = 0.0;
+  adjustment_requested = 0.0;
+  current_freq = 0.0;
+
+  if (gettimeofday(&T0, NULL) < 0) {
+    LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
+  }
+
+  newadj.tv_sec = 0;
+  newadj.tv_usec = 0;
+
+  if (adjtime(&newadj, &oldadj) < 0) {
+    LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
+  }
+}
+
+/* ================================================== */
+
+static void
+clock_finalise(void)
+{
+  /* Nothing to do yet */
+}
+
+/* ================================================== */
+
+static void
+start_adjust(void)
+{
+  struct timeval newadj, oldadj;
+  struct timeval T1;
+  double elapsed, accrued_error;
+  double adjust_required;
+  struct timeval exact_newadj;
+  long delta, tickdelta;
+  double rounding_error;
+  double old_adjust_remaining;
+
+  /* Determine the amount of error built up since the last adjustment */
+  if (gettimeofday(&T1, NULL) < 0) {
+    LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
+  }
+
+  UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
+  accrued_error = elapsed * current_freq;
+
+  adjust_required = - (accrued_error + offset_register);
+
+  UTI_DoubleToTimeval(adjust_required, &exact_newadj);
+
+  /* At this point, we need to round the required adjustment the
+     same way the kernel does. */
+
+  delta = exact_newadj.tv_sec * 1000000 + exact_newadj.tv_usec;
+  if (delta > kern_bigadj || delta < -kern_bigadj)
+    tickdelta = 10 * kern_tickadj;
+  else
+    tickdelta = kern_tickadj;
+  if (delta % tickdelta)
+       delta = delta / tickdelta * tickdelta;
+  newadj.tv_sec = 0;
+  newadj.tv_usec = (int)delta;
+  UTI_NormaliseTimeval(&newadj);
+
+  /* Add rounding error back onto offset register. */
+  UTI_DiffTimevalsToDouble(&rounding_error, &newadj, &exact_newadj);
+
+  if (adjtime(&newadj, &oldadj) < 0) {
+    LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
+  }
+
+  UTI_TimevalToDouble(&oldadj, &old_adjust_remaining);
+
+  offset_register = rounding_error - old_adjust_remaining;
+
+  T0 = T1;
+  UTI_TimevalToDouble(&newadj, &adjustment_requested);
+}
+
+/* ================================================== */
+
+static void
+stop_adjust(void)
+{
+  struct timeval T1;
+  struct timeval zeroadj, remadj;
+  double adjustment_remaining, adjustment_achieved;
+  double elapsed, elapsed_plus_adjust;
+
+  zeroadj.tv_sec = 0;
+  zeroadj.tv_usec = 0;
+
+  if (adjtime(&zeroadj, &remadj) < 0) {
+    LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
+  }
+
+  if (gettimeofday(&T1, NULL) < 0) {
+    LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
+  }
+
+  UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
+  UTI_TimevalToDouble(&remadj, &adjustment_remaining);
+
+  adjustment_achieved = adjustment_requested - adjustment_remaining;
+  elapsed_plus_adjust = elapsed - adjustment_achieved;
+
+  offset_register += current_freq * elapsed_plus_adjust - adjustment_remaining;
+
+  adjustment_requested = 0.0;
+  T0 = T1;
+}
+
+/* ================================================== */
+
+/* Positive offset means system clock is fast of true time, therefore
+   slew backwards */
+
+static void
+accrue_offset(double offset, double corr_rate)
+{
+  stop_adjust();
+  offset_register += offset;
+  start_adjust();
+}
+
+/* ================================================== */
+
+/* Positive offset means system clock is fast of true time, therefore
+   step backwards */
+
+static int
+apply_step_offset(double offset)
+{
+  struct timeval old_time, new_time, T1;
+
+  stop_adjust();
+
+  if (gettimeofday(&old_time, NULL) < 0) {
+    LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
+  }
+
+  UTI_AddDoubleToTimeval(&old_time, -offset, &new_time);
+
+  if (settimeofday(&new_time, NULL) < 0) {
+    DEBUG_LOG(LOGF_SysMacOSX, "settimeofday() failed");
+    return 0;
+  }
+
+  UTI_AddDoubleToTimeval(&T0, offset, &T1);
+  T0 = T1;
+
+  start_adjust();
+
+  return 1;
+}
+
+/* ================================================== */
+
+static double
+set_frequency(double new_freq_ppm)
+{
+  stop_adjust();
+  current_freq = new_freq_ppm * 1.0e-6;
+  start_adjust();
+
+  return current_freq * 1.0e6;
+}
+
+/* ================================================== */
+
+static double
+read_frequency(void)
+{
+  return current_freq * 1.0e6;
+}
+
+/* ================================================== */
+
+static void
+get_offset_correction(struct timeval *raw,
+                      double *corr, double *err)
+{
+  stop_adjust();
+  *corr = -offset_register;
+  start_adjust();
+  if (err)
+    *err = 0.0;
+}
+
+/* ================================================== */
+
+void
+SYS_MacOSX_Initialise(void)
+{
+  int result;
+  size_t len;
+  struct clockinfo clockinfo;
+  int mib[2];
+
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_CLOCKRATE;
+
+  len = sizeof(clockinfo);
+  result = sysctl(mib, 2, &clockinfo, &len, NULL, 0);
+
+  if(result < 0) {
+    LOG_FATAL(LOGF_SysMacOSX, "Cannot read clockinfo");
+  }
+  kern_tickadj = clockinfo.tickadj;
+  kern_bigadj = clockinfo.tick;
+
+  clock_initialise();
+
+  lcl_RegisterSystemDrivers(read_frequency, set_frequency,
+                            accrue_offset, apply_step_offset,
+                            get_offset_correction,
+                            NULL /* set_leap */,
+                            NULL /* set_sync_status */);
+}
+
+/* ================================================== */
+
+void
+SYS_MacOSX_Finalise(void)
+{
+  clock_finalise();
+}
+
+/* ================================================== */
+
+#endif
diff --git a/sys_macosx.h b/sys_macosx.h
new file mode 100644 (file)
index 0000000..b579415
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+  chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Richard P. Curnow  1997-2001
+ * Copyright (C) J. Hannken-Illjes  2001
+ * Copyright (C) Bryan Christianson 2015
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ **********************************************************************
+
+  =======================================================================
+
+  Header file for MacOS X driver
+
+  */
+
+#ifndef GOT_SYS_MACOSX_H
+#define GOT_SYS_MACOSX_H
+
+void SYS_MacOSX_Initialise(void);
+
+void SYS_MacOSX_Finalise(void);
+
+#endif
index b0f587c33bd69770052ad35878b6d2720885ec0a..5c1fb374f1123b0426c423a5d9f2720515cddafd 100644 (file)
--- a/sysincl.h
+++ b/sysincl.h
@@ -29,9 +29,9 @@
 #ifndef GOT_SYSINCL_H
 #define GOT_SYSINCL_H
 
-#if defined (SOLARIS) || defined(SUNOS) || defined(LINUX) || defined(__NetBSD__)
+#if defined (SOLARIS) || defined(SUNOS) || defined(LINUX) || defined(__NetBSD__) || defined (MACOSX)
 
-#if !defined(__NetBSD__) && !defined(__FreeBSD__)
+#if !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(MACOSX)
 #include <alloca.h>
 #endif
 #include <assert.h>
@@ -39,7 +39,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <float.h>
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(MACOSX)
 #include <malloc.h>
 #endif
 #include <math.h>