#include "libcflat.h"
#include "smp.h"
#include "atomic.h"
#include "processor.h"
#include "kvmclock.h"

#define DEFAULT_TEST_LOOPS 100000000L
#define DEFAULT_THRESHOLD  5L

long loops = DEFAULT_TEST_LOOPS;
long sec = 0;
long threshold = DEFAULT_THRESHOLD;

struct test_info {
        struct spinlock lock;
        u64 warps;                /* warp count */
        u64 stalls;               /* stall count */
        long long worst;          /* worst warp */
        volatile cycle_t last;    /* last cycle seen by test */
        int check;                /* check cycle ? */
};

struct test_info ti[4];

static void wallclock_test(void *data)
{
        int *p_err = data;
        long ksec, offset;
        struct timespec ts;

        kvm_get_wallclock(&ts);
        ksec = ts.tv_sec;

        offset = ksec - sec;
        printf("Raw nanoseconds value from kvmclock: %" PRIu64 " (cpu %d)\n", kvm_clock_read(), smp_id());
        printf("Seconds get from kvmclock: %ld (cpu %d, offset: %ld)\n", ksec, smp_id(), offset);

        if (offset > threshold || offset < -threshold) {
                printf("offset too large!\n");
                (*p_err)++;
        }
}

static void kvm_clock_test(void *data)
{
        struct test_info *hv_test_info = (struct test_info *)data;
        long i, check = hv_test_info->check;

        for (i = 0; i < loops; i++){
                cycle_t t0, t1;
                long long delta;

                if (check == 0) {
                        kvm_clock_read();
                        continue;
                }

                spin_lock(&hv_test_info->lock);
                t1 = kvm_clock_read();
                t0 = hv_test_info->last;
                hv_test_info->last = kvm_clock_read();
                spin_unlock(&hv_test_info->lock);

                delta = t1 - t0;
                if (delta < 0) {
                        spin_lock(&hv_test_info->lock);
                        ++hv_test_info->warps;
                        if (delta < hv_test_info->worst){
                                hv_test_info->worst = delta;
                                printf("Worst warp %lld\n", hv_test_info->worst);
                        }
                        spin_unlock(&hv_test_info->lock);
                }
                if (delta == 0)
                        ++hv_test_info->stalls;

                if (!((unsigned long)i & 31))
                        asm volatile("rep; nop");
        }
}

static int cycle_test(int check, struct test_info *ti)
{
        unsigned long long begin, end;

        begin = rdtsc();

        ti->check = check;
        on_cpus(kvm_clock_test, ti);

        end = rdtsc();

        printf("Total vcpus: %d\n", cpu_count());
        printf("Test  loops: %ld\n", loops);
        if (check == 1) {
                printf("Total warps:  %" PRId64 "\n", ti->warps);
                printf("Total stalls: %" PRId64 "\n", ti->stalls);
                printf("Worst warp:   %lld\n", ti->worst);
        } else
                printf("TSC cycles:  %lld\n", end - begin);

        return ti->warps ? 1 : 0;
}

int main(int ac, char **av)
{
        int nerr = 0;
        int ncpus;
        int i;

        if (ac > 1)
                loops = atol(av[1]);
        if (ac > 2)
                sec = atol(av[2]);
        if (ac > 3)
                threshold = atol(av[3]);

        ncpus = cpu_count();
        if (ncpus > MAX_CPU)
                report_abort("number cpus exceeds %d", MAX_CPU);

        on_cpus(kvm_clock_init, NULL);

        if (ac > 2) {
                printf("Wallclock test, threshold %ld\n", threshold);
                printf("Seconds get from host:     %ld\n", sec);
                for (i = 0; i < ncpus; ++i)
                        on_cpu(i, wallclock_test, &nerr);
        }

        printf("Check the stability of raw cycle ...\n");
        pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT
                          | PVCLOCK_RAW_CYCLE_BIT);
        if (cycle_test(1, &ti[0]))
                printf("Raw cycle is not stable\n");
        else
                printf("Raw cycle is stable\n");

        pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT);
        printf("Monotonic cycle test:\n");
        nerr += cycle_test(1, &ti[1]);

        printf("Measure the performance of raw cycle ...\n");
        pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT
                          | PVCLOCK_RAW_CYCLE_BIT);
        cycle_test(0, &ti[2]);

        printf("Measure the performance of adjusted cycle ...\n");
        pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT);
        cycle_test(0, &ti[3]);

        on_cpus(kvm_clock_clear, NULL);

        return nerr > 0 ? 1 : 0;
}
