2 chronyd/chronyc - Programs for keeping computer clocks accurate.
4 **********************************************************************
5 * Copyright (C) Miroslav Lichvar 2009
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 **********************************************************************
22 =======================================================================
36 #define SHMKEY 0x4e545030
39 int mode
; /* 0 - if valid set
43 * if count before and after read of values is equal,
48 time_t clockTimeStampSec
;
49 int clockTimeStampUSec
;
50 time_t receiveTimeStampSec
;
51 int receiveTimeStampUSec
;
56 int clockTimeStampNSec
;
57 int receiveTimeStampNSec
;
61 static int shm_initialise(RCL_Instance instance
) {
62 const char *options
[] = {"perm", NULL
};
67 RCL_CheckDriverOptions(instance
, options
);
69 param
= atoi(RCL_GetDriverParameter(instance
));
70 s
= RCL_GetDriverOption(instance
, "perm");
71 perm
= s
? strtol(s
, NULL
, 8) & 0777 : 0600;
73 id
= shmget(SHMKEY
+ param
, sizeof (struct shmTime
), IPC_CREAT
| perm
);
75 LOG_FATAL("shmget() failed : %s", strerror(errno
));
79 shm
= (struct shmTime
*)shmat(id
, 0, 0);
80 if ((long)shm
== -1) {
81 LOG_FATAL("shmat() failed : %s", strerror(errno
));
85 RCL_SetDriverData(instance
, shm
);
89 static void shm_finalise(RCL_Instance instance
)
91 shmdt(RCL_GetDriverData(instance
));
94 static int shm_poll(RCL_Instance instance
)
96 struct timespec receive_ts
, clock_ts
;
97 struct shmTime t
, *shm
;
100 shm
= (struct shmTime
*)RCL_GetDriverData(instance
);
104 if ((t
.mode
== 1 && t
.count
!= shm
->count
) ||
105 !(t
.mode
== 0 || t
.mode
== 1) || !t
.valid
) {
106 DEBUG_LOG("SHM sample ignored mode=%d count=%d valid=%d",
107 t
.mode
, t
.count
, t
.valid
);
113 receive_ts
.tv_sec
= t
.receiveTimeStampSec
;
114 clock_ts
.tv_sec
= t
.clockTimeStampSec
;
116 if (t
.clockTimeStampNSec
/ 1000 == t
.clockTimeStampUSec
&&
117 t
.receiveTimeStampNSec
/ 1000 == t
.receiveTimeStampUSec
) {
118 receive_ts
.tv_nsec
= t
.receiveTimeStampNSec
;
119 clock_ts
.tv_nsec
= t
.clockTimeStampNSec
;
121 receive_ts
.tv_nsec
= 1000 * t
.receiveTimeStampUSec
;
122 clock_ts
.tv_nsec
= 1000 * t
.clockTimeStampUSec
;
125 UTI_NormaliseTimespec(&clock_ts
);
126 UTI_NormaliseTimespec(&receive_ts
);
127 offset
= UTI_DiffTimespecsToDouble(&clock_ts
, &receive_ts
);
129 return RCL_AddSample(instance
, &receive_ts
, offset
, t
.leap
);
132 RefclockDriver RCL_SHM_driver
= {