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,32 ****
--- 23,33 ----
   * 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,54 ****
--- 46,56 ----
  #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,107 ****
   * 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
--- 99,108 ----
*** 138,167 ****
          (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;
--- 139,163 ----
*** 544,553 ****
--- 540,550 ----
           * 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,695 ****
--- 683,698 ----
          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,733 ****
--- 727,737 ----
                  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.
   */