The read_phc function implemented in phc2sys.c is used to perform clock comparison between two arbitrary clocks using clock_gettime.
This support is used to allow phc2sys to work on any pair of clocks and is implemented in a very similar manner as the kernel PTP_SYS_OFFSET ioctls. Make this function easier to re-use by moving it out of phc2sys.c and into a more accessible location. clockadj.c seems like a reasonable location as this file has many functions which deal with clockid_t values, and this functionality is tangentially related to adjusting clocks. Moving this function will allow using it in the phc_ctl program in a future change. Signed-off-by: Jacob Keller <jacob.e.kel...@intel.com> --- clockadj.c | 31 +++++++++++++++++++++++++++++++ clockadj.h | 16 ++++++++++++++++ phc2sys.c | 44 ++++++++------------------------------------ 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/clockadj.c b/clockadj.c index b5c78cd112ff..c78017049a0e 100644 --- a/clockadj.c +++ b/clockadj.c @@ -139,6 +139,37 @@ int clockadj_max_freq(clockid_t clkid) return f; } +int clockadj_compare(clockid_t clkid, clockid_t sysclk, int readings, + int64_t *offset, uint64_t *ts, int64_t *delay) +{ + struct timespec tdst1, tdst2, tsrc; + int i; + int64_t interval, best_interval = INT64_MAX; + + /* Pick the quickest clkid reading. */ + for (i = 0; i < readings; i++) { + if (clock_gettime(sysclk, &tdst1) || + clock_gettime(clkid, &tsrc) || + clock_gettime(sysclk, &tdst2)) { + pr_err("failed to read clock: %m"); + return 0; + } + + interval = (tdst2.tv_sec - tdst1.tv_sec) * NS_PER_SEC + + tdst2.tv_nsec - tdst1.tv_nsec; + + if (best_interval > interval) { + best_interval = interval; + *offset = (tdst1.tv_sec - tsrc.tv_sec) * NS_PER_SEC + + tdst1.tv_nsec - tsrc.tv_nsec + interval / 2; + *ts = tdst2.tv_sec * NS_PER_SEC + tdst2.tv_nsec; + } + } + *delay = best_interval; + + return 1; +} + void sysclk_set_leap(int leap) { clockid_t clkid = CLOCK_REALTIME; diff --git a/clockadj.h b/clockadj.h index 43325c8d5d15..995b2af11894 100644 --- a/clockadj.h +++ b/clockadj.h @@ -63,6 +63,22 @@ void clockadj_step(clockid_t clkid, int64_t step); */ int clockadj_max_freq(clockid_t clkid); +/** + * Compare offset between two clocks + * @param clkid A clock ID obtained using phc_open() or CLOCK_REALTIME + * @param sysclk A clock ID obtained using phc_open() or CLOCK_REALTIME + * @readings Number of readings to try + * @offset On return, the nanoseconds offset between the clocks + * @ts On return, the time of sysclk in nanoseconds that was used + * @delay On return, the interval between two reads of sysclk + * + * Compare the offset between two clocks in a similar manner as the + * PTP_SYS_OFFSET ioctls. Returns the difference between sysclk and clkid by + * performing multiple reads of sysclk with a read of clkid between. + */ +int clockadj_compare(clockid_t clkid, clockid_t sysclk, int readings, + int64_t *offset, uint64_t *ts, int64_t *delay); + /** * Set the system clock to insert/delete leap second at midnight. * @param leap +1 to insert leap second, -1 to delete leap second, diff --git a/phc2sys.c b/phc2sys.c index 6815c3dee8a0..5a14b0da8786 100644 --- a/phc2sys.c +++ b/phc2sys.c @@ -470,37 +470,6 @@ static void reconfigure(struct phc2sys_private *priv) pr_info("selecting %s as the master clock", src->device); } -static int read_phc(clockid_t clkid, clockid_t sysclk, int readings, - int64_t *offset, uint64_t *ts, int64_t *delay) -{ - struct timespec tdst1, tdst2, tsrc; - int i; - int64_t interval, best_interval = INT64_MAX; - - /* Pick the quickest clkid reading. */ - for (i = 0; i < readings; i++) { - if (clock_gettime(sysclk, &tdst1) || - clock_gettime(clkid, &tsrc) || - clock_gettime(sysclk, &tdst2)) { - pr_err("failed to read clock: %m"); - return 0; - } - - interval = (tdst2.tv_sec - tdst1.tv_sec) * NS_PER_SEC + - tdst2.tv_nsec - tdst1.tv_nsec; - - if (best_interval > interval) { - best_interval = interval; - *offset = (tdst1.tv_sec - tsrc.tv_sec) * NS_PER_SEC + - tdst1.tv_nsec - tsrc.tv_nsec + interval / 2; - *ts = tdst2.tv_sec * NS_PER_SEC + tdst2.tv_nsec; - } - } - *delay = best_interval; - - return 1; -} - static int64_t get_sync_offset(struct phc2sys_private *priv, struct clock *dst) { int direction = priv->forced_sync_offset; @@ -662,8 +631,10 @@ static int do_pps_loop(struct phc2sys_private *priv, struct clock *clock, /* If a PHC is available, use it to get the whole number of seconds in the offset and PPS for the rest. */ if (src != CLOCK_INVALID) { - if (!read_phc(src, clock->clkid, priv->phc_readings, - &phc_offset, &phc_ts, &phc_delay)) + if (!clockadj_compare(src, clock->clkid, + priv->phc_readings, + &phc_offset, &phc_ts, + &phc_delay)) return -1; /* Convert the time stamp to the PHC time. */ @@ -764,9 +735,10 @@ static int do_loop(struct phc2sys_private *priv) ts += offset; } else { /* use phc */ - if (!read_phc(priv->master->clkid, clock->clkid, - priv->phc_readings, - &offset, &ts, &delay)) + if (!clockadj_compare(priv->master->clkid, + clock->clkid, + priv->phc_readings, + &offset, &ts, &delay)) continue; } update_clock(priv, clock, offset, ts, delay); -- 2.31.1.331.gb0c09ab8796f _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel