/*
 * rcutorture.c: simple user-level performance/stress test of RCU.
 *
 * Usage:
 *     ./rcu <nreaders> rperf [ <seconds> ]
 *         Run a read-side performance test with the specified
 *         number of readers for <seconds> seconds.
 *     ./rcu <nupdaters> uperf [ <seconds> ]
 *         Run an update-side performance test with the specified
 *         number of updaters and specified duration.
 *     ./rcu <nreaders> perf [ <seconds> ]
 *         Run a combined read/update performance test with the specified
 *         number of readers and one updater and specified duration.
 *
 * The above tests produce output as follows:
 *
 * n_reads: 46008000  n_updates: 146026  nreaders: 2  nupdaters: 1 duration: 1
 * ns/read: 43.4707  ns/update: 6848.1
 *
 * The first line lists the total number of RCU reads and updates executed
 * during the test, the number of reader threads, the number of updater
 * threads, and the duration of the test in seconds.  The second line
 * lists the average duration of each type of operation in nanoseconds,
 * or "nan" if the corresponding type of operation was not performed.
 *
 *     ./rcu <nreaders> stress [ <seconds> ]
 *         Run a stress test with the specified number of readers and
 *         one updater.
 *
 * This test produces output as follows:
 *
 * n_reads: 114633217  n_updates: 3903415  n_mberror: 0
 * rcu_stress_count: 114618391 14826 0 0 0 0 0 0 0 0 0
 *
 * The first line lists the number of RCU read and update operations
 * executed, followed by the number of memory-ordering violations
 * (which will be zero in a correct RCU implementation).  The second
 * line lists the number of readers observing progressively more stale
 * data.  A correct RCU implementation will have all but the first two
 * numbers non-zero.
 *
 * 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.
 *
 * Copyright (c) 2008 Paul E. McKenney, IBM Corporation.
 */

/*
 * Test variables.
 */

#include "qemu/osdep.h"
#include "qemu/atomic.h"
#include "qemu/rcu.h"
#include "qemu/thread.h"

long long n_reads = 0LL;
long n_updates = 0L;
int nthreadsrunning;

#define GOFLAG_INIT 0
#define GOFLAG_RUN  1
#define GOFLAG_STOP 2

static volatile int goflag = GOFLAG_INIT;

#define RCU_READ_RUN 1000

#define NR_THREADS 100
static QemuMutex counts_mutex;
static QemuThread threads[NR_THREADS];
static struct rcu_reader_data *data[NR_THREADS];
static int n_threads;

static void create_thread(void *(*func)(void *))
{
    if (n_threads >= NR_THREADS) {
        fprintf(stderr, "Thread limit of %d exceeded!\n", NR_THREADS);
        exit(-1);
    }
    qemu_thread_create(&threads[n_threads], "test", func, &data[n_threads],
                       QEMU_THREAD_JOINABLE);
    n_threads++;
}

static void wait_all_threads(void)
{
    int i;

    for (i = 0; i < n_threads; i++) {
        qemu_thread_join(&threads[i]);
    }
    n_threads = 0;
}

/*
 * Performance test.
 */

static void *rcu_read_perf_test(void *arg)
{
    int i;
    long long n_reads_local = 0;

    rcu_register_thread();

    *(struct rcu_reader_data **)arg = &rcu_reader;
    atomic_inc(&nthreadsrunning);
    while (goflag == GOFLAG_INIT) {
        g_usleep(1000);
    }
    while (goflag == GOFLAG_RUN) {
        for (i = 0; i < RCU_READ_RUN; i++) {
            rcu_read_lock();
            rcu_read_unlock();
        }
        n_reads_local += RCU_READ_RUN;
    }
    qemu_mutex_lock(&counts_mutex);
    n_reads += n_reads_local;
    qemu_mutex_unlock(&counts_mutex);

    rcu_unregister_thread();
    return NULL;
}

static void *rcu_update_perf_test(void *arg)
{
    long long n_updates_local = 0;

    rcu_register_thread();

    *(struct rcu_reader_data **)arg = &rcu_reader;
    atomic_inc(&nthreadsrunning);
    while (goflag == GOFLAG_INIT) {
        g_usleep(1000);
    }
    while (goflag == GOFLAG_RUN) {
        synchronize_rcu();
        n_updates_local++;
    }
    qemu_mutex_lock(&counts_mutex);
    n_updates += n_updates_local;
    qemu_mutex_unlock(&counts_mutex);

    rcu_unregister_thread();
    return NULL;
}

static void perftestinit(void)
{
    nthreadsrunning = 0;
}

static void perftestrun(int nthreads, int duration, int nreaders, int nupdaters)
{
    while (atomic_read(&nthreadsrunning) < nthreads) {
        g_usleep(1000);
    }
    goflag = GOFLAG_RUN;
    g_usleep(duration * G_USEC_PER_SEC);
    goflag = GOFLAG_STOP;
    wait_all_threads();
    printf("n_reads: %lld  n_updates: %ld  nreaders: %d  nupdaters: %d duration: %d\n",
           n_reads, n_updates, nreaders, nupdaters, duration);
    printf("ns/read: %g  ns/update: %g\n",
           ((duration * 1000*1000*1000.*(double)nreaders) /
        (double)n_reads),
           ((duration * 1000*1000*1000.*(double)nupdaters) /
        (double)n_updates));
    exit(0);
}

static void perftest(int nreaders, int duration)
{
    int i;

    perftestinit();
    for (i = 0; i < nreaders; i++) {
        create_thread(rcu_read_perf_test);
    }
    create_thread(rcu_update_perf_test);
    perftestrun(i + 1, duration, nreaders, 1);
}

static void rperftest(int nreaders, int duration)
{
    int i;

    perftestinit();
    for (i = 0; i < nreaders; i++) {
        create_thread(rcu_read_perf_test);
    }
    perftestrun(i, duration, nreaders, 0);
}

static void uperftest(int nupdaters, int duration)
{
    int i;

    perftestinit();
    for (i = 0; i < nupdaters; i++) {
        create_thread(rcu_update_perf_test);
    }
    perftestrun(i, duration, 0, nupdaters);
}

/*
 * Stress test.
 */

#define RCU_STRESS_PIPE_LEN 10

struct rcu_stress {
    int pipe_count;
    int mbtest;
};

struct rcu_stress rcu_stress_array[RCU_STRESS_PIPE_LEN] = { { 0 } };
struct rcu_stress *rcu_stress_current;
int rcu_stress_idx;

int n_mberror;
long long rcu_stress_count[RCU_STRESS_PIPE_LEN + 1];


static void *rcu_read_stress_test(void *arg)
{
    int i;
    struct rcu_stress *p;
    int pc;
    long long n_reads_local = 0;
    long long rcu_stress_local[RCU_STRESS_PIPE_LEN + 1] = { 0 };
    volatile int garbage = 0;

    rcu_register_thread();

    *(struct rcu_reader_data **)arg = &rcu_reader;
    while (goflag == GOFLAG_INIT) {
        g_usleep(1000);
    }
    while (goflag == GOFLAG_RUN) {
        rcu_read_lock();
        p = atomic_rcu_read(&rcu_stress_current);
        if (p->mbtest == 0) {
            n_mberror++;
        }
        rcu_read_lock();
        for (i = 0; i < 100; i++) {
            garbage++;
        }
        rcu_read_unlock();
        pc = p->pipe_count;
        rcu_read_unlock();
        if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) {
            pc = RCU_STRESS_PIPE_LEN;
        }
        rcu_stress_local[pc]++;
        n_reads_local++;
    }
    qemu_mutex_lock(&counts_mutex);
    n_reads += n_reads_local;
    for (i = 0; i <= RCU_STRESS_PIPE_LEN; i++) {
        rcu_stress_count[i] += rcu_stress_local[i];
    }
    qemu_mutex_unlock(&counts_mutex);

    rcu_unregister_thread();
    return NULL;
}

static void *rcu_update_stress_test(void *arg)
{
    int i;
    struct rcu_stress *p;

    rcu_register_thread();

    *(struct rcu_reader_data **)arg = &rcu_reader;
    while (goflag == GOFLAG_INIT) {
        g_usleep(1000);
    }
    while (goflag == GOFLAG_RUN) {
        i = rcu_stress_idx + 1;
        if (i >= RCU_STRESS_PIPE_LEN) {
            i = 0;
        }
        p = &rcu_stress_array[i];
        p->mbtest = 0;
        smp_mb();
        p->pipe_count = 0;
        p->mbtest = 1;
        atomic_rcu_set(&rcu_stress_current, p);
        rcu_stress_idx = i;
        for (i = 0; i < RCU_STRESS_PIPE_LEN; i++) {
            if (i != rcu_stress_idx) {
                rcu_stress_array[i].pipe_count++;
            }
        }
        synchronize_rcu();
        n_updates++;
    }

    rcu_unregister_thread();
    return NULL;
}

static void *rcu_fake_update_stress_test(void *arg)
{
    rcu_register_thread();

    *(struct rcu_reader_data **)arg = &rcu_reader;
    while (goflag == GOFLAG_INIT) {
        g_usleep(1000);
    }
    while (goflag == GOFLAG_RUN) {
        synchronize_rcu();
        g_usleep(1000);
    }

    rcu_unregister_thread();
    return NULL;
}

static void stresstest(int nreaders, int duration)
{
    int i;

    rcu_stress_current = &rcu_stress_array[0];
    rcu_stress_current->pipe_count = 0;
    rcu_stress_current->mbtest = 1;
    for (i = 0; i < nreaders; i++) {
        create_thread(rcu_read_stress_test);
    }
    create_thread(rcu_update_stress_test);
    for (i = 0; i < 5; i++) {
        create_thread(rcu_fake_update_stress_test);
    }
    goflag = GOFLAG_RUN;
    g_usleep(duration * G_USEC_PER_SEC);
    goflag = GOFLAG_STOP;
    wait_all_threads();
    printf("n_reads: %lld  n_updates: %ld  n_mberror: %d\n",
           n_reads, n_updates, n_mberror);
    printf("rcu_stress_count:");
    for (i = 0; i <= RCU_STRESS_PIPE_LEN; i++) {
        printf(" %lld", rcu_stress_count[i]);
    }
    printf("\n");
    exit(0);
}

/* GTest interface */

static void gtest_stress(int nreaders, int duration)
{
    int i;

    rcu_stress_current = &rcu_stress_array[0];
    rcu_stress_current->pipe_count = 0;
    rcu_stress_current->mbtest = 1;
    for (i = 0; i < nreaders; i++) {
        create_thread(rcu_read_stress_test);
    }
    create_thread(rcu_update_stress_test);
    for (i = 0; i < 5; i++) {
        create_thread(rcu_fake_update_stress_test);
    }
    goflag = GOFLAG_RUN;
    g_usleep(duration * G_USEC_PER_SEC);
    goflag = GOFLAG_STOP;
    wait_all_threads();
    g_assert_cmpint(n_mberror, ==, 0);
    for (i = 2; i <= RCU_STRESS_PIPE_LEN; i++) {
        g_assert_cmpint(rcu_stress_count[i], ==, 0);
    }
}

static void gtest_stress_1_1(void)
{
    gtest_stress(1, 1);
}

static void gtest_stress_10_1(void)
{
    gtest_stress(10, 1);
}

static void gtest_stress_1_5(void)
{
    gtest_stress(1, 5);
}

static void gtest_stress_10_5(void)
{
    gtest_stress(10, 5);
}

/*
 * Mainprogram.
 */

static void usage(int argc, char *argv[])
{
    fprintf(stderr, "Usage: %s [nreaders [ perf | stress ] ]\n", argv[0]);
    exit(-1);
}

int main(int argc, char *argv[])
{
    int nreaders = 1;
    int duration = 1;

    qemu_mutex_init(&counts_mutex);
    if (argc >= 2 && argv[1][0] == '-') {
        g_test_init(&argc, &argv, NULL);
        if (g_test_quick()) {
            g_test_add_func("/rcu/torture/1reader", gtest_stress_1_1);
            g_test_add_func("/rcu/torture/10readers", gtest_stress_10_1);
        } else {
            g_test_add_func("/rcu/torture/1reader", gtest_stress_1_5);
            g_test_add_func("/rcu/torture/10readers", gtest_stress_10_5);
        }
        return g_test_run();
    }

    if (argc >= 2) {
        nreaders = strtoul(argv[1], NULL, 0);
    }
    if (argc > 3) {
        duration = strtoul(argv[3], NULL, 0);
    }
    if (argc < 3 || strcmp(argv[2], "stress") == 0) {
        stresstest(nreaders, duration);
    } else if (strcmp(argv[2], "rperf") == 0) {
        rperftest(nreaders, duration);
    } else if (strcmp(argv[2], "uperf") == 0) {
        uperftest(nreaders, duration);
    } else if (strcmp(argv[2], "perf") == 0) {
        perftest(nreaders, duration);
    }
    usage(argc, argv);
    return 0;
}
