// TimerIssue.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include <stdio.h>

/*
    my code
*/
static LONGLONG MyTickHz; /* Clock frequency (cycles/second) - set by Init */

LONGLONG my_now(void);


/*
    LIBCURL code
*/
struct timeval curlx_tvnow(void);



int main(int argc, char* argv[])
{
    int            counter = 0; /* num of iterations */
    struct timeval curl_last_time;
    struct timeval curl_curr_time;
    int            curl_delta;
    
    LONGLONG       my_last_time;
    LONGLONG       my_curr_time;
    int            my_delta;
    
    LARGE_INTEGER  Frequency;


    if (QueryPerformanceFrequency(&Frequency) == 0)
    {
        printf("QueryPerformanceFrequency failed. Exit\n");
        goto lexit;
    }
    MyTickHz = Frequency.QuadPart;


    curl_last_time = curlx_tvnow();
    my_last_time   = my_now();


    while (counter < 500)
    {
        counter++;
        Sleep(2);  /* Sleep 2 milliseconds */

        curl_curr_time = curlx_tvnow();
        my_curr_time   = my_now();
        
        curl_delta = (curl_curr_time.tv_sec==curl_last_time.tv_sec) ?
                     (curl_curr_time.tv_usec - curl_last_time.tv_usec) :
                     (curl_curr_time.tv_usec + (1000000-curl_last_time.tv_usec));
        curl_delta /= 1000;  /* usec -> msec*/
                     
        my_delta   = (int)((LONGLONG)(my_curr_time - my_last_time) /
                           (LONGLONG)1000000);  /* nsec -> msec */

        if (curl_delta != my_delta)
        {
            printf("%d: curl: curr=%d.%d, last=%d.%d, delta=%d\n", counter,
                        curl_curr_time.tv_sec, curl_curr_time.tv_usec,
                        curl_last_time.tv_sec, curl_last_time.tv_usec,
                        curl_delta);
/*
            printf("%d: curl_delta=%d, my_delta=%d\n", counter, curl_delta, my_delta);
*/
        }

        curl_last_time = curl_curr_time;
        my_last_time   = my_curr_time;
    }

lexit:
    {
        char ch;
        printf("Enter any key to exit...\n");
        scanf("%c",&ch);
    }
    return 0;
}



struct timeval curlx_tvnow(void)
{
    /*
    ** GetTickCount() is available on _all_ Windows versions from W95 up
    ** to nowadays. Returns milliseconds elapsed since last system boot,
    ** increases monotonically and wraps once 49.7 days have elapsed.
    */
    struct timeval now;
    DWORD milliseconds = GetTickCount();
    now.tv_sec = milliseconds / 1000;
    now.tv_usec = (milliseconds % 1000) * 1000;
    return now;
}


LONGLONG my_now(void)
{
    LONGLONG        result;
    LARGE_INTEGER   PerformanceCount;
    static LONGLONG nsec_per_sec = (LONGLONG)1000000000;

    QueryPerformanceCounter(&PerformanceCount);

    /* convert to nanoseconds and maintain resolution */
    result = (PerformanceCount.QuadPart / MyTickHz) * nsec_per_sec;
    result += (((PerformanceCount.QuadPart % MyTickHz) * nsec_per_sec) / MyTickHz);

    return result;
}

