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


------------------------------------------------------------------------------
Is your legacy SCM system holding you back? Join Perforce May 7 to find out:
&#149; 3 signs your SCM is hindering your productivity
&#149; Requirements for releasing software faster
&#149; Expert tips and advice for migrating your SCM now
http://p.sf.net/sfu/perforce
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to