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

Reply via email to