sys: MacOS X driver ported from NetBSD
This commit is contained in:
parent
8de04a808d
commit
d6aafa3f64
8 changed files with 378 additions and 3 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -2,6 +2,8 @@
|
|||
.vimrc
|
||||
*.o
|
||||
*.swp
|
||||
*.dSYM
|
||||
*.DS_Store
|
||||
RELEASES
|
||||
Makefile
|
||||
chrony.conf.5
|
||||
|
|
|
@ -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
|
||||
|
|
7
configure
vendored
7
configure
vendored
|
@ -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
|
||||
|
|
|
@ -94,6 +94,7 @@ typedef enum {
|
|||
LOGF_Sys,
|
||||
LOGF_SysGeneric,
|
||||
LOGF_SysLinux,
|
||||
LOGF_SysMacOSX,
|
||||
LOGF_SysNetBSD,
|
||||
LOGF_SysSolaris,
|
||||
LOGF_SysSunOS,
|
||||
|
|
12
sys.c
12
sys.c
|
@ -46,6 +46,10 @@
|
|||
#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
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
314
sys_macosx.c
Normal file
314
sys_macosx.c
Normal file
|
@ -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
|
37
sys_macosx.h
Normal file
37
sys_macosx.h
Normal file
|
@ -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
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue