/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bandwidth.h"

#include <ctype.h>
#include <pthread.h>
#include <sched.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>

#include <map>
#include <memory>
#include <vector>


typedef struct {
    const char *name;
    bool int_type;
} option_t;

option_t bandwidth_opts[] = {
    { "size", true },
    { "num_warm_loops", true },
    { "num_loops", true },
    { "type", false },
    { NULL, false },
};

option_t per_core_opts[] = {
    { "size", true },
    { "num_warm_loops", true},
    { "num_loops", true },
    { "type", false },
    { NULL, false },
};

option_t multithread_opts[] = {
    { "size", true },
    { "num_warm_loops", true},
    { "num_loops", true },
    { "type", false },
    { "num_threads", true },
    { NULL, false },
};

typedef union {
    int int_value;
    const char *char_value;
} arg_value_t;
typedef std::map<const char*, arg_value_t> arg_t;

bool processBandwidthOptions(int argc, char** argv, option_t options[],
                             arg_t *values) {
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] == '-' && argv[i][1] == '-' && !isdigit(argv[i][2])) {
            char *arg = &argv[i][2];

            for (int j = 0; options[j].name != NULL; j++) {
                if (strcmp(arg, options[j].name) == 0) {
                    const char *name = options[j].name;
                    if (i == argc - 1) {
                        printf("The option --%s requires an argument.\n", name);
                        return false;
                    }
                    if (options[j].int_type) {
                        (*values)[name].int_value = strtol(argv[++i], NULL, 0);
                    } else {
                        (*values)[name].char_value = argv[++i];
                    }
                }
            }
        }
    }

    return true;
}

BandwidthBenchmark *createBandwidthBenchmarkObject(arg_t values) {
    BandwidthBenchmark *bench = NULL;

    const char *name = values["type"].char_value;
    size_t size = 0;
    if (values.count("size") > 0) {
        size = values["size"].int_value;
    }
    if (strcmp(name, "copy_ldrd_strd") == 0) {
        bench = new CopyLdrdStrdBenchmark();
    } else if (strcmp(name, "copy_ldmia_stmia") == 0) {
        bench = new CopyLdmiaStmiaBenchmark();
    } else if (strcmp(name, "copy_vld1_vst1") == 0) {
        bench = new CopyVld1Vst1Benchmark();
    } else if (strcmp(name, "copy_vldr_vstr") == 0) {
        bench = new CopyVldrVstrBenchmark();
    } else if (strcmp(name, "copy_vldmia_vstmia") == 0) {
        bench = new CopyVldmiaVstmiaBenchmark();
    } else if (strcmp(name, "memcpy") == 0) {
        bench = new MemcpyBenchmark();
    } else if (strcmp(name, "write_strd") == 0) {
        bench = new WriteStrdBenchmark();
    } else if (strcmp(name, "write_stmia") == 0) {
        bench = new WriteStmiaBenchmark();
    } else if (strcmp(name, "write_vst1") == 0) {
        bench = new WriteVst1Benchmark();
    } else if (strcmp(name, "write_vstr") == 0) {
        bench = new WriteVstrBenchmark();
    } else if (strcmp(name, "write_vstmia") == 0) {
        bench = new WriteVstmiaBenchmark();
    } else if (strcmp(name, "memset") == 0) {
        bench = new MemsetBenchmark();
    } else if (strcmp(name, "read_ldrd") == 0) {
        bench = new ReadLdrdBenchmark();
    } else if (strcmp(name, "read_ldmia") == 0) {
        bench = new ReadLdmiaBenchmark();
    } else if (strcmp(name, "read_vld1") == 0) {
        bench = new ReadVld1Benchmark();
    } else if (strcmp(name, "read_vldr") == 0) {
        bench = new ReadVldrBenchmark();
    } else if (strcmp(name, "read_vldmia") == 0) {
        bench = new ReadVldmiaBenchmark();
    } else {
        printf("Unknown type name %s\n", name);
        return NULL;
    }

    if (!bench->setSize(size)) {
        printf("Failed to allocate buffers for benchmark.\n");
        delete bench;
        return NULL;
    }

    if (values.count("num_warm_loops") > 0) {
        bench->set_num_loops(values["num_warm_loops"].int_value);
    }
    if (values.count("num_loops") > 0) {
        bench->set_num_loops(values["num_loops"].int_value);
    }

    return bench;
}

bool getAvailCpus(std::vector<int> *cpu_list) {
    cpu_set_t cpuset;

    CPU_ZERO(&cpuset);
    if (sched_getaffinity(0, sizeof(cpuset), &cpuset) != 0) {
        perror("sched_getaffinity failed.");
        return false;
    }

    for (int i = 0; i < CPU_SETSIZE; i++) {
        if (CPU_ISSET(i, &cpuset)) {
            cpu_list->push_back(i);
        }
    }

    return true;
}

typedef struct {
    int core;
    BandwidthBenchmark *bench;
    double  avg_mb;
    volatile bool *run;
} thread_arg_t;

void *runBandwidthThread(void *data) {
    thread_arg_t *arg = reinterpret_cast<thread_arg_t *>(data);

    if (arg->core >= 0) {
        cpu_set_t cpuset;
        CPU_ZERO(&cpuset);
        CPU_SET(arg->core, &cpuset);
        if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
            perror("sched_setaffinity failed");
            return NULL;
        }
    }

    // Spinloop waiting for the run variable to get set to true.
    while (!*arg->run) {
    }

    double avg_mb = 0;
    for (int run = 1; ; run++) {
        arg->bench->run();
        if (!*arg->run) {
            // Throw away the last data point since it's possible not
            // all of the threads are running at this point.
            break;
        }
        avg_mb = (avg_mb/run) * (run-1) + arg->bench->mb_per_sec()/run;
    }
    arg->avg_mb = avg_mb;

    return NULL;
}

bool processThreadArgs(int argc, char** argv, option_t options[],
                       arg_t *values) {
    // Use some smaller values for the number of loops.
    (*values)["num_warm_loops"].int_value = 1000000;
    (*values)["num_loops"].int_value = 10000000;

    if (!processBandwidthOptions(argc, argv, options, values)) {
        return false;
    }
    if (values->count("size") > 0 && ((*values)["size"].int_value % 64) != 0) {
        printf("The size values must be a multiple of 64.\n");
        return false;
    }
    if (values->count("type") == 0) {
        printf("Must specify the type value.\n");
        return false;
    }

    std::unique_ptr<BandwidthBenchmark> bench{
        createBandwidthBenchmarkObject(*values)};
    if (!bench) {
        return false;
    }

    if (setpriority(PRIO_PROCESS, 0, -20)) {
        perror("Unable to raise priority of process.");
        return false;
    }

    printf("Calculating optimum run time...\n");
    nsecs_t t = system_time();
    bench->run();
    t = system_time() - t;
    // Since this is only going to be running single threaded, assume that
    // if the number is set to ten times this value, we should get at least
    // a couple of samples per thread.
    int run_time = int((t/1000000000.0)*10 + 0.5) + 5;

    (*values)["run_time"].int_value = run_time;
    (*values)["size"].int_value = bench->size();
    (*values)["num_warm_loops"].int_value = bench->num_warm_loops();
    (*values)["num_loops"].int_value = bench->num_loops();

    return true;
}

bool runThreadedTest(thread_arg_t args[], int num_threads, int run_time) {
    pthread_t threads[num_threads];
    volatile bool run = false;

    int rc;
    for (int i = 0; i < num_threads; i++) {
        args[i].run = &run;
        rc = pthread_create(&threads[i], NULL, runBandwidthThread,
                            (void*)&args[i]);
        if (rc != 0) {
            printf("Failed to launch thread %d\n", i);
            return false;
        }
    }

    // Kick start the threads.
    run = true;

    // Let the threads run.
    sleep(run_time);

    // Stop the threads.
    run = false;

    // Wait for the threads to complete.
    for (int i = 0; i < num_threads; i++) {
        rc = pthread_join(threads[i], NULL);
        if (rc != 0) {
            printf("Thread %d failed to join.\n", i);
            return false;
        }
        printf("Thread %d: bandwidth using %s %0.2f MB/s\n", i,
               args[i].bench->getName(), args[i].avg_mb);
    }

    return true;
}

int per_core_bandwidth(int argc, char** argv) {
    arg_t values;
    if (!processThreadArgs(argc, argv, per_core_opts, &values)) {
        return -1;
    }

    std::vector<int> cpu_list;
    if (!getAvailCpus(&cpu_list)) {
        printf("Failed to get available cpu list.\n");
        return -1;
    }

    thread_arg_t args[cpu_list.size()];

    int i = 0;
    for (std::vector<int>::iterator it = cpu_list.begin();
         it != cpu_list.end(); ++it, ++i) {
        args[i].core = *it;
        args[i].bench = createBandwidthBenchmarkObject(values);
        if (!args[i].bench) {
            for (int j = 0; j < i; j++)
                delete args[j].bench;
            return -1;
        }
    }

    printf("Running on %d cores\n", cpu_list.size());
    printf("  run_time = %ds\n", values["run_time"].int_value);
    printf("  size = %d\n", values["size"].int_value);
    printf("  num_warm_loops = %d\n", values["num_warm_loops"].int_value);
    printf("  num_loops = %d\n", values["num_loops"].int_value);
    printf("\n");

    if (!runThreadedTest(args, cpu_list.size(), values["run_time"].int_value)) {
        return -1;
    }

    return 0;
}

int multithread_bandwidth(int argc, char** argv) {
    arg_t values;
    if (!processThreadArgs(argc, argv, multithread_opts, &values)) {
        return -1;
    }
    if (values.count("num_threads") == 0) {
        printf("Must specify the num_threads value.\n");
        return -1;
    }
    int num_threads = values["num_threads"].int_value;

    thread_arg_t args[num_threads];

    for (int i = 0; i < num_threads; i++) {
        args[i].core = -1;
        args[i].bench = createBandwidthBenchmarkObject(values);
        if (!args[i].bench) {
            for (int j = 0; j < i; j++)
                delete args[j].bench;
            return -1;
        }
    }

    printf("Running %d threads\n", num_threads);
    printf("  run_time = %ds\n", values["run_time"].int_value);
    printf("  size = %d\n", values["size"].int_value);
    printf("  num_warm_loops = %d\n", values["num_warm_loops"].int_value);
    printf("  num_loops = %d\n", values["num_loops"].int_value);
    printf("\n");

    if (!runThreadedTest(args, num_threads, values["run_time"].int_value)) {
        return -1;
    }

    return 0;
}

bool run_bandwidth_benchmark(int argc, char** argv, const char *name,
                             std::vector<BandwidthBenchmark*> bench_objs) {
    arg_t values;
    values["size"].int_value = 0;
    values["num_warm_loops"].int_value = 0;
    values["num_loops"].int_value = 0;
    if (!processBandwidthOptions(argc, argv, bandwidth_opts, &values)) {
        return false;
    }

    size_t size = values["size"].int_value;
    if ((size % 64) != 0) {
        printf("The size value must be a multiple of 64.\n");
        return false;
    }

    if (setpriority(PRIO_PROCESS, 0, -20)) {
        perror("Unable to raise priority of process.");
        return false;
    }

    bool preamble_printed = false;
    size_t num_warm_loops = values["num_warm_loops"].int_value;
    size_t num_loops = values["num_loops"].int_value;
    for (std::vector<BandwidthBenchmark*>::iterator it = bench_objs.begin();
         it != bench_objs.end(); ++it) {
        if (!(*it)->canRun()) {
            continue;
        }
        if (!(*it)->setSize(values["size"].int_value)) {
            printf("Failed creating buffer for bandwidth test.\n");
            return false;
        }
        if (num_warm_loops) {
            (*it)->set_num_warm_loops(num_warm_loops);
        }
        if (num_loops) {
            (*it)->set_num_loops(num_loops);
        }
        if (!preamble_printed) {
            preamble_printed = true;
            printf("Benchmarking %s bandwidth\n", name);
            printf("  size = %d\n", (*it)->size());
            printf("  num_warm_loops = %d\n", (*it)->num_warm_loops());
            printf("  num_loops = %d\n\n", (*it)->num_loops());
        }
        (*it)->run();
        printf("  %s bandwidth with %s: %0.2f MB/s\n", name, (*it)->getName(),
               (*it)->mb_per_sec());
    }

    return true;
}

int copy_bandwidth(int argc, char** argv) {
    std::vector<BandwidthBenchmark*> bench_objs;
    bench_objs.push_back(new CopyLdrdStrdBenchmark());
    bench_objs.push_back(new CopyLdmiaStmiaBenchmark());
    bench_objs.push_back(new CopyVld1Vst1Benchmark());
    bench_objs.push_back(new CopyVldrVstrBenchmark());
    bench_objs.push_back(new CopyVldmiaVstmiaBenchmark());
    bench_objs.push_back(new MemcpyBenchmark());

    if (!run_bandwidth_benchmark(argc, argv, "copy", bench_objs)) {
        return -1;
    }
    return 0;
}

int write_bandwidth(int argc, char** argv) {
    std::vector<BandwidthBenchmark*> bench_objs;
    bench_objs.push_back(new WriteStrdBenchmark());
    bench_objs.push_back(new WriteStmiaBenchmark());
    bench_objs.push_back(new WriteVst1Benchmark());
    bench_objs.push_back(new WriteVstrBenchmark());
    bench_objs.push_back(new WriteVstmiaBenchmark());
    bench_objs.push_back(new MemsetBenchmark());

    if (!run_bandwidth_benchmark(argc, argv, "write", bench_objs)) {
        return -1;
    }

    return 0;
}

int read_bandwidth(int argc, char** argv) {
    std::vector<BandwidthBenchmark*> bench_objs;
    bench_objs.push_back(new ReadLdrdBenchmark());
    bench_objs.push_back(new ReadLdmiaBenchmark());
    bench_objs.push_back(new ReadVld1Benchmark());
    bench_objs.push_back(new ReadVldrBenchmark());
    bench_objs.push_back(new ReadVldmiaBenchmark());

    if (!run_bandwidth_benchmark(argc, argv, "read", bench_objs)) {
        return -1;
    }
    return 0;
}
