[chrony-dev] [PATCH] Port to MacOS X |
[ Thread Index |
Date Index
| More chrony.tuxfamily.org/chrony-dev Archives
]
- To: chrony-dev@xxxxxxxxxxxxxxxxxxxx
- Subject: [chrony-dev] [PATCH] Port to MacOS X
- From: Bryan Christianson <bryan@xxxxxxxxxxxxx>
- Date: Wed, 10 Jun 2015 03:43:23 +1200
- Cc: Bryan Christianson <bryan@xxxxxxxxxxxxx>
- Dkim-signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=smtpcorp.com; s=a0-2; h=Feedback-ID:X-Smtpcorp-Track:Subject:Message-Id: Date:To:From; bh=/UURc8vYTC10pzq3QYoys3UiT4XVyktQANY/yIbBXOw=; b=wA36t0AusGNb 8PGKAZcYXH088V3M6x7JFjdfw2BzvsdfuNjUkMD/vu70yjIktV5AdZfr56WGVUOXNLys5sMuQ3C0J SHcPbbKqjlo6Osyw6QoyIHuhsfOCMmoiIZoaVdgBpWL4RUbBqtDyzANwJogLzx9Jg8KOqhsKRrn0z rMBdcFoQW0S6DWNZr/f7vIt+AjUOxabGH5gd4JrPRkhc0Gfjpv4KeAT4SmVDGBsW7sU+ehVDFJfGu wfhUq7zLoLVDcOEn1nirUJLQh4VOhML1AOGF4fFqrQ+Y+v6SCW+7vJyOy3dJhYAvgr4G2GyDHd7hl 5TSYsBv0jsc3AYpQjlYjQw==;
- Feedback-id: 149811m:149811acx33YQ:149811s7oJXu2sTg:SMTPCORP
---
Makefile.in | 5 +-
configure | 5 +
logging.h | 1 +
sys.c | 12 ++
sys_macos.c | 394 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sys_macos.h | 36 ++++++
sysincl.h | 4 +-
7 files changed, 454 insertions(+), 3 deletions(-)
create mode 100644 sys_macos.c
create mode 100644 sys_macos.h
diff --git a/Makefile.in b/Makefile.in
index 6396d8d..c7bbcac 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -77,8 +77,9 @@ distclean : clean
-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 -f *.o *.s chronyc chronyd core *~ chrony.info chrony.html chrony.txt config.*
-rm -rf .deps
+ -rm -rf docheck.dSYM
getdate.c :
bison -o getdate.c getdate.y
@@ -112,6 +113,8 @@ install: chronyd chronyc chrony.txt
chmod 644 $(DESTDIR)$(DOCDIR)/COPYING
cp README $(DESTDIR)$(DOCDIR)/README
chmod 644 $(DESTDIR)$(DOCDIR)/README
+ cp chrony.1 $(DESTDIR)$(MANDIR)/man1
+ chmod 644 $(DESTDIR)$(MANDIR)/man1/chrony.1
cp chronyc.1 $(DESTDIR)$(MANDIR)/man1
chmod 644 $(DESTDIR)$(MANDIR)/man1/chronyc.1
cp chronyd.8 $(DESTDIR)$(MANDIR)/man8
diff --git a/configure b/configure
index b05b32b..ebafb50 100755
--- a/configure
+++ b/configure
@@ -398,6 +398,11 @@ case $SYSTEM in
add_def SUNOS
echo "Configuring for $SYSTEM (using SunOS driver)"
;;
+ Darwin-* )
+ EXTRA_OBJECTS="sys_macos.o"
+ MYLDFLAGS="-lresolv" $MYLDFLAGS
+ echo "Configuring for $SYSTEM"
+ ;;
NetBSD-* )
EXTRA_OBJECTS="sys_netbsd.o"
EXTRA_LIBS="-lkvm"
diff --git a/logging.h b/logging.h
index 6dfb774..649ead1 100644
--- a/logging.h
+++ b/logging.h
@@ -94,6 +94,7 @@ typedef enum {
LOGF_Sys,
LOGF_SysGeneric,
LOGF_SysLinux,
+ LOGF_SysMacOS,
LOGF_SysNetBSD,
LOGF_SysSolaris,
LOGF_SysSunOS,
diff --git a/sys.c b/sys.c
index 6b6aff4..387f94c 100644
--- a/sys.c
+++ b/sys.c
@@ -46,6 +46,10 @@
#include "sys_netbsd.h"
#endif
+#if defined (__APPLE__)
+#include "sys_macos.h"
+#endif
+
/* ================================================== */
void
@@ -68,6 +72,10 @@ SYS_Initialise(void)
SYS_NetBSD_Initialise();
#endif
+#if defined(__APPLE__)
+ SYS_MacOS_Initialise();
+#endif
+
}
/* ================================================== */
@@ -91,6 +99,10 @@ SYS_Finalise(void)
#if defined(__NetBSD__)
SYS_NetBSD_Finalise();
#endif
+
+#if defined(__APPLE__)
+ SYS_MacOS_Finalise();
+#endif
}
/* ================================================== */
diff --git a/sys_macos.c b/sys_macos.c
new file mode 100644
index 0000000..02743c5
--- /dev/null
+++ b/sys_macos.c
@@ -0,0 +1,394 @@
+/*
+ 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 operating system.
+ */
+
+#include "config.h"
+
+#ifdef __APPLE__
+
+#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_macos.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 timespec 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 inline void
+ts_add_double(struct timespec *a, const struct timespec *b, double c)
+{
+ time_t secs;
+ time_t nsecs;
+
+ secs = (time_t)c;
+ nsecs = (c - (time_t)c) * 1E9;
+
+ secs += b->tv_sec;
+ nsecs += b->tv_nsec;
+
+ if(nsecs >= 1E9) {
+ nsecs -= 1E9;
+ secs++;
+ }
+
+ if(nsecs <= -1E9) {
+ nsecs += 1E9;
+ secs--;
+ }
+ a->tv_sec = secs;
+ a->tv_nsec = nsecs;
+}
+
+/* ================================================== */
+
+static inline double
+ts_diff_to_double(const struct timespec *a, const struct timespec *b)
+{
+ double result;
+
+ result = (a->tv_nsec - b->tv_nsec) / 1.0E9;
+ result += (a->tv_sec - b->tv_sec);
+
+ return result;
+}
+
+/* ================================================== */
+
+#include <mach/clock.h>
+#include <mach/mach.h>
+
+static inline void
+getwallclock(struct timespec *ts)
+{
+#if 0
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) < 0) {
+ LOG_FATAL(LOGF_SysMacOS, "gettimeofday() failed");
+ }
+
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = tv.tv_usec * 1000;
+#else
+ clock_serv_t cclock;
+ mach_timespec_t mts;
+
+ host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
+ clock_get_time(cclock, &mts);
+ mach_port_deallocate(mach_task_self(), cclock);
+
+ ts->tv_sec = mts.tv_sec;
+ ts->tv_nsec = mts.tv_nsec;
+#endif
+}
+
+/* ================================================== */
+
+static inline int
+setwallclock(const struct timespec *clock)
+{
+ struct timeval tv;
+
+ tv.tv_sec = clock->tv_sec;
+ tv.tv_usec = (int)clock->tv_nsec / 1000;
+
+ if (settimeofday(&tv, NULL) < 0) {
+ DEBUG_LOG(LOGF_SysMacOS, "settimeofday() failed");
+ return -1;
+ }
+ return 0;
+}
+
+/* ================================================== */
+
+static inline void
+adjustclock(double delta, double *old_delta)
+{
+ struct timeval tv_delta;
+ struct timeval tv_old_delta;
+
+ UTI_DoubleToTimeval(delta, &tv_delta);
+
+ if (adjtime(&tv_delta, &tv_old_delta) < 0) {
+ LOG_FATAL(LOGF_SysMacOS, "adjtime() failed");
+ }
+
+ UTI_TimevalToDouble(&tv_old_delta, old_delta);
+}
+
+/* ================================================== */
+
+static void
+clock_initialise(void)
+{
+ double newadj, oldadj;
+
+ offset_register = 0.0;
+ adjustment_requested = 0.0;
+ current_freq = 0.0;
+
+ getwallclock(&T0);
+
+ newadj = 0;
+ adjustclock(newadj, &oldadj);
+}
+
+/* ================================================== */
+
+static void
+clock_finalise(void)
+{
+ /* Nothing to do yet */
+
+}
+
+/* ================================================== */
+
+static void
+start_adjust(void)
+{
+ double newadj;
+ struct timespec T1;
+ double elapsed, accrued_error;
+ double adjust_required;
+ long delta, tickdelta;
+ double rounding_error;
+ double old_adjust_remaining;
+
+ /* Determine the amount of error built up since the last adjustment */
+ getwallclock(&T1);
+
+ elapsed = ts_diff_to_double(&T1, &T0);
+ accrued_error = elapsed * current_freq;
+
+ adjust_required = - (accrued_error + offset_register);
+
+ /* At this point, we need to round the required adjustment the
+ same way the kernel does. */
+
+ delta = adjust_required * 1E6;
+ if (delta > kern_bigadj || delta < -kern_bigadj)
+ tickdelta = 10 * kern_tickadj;
+ else
+ tickdelta = kern_tickadj;
+ if (delta % tickdelta)
+ delta = delta / tickdelta * tickdelta;
+
+ newadj = delta / 1.0E6;
+
+ /* Add rounding error back onto offset register. */
+ rounding_error = newadj - adjust_required;
+
+ adjustclock(newadj, &old_adjust_remaining);
+
+ offset_register = rounding_error - old_adjust_remaining;
+
+ T0 = T1;
+ adjustment_requested = newadj;
+}
+
+/* ================================================== */
+
+static void
+stop_adjust(void)
+{
+ struct timespec T1;
+ double adjustment_remaining, adjustment_achieved;
+ double elapsed, elapsed_plus_adjust;
+
+ adjustclock(0, &adjustment_remaining);
+
+ getwallclock(&T1);
+
+ elapsed = ts_diff_to_double(&T1, &T0);
+
+ 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 timespec new_time;
+ struct timespec old_time;
+
+ stop_adjust();
+
+ getwallclock(&old_time);
+
+ ts_add_double(&new_time, &old_time, -offset);
+
+ if(setwallclock(&new_time) < 0) {
+ return 0;
+ }
+
+ ts_add_double(&T0, &T0, offset);
+
+ 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_MacOS_Initialise(void)
+{
+ size_t len;
+ struct clockinfo clockinfo;
+ int mib[2];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_CLOCKRATE;
+
+ len = sizeof(clockinfo);
+ int result = sysctl(mib, 2, &clockinfo, &len, NULL, 0);
+
+ if(result < 0) {
+ LOG_FATAL(LOGF_SysMacOS, "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_MacOS_Finalise(void)
+{
+ clock_finalise();
+}
+
+/* ================================================== */
+
+
+#endif /* __APPLE__ */
diff --git a/sys_macos.h b/sys_macos.h
new file mode 100644
index 0000000..f7ec31c
--- /dev/null
+++ b/sys_macos.h
@@ -0,0 +1,36 @@
+/*
+ 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 driver
+ */
+
+#ifndef GOT_SYS_MACOS_H
+#define GOT_SYS_MACOS_H
+
+void SYS_MacOS_Initialise(void);
+
+void SYS_MacOS_Finalise(void);
+
+#endif
diff --git a/sysincl.h b/sysincl.h
index b0f587c..cea80c8 100644
--- a/sysincl.h
+++ b/sysincl.h
@@ -29,7 +29,7 @@
#ifndef GOT_SYSINCL_H
#define GOT_SYSINCL_H
-#if defined (SOLARIS) || defined(SUNOS) || defined(LINUX) || defined(__NetBSD__)
+#if defined(__APPLE__) || defined (SOLARIS) || defined(SUNOS) || defined(LINUX) || defined(__NetBSD__)
#if !defined(__NetBSD__) && !defined(__FreeBSD__)
#include <alloca.h>
@@ -39,7 +39,7 @@
#include <errno.h>
#include <fcntl.h>
#include <float.h>
-#if !defined(__FreeBSD__)
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
#include <malloc.h>
#endif
#include <math.h>
--
2.3.2 (Apple Git-55)
--
To unsubscribe email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "unsubscribe" in the subject.
For help email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "help" in the subject.
Trouble? Email listmaster@xxxxxxxxxxxxxxxxxxxx.