Split the generic (global) part of update_sync_offset and the part that
affects individual clocks. This is in preparation for phc2sys handling
synchronization of more clocks.

Signed-off-by: Jiri Benc <jb...@redhat.com>
---
 phc2sys.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/phc2sys.c b/phc2sys.c
index 0581eb5bcb24..19dce45964eb 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -60,7 +60,9 @@
 #define PMC_UPDATE_INTERVAL (60 * NS_PER_SEC)
 
 struct clock;
-static int update_sync_offset(struct clock *clock, int64_t offset, uint64_t 
ts);
+static int update_sync_offset(struct clock *clock);
+static int clock_handle_leap(struct clock *clock, clockid_t src,
+                            int64_t offset, uint64_t ts, int do_leap);
 
 static clockid_t clock_open(char *device)
 {
@@ -181,13 +183,14 @@ static void update_clock_stats(struct clock *clock,
        stats_reset(clock->delay_stats);
 }
 
-static void update_clock(struct clock *clock,
-                        int64_t offset, uint64_t ts, int64_t delay)
+static void update_clock(struct clock *clock, clockid_t src,
+                        int64_t offset, uint64_t ts, int64_t delay,
+                        int do_leap)
 {
        enum servo_state state;
        double ppb;
 
-       if (update_sync_offset(clock, offset, ts))
+       if (clock_handle_leap(clock, src, offset, ts, do_leap))
                return;
 
        if (clock->sync_offset_direction)
@@ -268,6 +271,7 @@ static int do_pps_loop(struct clock *clock, int fd,
 {
        int64_t pps_offset, phc_offset, phc_delay;
        uint64_t pps_ts, phc_ts;
+       int do_leap;
 
        clock->source_label = "pps";
 
@@ -304,7 +308,10 @@ static int do_pps_loop(struct clock *clock, int fd,
                        pps_offset = pps_ts - phc_ts;
                }
 
-               update_clock(clock, pps_offset, pps_ts, -1);
+               do_leap = update_sync_offset(clock);
+               if (do_leap <= 0)
+                       continue;
+               update_clock(clock, src, pps_offset, pps_ts, -1, do_leap);
        }
        close(fd);
        return 0;
@@ -316,6 +323,7 @@ static int do_sysoff_loop(struct clock *clock, clockid_t 
src,
        uint64_t ts;
        int64_t offset, delay;
        int err = 0, fd = CLOCKID_TO_FD(src);
+       int do_leap;
 
        clock->source_label = "sys";
 
@@ -325,7 +333,10 @@ static int do_sysoff_loop(struct clock *clock, clockid_t 
src,
                        err = -1;
                        break;
                }
-               update_clock(clock, offset, ts, delay);
+               do_leap = update_sync_offset(clock);
+               if (do_leap <= 0)
+                       continue;
+               update_clock(clock, src, offset, ts, delay, do_leap);
        }
        return err;
 }
@@ -335,6 +346,7 @@ static int do_phc_loop(struct clock *clock, clockid_t src,
 {
        uint64_t ts;
        int64_t offset, delay;
+       int do_leap;
 
        clock->source_label = "phc";
 
@@ -344,7 +356,10 @@ static int do_phc_loop(struct clock *clock, clockid_t src,
                              &offset, &ts, &delay)) {
                        continue;
                }
-               update_clock(clock, offset, ts, delay);
+               do_leap = update_sync_offset(clock);
+               if (do_leap <= 0)
+                       continue;
+               update_clock(clock, src, offset, ts, delay, do_leap);
        }
        return 0;
 }
@@ -495,10 +510,19 @@ static void close_pmc(struct clock *clock)
        clock->pmc = NULL;
 }
 
-static int update_sync_offset(struct clock *clock, int64_t offset, uint64_t ts)
+/* Returns: -1 in case of error, 0 for normal sync, 1 to leap clock */
+static int update_sync_offset(struct clock *clock)
 {
+       struct timespec tp;
+       uint64_t ts;
        int clock_leap;
 
+       if (clock_gettime(CLOCK_REALTIME, &tp)) {
+               pr_err("failed to read clock: %m");
+               return -1;
+       }
+       ts = tp.tv_sec * NS_PER_SEC + tp.tv_nsec;
+
        if (clock->pmc &&
            !(ts > clock->pmc_last_update &&
              ts - clock->pmc_last_update < PMC_UPDATE_INTERVAL)) {
@@ -511,9 +535,28 @@ static int update_sync_offset(struct clock *clock, int64_t 
offset, uint64_t ts)
        if (!clock->leap && !clock->leap_set)
                return 0;
 
+       clock_leap = leap_second_status(ts, clock->leap_set,
+                                       &clock->leap, &clock->sync_offset);
+       if (clock->leap_set != clock_leap) {
+               clock->leap_set = clock_leap;
+               return 1;
+       }
+       return 0;
+}
+
+/* Returns: non-zero to skip clock update */
+static int clock_handle_leap(struct clock *clock, clockid_t src,
+                            int64_t offset, uint64_t ts, int do_leap)
+{
+       if (!clock->leap && !do_leap)
+               return 0;
+
+       if (clock->clkid != CLOCK_REALTIME && src != CLOCK_REALTIME)
+               return 0;
+
        /* If the system clock is the master clock, get a time stamp from
           it, as it is the clock which will include the leap second. */
-       if (clock->clkid != CLOCK_REALTIME) {
+       if (src == CLOCK_REALTIME) {
                struct timespec tp;
                if (clock_gettime(CLOCK_REALTIME, &tp)) {
                        pr_err("failed to read clock: %m");
@@ -533,17 +576,13 @@ static int update_sync_offset(struct clock *clock, 
int64_t offset, uint64_t ts)
        /* Suspend clock updates in the last second before midnight. */
        if (is_utc_ambiguous(ts)) {
                pr_info("clock update suspended due to leap second");
-               return -1;
+               return 1;
        }
 
-       clock_leap = leap_second_status(ts, clock->leap_set,
-                                       &clock->leap, &clock->sync_offset);
-
-       if (clock->leap_set != clock_leap) {
+       if (do_leap) {
                /* Only the system clock can leap. */
                if (clock->clkid == CLOCK_REALTIME && clock->kernel_leap)
-                       sysclk_set_leap(clock_leap);
-               clock->leap_set = clock_leap;
+                       sysclk_set_leap(clock->leap_set);
        }
 
        return 0;
-- 
1.7.6.5


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to