Print this page
OS-5192 need faster clock_gettime
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
Reviewed by: Ryan Zezeski <ryan@zinascii.com>
        
@@ -23,10 +23,11 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  *
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  * Copyright (c) 2014, 2016 by Delphix. All rights reserved.
+ * Copyright 2016 Joyent, Inc.
  */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -45,10 +46,11 @@
 #include <sys/dtrace.h>
 #include <sys/time.h>
 #include <sys/panic.h>
 #include <sys/cpu.h>
 #include <sys/sdt.h>
+#include <sys/comm_page.h>
 
 /*
  * Using the Pentium's TSC register for gethrtime()
  * ------------------------------------------------
  *
@@ -97,11 +99,10 @@
  * monotonically increases.
  */
 
 #define NSEC_SHIFT 5
 
-static uint_t nsec_scale;
 static uint_t nsec_unscale;
 
 /*
  * These two variables used to be grouped together inside of a structure that
  * lived on a single cache line. A regression (bug ID 4623398) caused the
@@ -138,30 +139,25 @@
         (hrt) += mul32(_l[0], scale) >> (32 - NSEC_SHIFT); \
 }
 
 int tsc_master_slave_sync_needed = 1;
 
-static int      tsc_max_delta;
-static hrtime_t tsc_sync_tick_delta[NCPU];
 typedef struct tsc_sync {
         volatile hrtime_t master_tsc, slave_tsc;
 } tsc_sync_t;
 static tsc_sync_t *tscp;
 static hrtime_t largest_tsc_delta = 0;
 static ulong_t shortest_write_time = ~0UL;
 
-static hrtime_t tsc_last = 0;
 static hrtime_t tsc_last_jumped = 0;
-static hrtime_t tsc_hrtime_base = 0;
 static int      tsc_jumped = 0;
 static uint32_t tsc_wayback = 0;
 /*
  * The cap of 1 second was chosen since it is the frequency at which the
  * tsc_tick() function runs which means that when gethrtime() is called it
  * should never be more than 1 second since tsc_last was updated.
  */
-static hrtime_t tsc_resume_cap;
 static hrtime_t tsc_resume_cap_ns = NANOSEC;     /* 1s */
 
 static hrtime_t shadow_tsc_hrtime_base;
 static hrtime_t shadow_tsc_last;
 static uint_t   shadow_nsec_scale;
@@ -544,10 +540,11 @@
          * deltas is > smallest of the write time.
          */
         if (largest_tsc_delta > shortest_write_time) {
                 gethrtimef = tsc_gethrtime_delta;
                 gethrtimeunscaledf = tsc_gethrtimeunscaled_delta;
+                tsc_ncpu = NCPU;
         }
         restore_int_flag(flags);
 }
 
 /*
@@ -686,10 +683,16 @@
         scalehrtimef = tsc_scalehrtime;
         unscalehrtimef = tsc_unscalehrtime;
         hrtime_tick = tsc_tick;
         gethrtime_hires = 1;
         /*
+         * Being part of the comm page, tsc_ncpu communicates the published
+         * length of the tsc_sync_tick_delta array.  This is kept zeroed to
+         * ignore the absent delta data while the TSCs are synced.
+         */
+        tsc_ncpu = 0;
+        /*
          * Allocate memory for the structure used in the tsc sync logic.
          * This structure should be aligned on a multiple of cache line size.
          */
         tscp = kmem_zalloc(PAGESIZE, KM_SLEEP);
 
@@ -724,10 +727,11 @@
                 tsc_sync_tick_delta[i] += tdelta;
         }
 
         gethrtimef = tsc_gethrtime_delta;
         gethrtimeunscaledf = tsc_gethrtimeunscaled_delta;
+        tsc_ncpu = NCPU;
 }
 
 /*
  * Functions to manage TSC and high-res time on suspend and resume.
  */