// //////////////////////////////////////////////////////////
// wallclock.c
// Copyright (c) 2014 Stephan Brumme. All rights reserved.
// see http://create.stephan-brumme.com/disclaimer.html
//

// only for printf in the test code in main()
#include <stdio.h>


// include OS specific timing library
#ifdef _MSC_VER
// Windows
#include <Windows.h>
#else
// Linux
#include <sys/time.h>
#endif


/// return a timestamp with sub-second precision
/** QueryPerformanceCounter has an undefined starting point (null/zero)
    and can wrap around, i.e. be nulled again.
    gettimeofday (Linux only) returns the number of seconds since January 1, 1970 **/
double seconds()
{
#ifdef _MSC_VER
  static LARGE_INTEGER frequency;
  if (frequency.QuadPart == 0)
    ::QueryPerformanceFrequency(&frequency);

  LARGE_INTEGER now;
  ::QueryPerformanceCounter(&now);
  return now.QuadPart / double(frequency.QuadPart);
#else
  // lower resolution but never wraps around:
  struct timeval now;
  gettimeofday(&now, NULL);
  return now.tv_sec + now.tv_usec / 1000000.0;
#endif
}


// test code
int main(int argc, char** argv)
{
  // find minimum gap between two consecutive timestamps => timing resolution
  const int NumTests = 10;
  int i;
  for (i = 0; i < NumTests; i++)
  {
    double time1 = seconds();
    double time2 = time1;

    // wait until timestamp changes
    while (time2 == time1)
      time2 = seconds();

    // compute difference ...
    double microseconds = (time2 - time1) * 1000*1000;
    double megahertz    = 1 / microseconds;
    // ... and display it
    printf("%f microseconds => %f megahertz\n", microseconds, megahertz);
  }

  return 0;
}
