/* Collection of code snippets by Arne Vajhøj */
/* (from articles on eksperten.dk / vajhoej.dk written sometime between 2004 and now) */
#ifndef HIGH_RES_TIMER_H
#define HIGH_RES_TIMER_H

#ifdef __cplusplus
extern "C" {
#endif

#if defined(__vms) && (defined(__alpha) || defined(__ia64))
#include <starlet.h>

static long long int vms_get_timecount(void)
{
    long int res;
    long long int t;
    res = sys$gettim(&t);
    return (res & 1 == 1) ? t : 0;
}

#define TIMECOUNT_T long long int
#define GET_TIMECOUNT vms_get_timecount()
#define UNITS_PER_SECOND 10000000
#endif

#ifdef __unix
#include <time.h>

static long long int unix_get_timecount(void)
{
    int res;
    struct timespec t;
    res = clock_gettime(CLOCK_MONOTONIC, &t);
    return (res == 0) ? (t.tv_sec * 1000000000LL + t.tv_nsec) : 0;
}

#define TIMECOUNT_T long long int
#define GET_TIMECOUNT unix_get_timecount()
#define UNITS_PER_SECOND 1000000000
#endif

#ifdef _WIN32
#include <windows.h>

static long long int win32_get_timecount(void)
{
    BOOL res;
    LARGE_INTEGER t;
    res = QueryPerformanceCounter(&t);
    return res ? t.QuadPart : 0;
}

static long long int win32_units_per_second(void)
{
    BOOL res;
    LARGE_INTEGER t;
    res = QueryPerformanceFrequency(&t);
    return res ? t.QuadPart : 0;
}

#define TIMECOUNT_T long long int
#define GET_TIMECOUNT win32_get_timecount()
#define UNITS_PER_SECOND win32_units_per_second()
#endif

#ifndef TIMECOUNT_T
#error "TIMECOUNT_T not defined"
#endif

#ifndef GET_TIMECOUNT
#error "GET_TIMECOUNT not defined"
#endif

#ifndef UNITS_PER_SECOND
#error "UNITS_PER_SECOND not defined"
#endif

#ifdef __cplusplus
}
#endif

#endif
