/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
  Copyright (c) 2005 Eliot Dresselhaus

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <vppinfra/os.h>
#include <vppinfra/time.h>
#include <vppinfra/format.h>
#include <vppinfra/cpu.h>
#include <math.h>

#ifdef CLIB_UNIX

#include <math.h>
#include <sys/time.h>
#include <fcntl.h>

/* Not very accurate way of determining cpu clock frequency
   for unix.  Better to use /proc/cpuinfo on linux. */
static f64
estimate_clock_frequency (f64 sample_time)
{
  f64 time_now, time_start, time_limit, freq;
  u64 t[2];

  time_start = time_now = unix_time_now ();
  time_limit = time_now + sample_time;
  t[0] = clib_cpu_time_now ();
  while (time_now < time_limit)
    time_now = unix_time_now ();
  t[1] = clib_cpu_time_now ();

  freq = (t[1] - t[0]) / (time_now - time_start);

  return freq;
}

/* Fetch cpu frequency via parseing /proc/cpuinfo.
   Only works for Linux. */
static f64
clock_frequency_from_proc_filesystem (void)
{
  f64 cpu_freq = 1e9;		/* better than 40... */
  f64 ppc_timebase = 0;		/* warnings be gone */
  int fd;
  unformat_input_t input;

/* $$$$ aarch64 kernel doesn't report "cpu MHz" */
#if defined(__aarch64__)
  return 0.0;
#endif

  cpu_freq = 0;
  fd = open ("/proc/cpuinfo", 0);
  if (fd < 0)
    return cpu_freq;

  unformat_init_clib_file (&input, fd);

  ppc_timebase = 0;
  while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (&input, "cpu MHz : %f", &cpu_freq))
	cpu_freq *= 1e6;
      else if (unformat (&input, "timebase : %f", &ppc_timebase))
	;
      else
	unformat_skip_line (&input);
    }

  unformat_free (&input);

  close (fd);

  /* Override CPU frequency with time base for PPC. */
  if (ppc_timebase != 0)
    cpu_freq = ppc_timebase;

  return cpu_freq;
}

/* Fetch cpu frequency via reading /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
   Only works for Linux. */
static f64
clock_frequency_from_sys_filesystem (void)
{
  f64 cpu_freq = 0.0;
  int fd;
  unformat_input_t input;

  /* Time stamp always runs at max frequency. */
  cpu_freq = 0;
  fd = open ("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", 0);
  if (fd < 0)
    goto done;

  unformat_init_clib_file (&input, fd);
  (void) unformat (&input, "%f", &cpu_freq);
  cpu_freq *= 1e3;		/* measured in kHz */
  unformat_free (&input);
  close (fd);
done:
  return cpu_freq;
}

f64
os_cpu_clock_frequency (void)
{
#if defined (__aarch64__)
  /* The system counter increments at a fixed frequency. It is distributed
   * to each core which has registers for reading the current counter value
   * as well as the clock frequency. The system counter is not clocked at
   * the same frequency as the core. */
  u64 hz;
  asm volatile ("mrs %0, cntfrq_el0":"=r" (hz));
  return (f64) hz;
#endif
  f64 cpu_freq;

#ifdef __x86_64__
  u32 __clib_unused eax = 0, ebx = 0, ecx = 0, edx = 0;
  clib_get_cpuid (0x00, &eax, &ebx, &ecx, &edx);
  if (eax >= 0x15)
    {
      u32 max_leaf = eax;
      /*
         CPUID Leaf 0x15 - Time Stamp Counter and Nominal Core Crystal Clock Info
         eax - denominator of the TSC/”core crystal clock” ratio
         ebx - numerator of the TSC/”core crystal clock” ratio
         ecx - nominal frequency of the core crystal clock in Hz
         edx - reseved
       */

      clib_get_cpuid (0x15, &eax, &ebx, &ecx, &edx);
      if (ebx && ecx)
	return ecx * ebx / eax;

      if (max_leaf >= 0x16)
	{
	  /*
	     CPUID Leaf 0x16 - Processor Frequency Information Leaf
	     eax - Bits 15 - 00: Processor Base Frequency (in MHz).
	   */

	  clib_get_cpuid (0x16, &eax, &ebx, &ecx, &edx);
	  if (eax)
	    return 1e6 * (eax & 0xffff);
	}
    }
#endif

  /* If we have an invariant TSC, use it to estimate the clock frequency */
  if (clib_cpu_supports_invariant_tsc ())
    return estimate_clock_frequency (1e-3);

  /* Next, try /sys version. */
  cpu_freq = clock_frequency_from_sys_filesystem ();
  if (cpu_freq != 0)
    return cpu_freq;

  /* Next try /proc version. */
  cpu_freq = clock_frequency_from_proc_filesystem ();
  if (cpu_freq != 0)
    return cpu_freq;

  /* If /proc/cpuinfo fails (e.g. not running on Linux) fall back to
     gettimeofday based estimated clock frequency. */
  return estimate_clock_frequency (1e-3);
}

#endif /* CLIB_UNIX */

/* Initialize time. */
void
clib_time_init (clib_time_t * c)
{
  clib_memset (c, 0, sizeof (c[0]));
  c->clocks_per_second = os_cpu_clock_frequency ();
  /*
   * Sporadic reports of os_cpu_clock_frequency() returning 0.0
   * in highly parallel container environments.
   * To avoid immediate division by zero:
   *   Step 1: try estimate_clock_frequency().
   *   Step 2: give up. Pretend we have a 2gHz clock.
   */
  if (PREDICT_FALSE (c->clocks_per_second == 0.0))
    {
      c->clocks_per_second = estimate_clock_frequency (1e-3);
      if (c->clocks_per_second == 0.0)
	{
	  clib_warning ("os_cpu_clock_frequency() returned 0.0, use 2e9...");
	  c->clocks_per_second = 2e9;
	}
    }
  c->seconds_per_clock = 1 / c->clocks_per_second;
  c->log2_clocks_per_second = min_log2_u64 ((u64) c->clocks_per_second);

  /* Verify frequency every 16 sec */
  c->log2_clocks_per_frequency_verify = c->log2_clocks_per_second + 4;

  c->last_verify_reference_time = unix_time_now ();
  c->init_reference_time = c->last_verify_reference_time;
  c->last_cpu_time = clib_cpu_time_now ();
  c->init_cpu_time = c->last_verify_cpu_time = c->last_cpu_time;
  c->total_cpu_time = 0ULL;

  /*
   * Use exponential smoothing, with a half-life of 1 minute
   * reported_rate(t) = reported_rate(t-1) * K + rate(t)*(1-K)
   * where K = e**(-1.0/3.75);
   * 15 samples in 4 minutes
   * 7.5 samples in 2 minutes,
   * 3.75 samples in 1 minute, etc.
   */
  c->damping_constant = exp (-1.0 / 3.75);
}

void
clib_time_verify_frequency (clib_time_t * c)
{
  f64 now_reference, delta_reference, delta_reference_max;
  u64 delta_clock;
  f64 new_clocks_per_second, delta;

  /* Ask the kernel and the CPU what time it is... */
  now_reference = unix_time_now ();
  c->last_cpu_time = clib_cpu_time_now ();

  /* Calculate a new clock rate sample */
  delta_reference = now_reference - c->last_verify_reference_time;
  delta_clock = c->last_cpu_time - c->last_verify_cpu_time;

  c->last_verify_cpu_time = c->last_cpu_time;
  c->last_verify_reference_time = now_reference;

  /*
   * Is the reported reference interval non-positive,
   * or off by a factor of two - or 8 seconds - whichever is larger?
   * Someone reset the clock behind our back.
   */
  delta_reference_max = (f64) (2ULL << c->log2_clocks_per_frequency_verify) /
    (f64) (1ULL << c->log2_clocks_per_second);
  delta_reference_max = delta_reference_max > 8.0 ? delta_reference_max : 8.0;

  /* Ignore this sample */
  if (delta_reference <= 0.0 || delta_reference > delta_reference_max)
    return;

  /*
   * Reject large frequency changes, another consequence of
   * system clock changes particularly with old kernels.
   */
  new_clocks_per_second = ((f64) delta_clock) / delta_reference;

  /* Compute abs(rate change) */
  delta = new_clocks_per_second - c->clocks_per_second;
  if (delta < 0.0)
    delta = -delta;

  /* If rate change > 1%, reject this sample */
  if (PREDICT_FALSE ((delta / c->clocks_per_second) > .01))
    {
      clib_warning ("Rejecting large frequency change of %.2f%%",
		    (delta / c->clocks_per_second) * 100.0);
      return;
    }

  /* Add sample to the exponentially-smoothed rate */
  c->clocks_per_second = c->clocks_per_second * c->damping_constant +
    (1.0 - c->damping_constant) * new_clocks_per_second;
  c->seconds_per_clock = 1.0 / c->clocks_per_second;

  /*
   * Recalculate total_cpu_time based on the kernel timebase, and
   * the calculated clock rate
   */
  c->total_cpu_time =
    (now_reference - c->init_reference_time) * c->clocks_per_second;
}


u8 *
format_clib_time (u8 * s, va_list * args)
{
  clib_time_t *c = va_arg (*args, clib_time_t *);
  int verbose = va_arg (*args, int);
  f64 now, reftime, delta_reftime_in_seconds, error;

  /* Compute vpp elapsed time from the CPU clock */
  reftime = unix_time_now ();
  now = clib_time_now (c);

  s = format (s, "Time now %.6f", now);
  if (verbose == 0)
    return s;

  /* And also from the kernel */
  delta_reftime_in_seconds = reftime - c->init_reference_time;

  error = now - delta_reftime_in_seconds;

  s = format (s, ", reftime %.6f, error %.6f, clocks/sec %.6f",
	      delta_reftime_in_seconds, error, c->clocks_per_second);
  return (s);
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
