Improve stability of PHC reading in phc2sys.

Make five PHC readings in sequence and pick the quickest one.

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
master
Richard Cochran 2012-08-29 15:28:42 +02:00
parent 998093b6f7
commit f08d264e1d
1 changed files with 23 additions and 12 deletions

View File

@ -41,6 +41,8 @@
#define max_ppb 512000 #define max_ppb 512000
#define min_ppb -512000 #define min_ppb -512000
#define PHC_READINGS 5
static clockid_t clock_open(char *device) static clockid_t clock_open(char *device)
{ {
int fd = open(device, O_RDWR); int fd = open(device, O_RDWR);
@ -87,25 +89,34 @@ static void clock_step(clockid_t clkid, int64_t ns)
static int read_phc(clockid_t clkid, clockid_t sysclk, int rdelay, int64_t *offset, uint64_t *ts) static int read_phc(clockid_t clkid, clockid_t sysclk, int rdelay, int64_t *offset, uint64_t *ts)
{ {
struct timespec tsrc, tdst; struct timespec tdst1, tdst2, tsrc;
int i;
int64_t interval, best_interval = INT64_MAX;
if (clkid == CLOCK_INVALID) { if (clkid == CLOCK_INVALID) {
return 0; return 0;
} }
if (clock_gettime(clkid, &tsrc)) { /* Pick the quickest clkid reading. */
for (i = 0; i < PHC_READINGS; i++) {
if (clock_gettime(sysclk, &tdst1) ||
clock_gettime(clkid, &tsrc) ||
clock_gettime(sysclk, &tdst2)) {
perror("clock_gettime"); perror("clock_gettime");
return 0; return 0;
} }
if (clock_gettime(sysclk, &tdst)) { interval = (tdst2.tv_sec - tdst1.tv_sec) * NS_PER_SEC +
perror("clock_gettime"); tdst2.tv_nsec - tdst1.tv_nsec;
return 0;
}
*offset = tdst.tv_sec * NS_PER_SEC - tsrc.tv_sec * NS_PER_SEC + if (best_interval > interval) {
tdst.tv_nsec - tsrc.tv_nsec - rdelay; best_interval = interval;
*ts = tdst.tv_sec * NS_PER_SEC + tdst.tv_nsec; *offset = (tdst1.tv_sec - tsrc.tv_sec) * NS_PER_SEC +
tdst1.tv_nsec - tsrc.tv_nsec +
interval / 2 - rdelay;
*ts = tdst2.tv_sec * NS_PER_SEC + tdst2.tv_nsec;
}
}
return 1; return 1;
} }