/* $Id$ */
/* 
 * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pj/os.h>
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/log.h>
#include <windows.h>

#define THIS_FILE   "os_timestamp_win32.c"


#if 1
#   define TRACE_(x)	    PJ_LOG(3,x)
#else
#   define TRACE_(x)	    ;
#endif


/////////////////////////////////////////////////////////////////////////////

#if defined(PJ_TIMESTAMP_USE_RDTSC) && PJ_TIMESTAMP_USE_RDTSC!=0 && \
    defined(PJ_M_I386) && PJ_M_I386 != 0 && \
    defined(PJ_HAS_PENTIUM) && PJ_HAS_PENTIUM!=0 && \
    defined(_MSC_VER)

/*
 * Use rdtsc to get the OS timestamp.
 */
static LONG CpuMhz;
static pj_int64_t CpuHz;
 
static pj_status_t GetCpuHz(void)
{
    HKEY key;
    LONG rc;
    DWORD size;

#if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
		      L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
		      0, 0, &key);
#else
    rc = RegOpenKey( HKEY_LOCAL_MACHINE,
		     "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
		     &key);
#endif

    if (rc != ERROR_SUCCESS)
	return PJ_RETURN_OS_ERROR(rc);

    size = sizeof(CpuMhz);
    rc = RegQueryValueEx(key, "~MHz", NULL, NULL, (BYTE*)&CpuMhz, &size);
    RegCloseKey(key);

    if (rc != ERROR_SUCCESS) {
	return PJ_RETURN_OS_ERROR(rc);
    }

    CpuHz = CpuMhz;
    CpuHz = CpuHz * 1000000;

    return PJ_SUCCESS;
}

/* __int64 is nicely returned in EDX:EAX */
__declspec(naked) __int64 rdtsc() 
{
    __asm 
    {
	RDTSC
	RET
    }
}

PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
{
    ts->u64 = rdtsc();
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
{
    pj_status_t status;

    if (CpuHz == 0) {
	status = GetCpuHz();
	if (status != PJ_SUCCESS)
	    return status;
    }

    freq->u64 = CpuHz;
    return PJ_SUCCESS;
}

/////////////////////////////////////////////////////////////////////////////

#elif defined(PJ_TIMESTAMP_WIN32_USE_SAFE_QPC) && \
         PJ_TIMESTAMP_WIN32_USE_SAFE_QPC!=0

/* Use safe QueryPerformanceCounter.
 * This implementation has some protection against bug in KB Q274323:
 *   Performance counter value may unexpectedly leap forward
 *   http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323
 *
 * THIS SHOULD NOT BE USED YET AS IT DOESN'T HANDLE SYSTEM TIME
 * CHANGE.
 */

static pj_timestamp g_ts_freq;
static pj_timestamp g_ts_base;
static pj_int64_t   g_time_base;

PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
{
    enum { MAX_RETRY = 10 };
    unsigned i;


    /* pj_get_timestamp_freq() must have been called before.
     * This is done when application called pj_init().
     */
    pj_assert(g_ts_freq.u64 != 0);

    /* Retry QueryPerformanceCounter() until we're sure that the
     * value returned makes sense.
     */
    i = 0;
    do {
	LARGE_INTEGER val;
	pj_int64_t counter64, time64, diff;
	pj_time_val time_now;

	/* Retrieve the counter */
	if (!QueryPerformanceCounter(&val))
	    return PJ_RETURN_OS_ERROR(GetLastError());

	/* Regardless of the goodness of the value, we should put
	 * the counter here, because normally application wouldn't
	 * check the error result of this function.
	 */
	ts->u64 = val.QuadPart;

	/* Retrieve time */
	pj_gettimeofday(&time_now);

	/* Get the counter elapsed time in miliseconds */
	counter64 = (val.QuadPart - g_ts_base.u64) * 1000 / g_ts_freq.u64;
	
	/* Get the time elapsed in miliseconds. 
	 * We don't want to use PJ_TIME_VAL_MSEC() since it's using
	 * 32bit calculation, which limits the maximum elapsed time
	 * to around 49 days only.
	 */
	time64 = time_now.sec;
	time64 = time64 * 1000 + time_now.msec;
	//time64 = GetTickCount();

	/* It's good if the difference between two clocks are within
	 * some compile time constant (default: 20ms, which to allow
	 * context switch happen between QueryPerformanceCounter and
	 * pj_gettimeofday()).
	 */
	diff = (time64 - g_time_base) - counter64;
	if (diff >= -20 && diff <= 20) {
	    /* It's good */
	    return PJ_SUCCESS;
	}

	++i;

    } while (i < MAX_RETRY);

    TRACE_((THIS_FILE, "QueryPerformanceCounter returned bad value"));
    return PJ_ETIMEDOUT;
}

static pj_status_t init_performance_counter(void)
{
    LARGE_INTEGER val;
    pj_time_val time_base;
    pj_status_t status;

    /* Get the frequency */
    if (!QueryPerformanceFrequency(&val))
	return PJ_RETURN_OS_ERROR(GetLastError());

    g_ts_freq.u64 = val.QuadPart;

    /* Get the base timestamp */
    if (!QueryPerformanceCounter(&val))
	return PJ_RETURN_OS_ERROR(GetLastError());

    g_ts_base.u64 = val.QuadPart;


    /* Get the base time */
    status = pj_gettimeofday(&time_base);
    if (status != PJ_SUCCESS)
	return status;

    /* Convert time base to 64bit value in msec */
    g_time_base = time_base.sec;
    g_time_base  = g_time_base * 1000 + time_base.msec;
    //g_time_base = GetTickCount();

    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
{
    if (g_ts_freq.u64 == 0) {
	enum { MAX_REPEAT = 10 };
	unsigned i;
	pj_status_t status;

	/* Make unellegant compiler happy */
	status = 0;

	/* Repeat initializing performance counter until we're sure
	 * the base timing is correct. It is possible that the system
	 * returns bad counter during this initialization!
	 */
	for (i=0; i<MAX_REPEAT; ++i) {

	    pj_timestamp dummy;

	    /* Init base time */
	    status = init_performance_counter();
	    if (status != PJ_SUCCESS)
		return status;

	    /* Try the base time */
	    status = pj_get_timestamp(&dummy);
	    if (status == PJ_SUCCESS)
		break;
	}

	if (status != PJ_SUCCESS)
	    return status;
    }

    freq->u64 = g_ts_freq.u64;
    return PJ_SUCCESS;
}

/////////////////////////////////////////////////////////////////////////////

#else

/*
 * Use QueryPerformanceCounter and QueryPerformanceFrequency.
 * This should be the default implementation to be used on Windows.
 */
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
{
    LARGE_INTEGER val;

    if (!QueryPerformanceCounter(&val))
	return PJ_RETURN_OS_ERROR(GetLastError());

    ts->u64 = val.QuadPart;
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
{
    LARGE_INTEGER val;

    if (!QueryPerformanceFrequency(&val))
	return PJ_RETURN_OS_ERROR(GetLastError());

    freq->u64 = val.QuadPart;
    return PJ_SUCCESS;
}


#endif	/* PJ_TIMESTAMP_USE_RDTSC */

