Hello all,

There is an abnormality in the openvpn sources I want to resolve.

In windows there is own implementation of gettimeofday().
In the past there was no gettimeofday(), so we used performance counters,
then James optimize it to reduce CPU consumption.

Unlike in the past, mingw does provide this function these days.
The question is if it is good enough.

There is also a note:
/* on WIN32, gettimeofday is faster than time(NULL) */

I am not sure about any of these, can you please try to run the
benchmark and report back the results?
It must be compiled using mingw, either at cygwin or at linux.

Thanks,
Alon
#include <sys/time.h>
#include <stdio.h>
#include <windows.h>

static time_t gtc_base = 0;
static DWORD gtc_last = 0;
static time_t last_sec = 0;
static unsigned int last_msec = 0;
static int bt_last = 0;

static void
gettimeofday_calibrate (void)
{
  const time_t t = time(NULL);
  const DWORD gtc = GetTickCount();
  gtc_base = t - gtc/1000;
  gtc_last = gtc;
}

/*
 * Rewritten by JY for OpenVPN 2.1, after I realized that
 * QueryPerformanceCounter takes nearly 2 orders of magnitude
 * more processor cycles than GetTickCount.
 */
int
openvpn_gettimeofday (struct timeval *tv, void *tz)
{
  const DWORD gtc = GetTickCount();
  int bt = 0;
  time_t sec;
  unsigned int msec;
  const int backtrack_hold_seconds = 10;

  /* recalibrate at the dreaded 49.7 day mark */
  if (!gtc_base || gtc < gtc_last)
    gettimeofday_calibrate ();
  gtc_last = gtc;

  sec = gtc_base + gtc / 1000;
  msec = gtc % 1000;

  if (sec == last_sec)
    {
      if (msec < last_msec)
	{
	  msec = last_msec;
	  bt = 1;
	}
    }
  else if (sec < last_sec)
    {
      /* We try to dampen out backtracks of less than backtrack_hold_seconds.
	 Larger backtracks will be passed through and dealt with by the
	 TIME_BACKTRACK_PROTECTION code (if enabled) */
      if (sec > last_sec - backtrack_hold_seconds)
	{
	  sec = last_sec;
	  msec = last_msec;
	}
      bt = 1;
    }

  tv->tv_sec = last_sec = sec;
  tv->tv_usec = (last_msec = msec) * 1000;

  if (bt && !bt_last)
    gettimeofday_calibrate ();
  bt_last = bt;

  return 0;
}

int main(void) {
	struct timeval tv;
	long i;
	long n=1000000000;
	time_t mark;
	mark = time(NULL);
	for(i=0;i<n;i++) {
		time(NULL);
	}
	printf("time(): %d\n", time(NULL)-mark);
	mark = time(NULL);
	for(i=0;i<n;i++) {
		gettimeofday(&tv, NULL);
	}
	printf("gettimeofday(): %d\n", time(NULL)-mark);
	mark = time(NULL);
	for(i=0;i<n;i++) {
		openvpn_gettimeofday(&tv, NULL);
	}
	printf("openvpn_gettimeofday(): %d\n", time(NULL)-mark);
	return 0;
}

Reply via email to