/*
 * Copyright (C) 2010 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.
 *
 */

/*
 * Binder add integers benchmark
 *
 * Measures the rate at which a short binder IPC operation can be
 * performed.  The operation consists of the client sending a parcel
 * that contains two integers.  For each parcel that the server
 * receives, it adds the two integers and sends the sum back to
 * the client.
 *
 * This benchmark supports the following command-line options:
 *
 *   -c cpu - bind client to specified cpu (default: unbound)
 *   -s cpu - bind server to specified cpu (default: unbound)
 *   -n num - perform IPC operation num times (default: 1000)
 *   -d time - delay specified amount of seconds after each
 *             IPC operation. (default 1e-3)
 */

#include <cerrno>
#include <grp.h>
#include <iostream>
#include <libgen.h>
#include <time.h>
#include <unistd.h>

#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <testUtil.h>

using namespace android;
using namespace std;

const int unbound = -1; // Indicator for a thread not bound to a specific CPU

String16 serviceName("test.binderAddInts");

struct options {
    int serverCPU;
    int clientCPU;
    unsigned int iterations;
    float        iterDelay; // End of iteration delay in seconds
} options = { // Set defaults
    unbound, // Server CPU
    unbound, // Client CPU
    1000,    // Iterations
    1e-3,    // End of iteration delay
};

class AddIntsService : public BBinder
{
  public:
    explicit AddIntsService(int cpu = unbound);
    virtual ~AddIntsService() {}

    enum command {
        ADD_INTS = 0x120,
    };

    virtual status_t onTransact(uint32_t code,
                                const Parcel& data, Parcel* reply,
                                uint32_t flags = 0);

  private:
    int cpu_;
};

// File scope function prototypes
static void server(void);
static void client(void);
static void bindCPU(unsigned int cpu);
static ostream &operator<<(ostream &stream, const String16& str);
static ostream &operator<<(ostream &stream, const cpu_set_t& set);

int main(int argc, char *argv[])
{
    int rv;

    // Determine CPUs available for use.
    // This testcase limits its self to using CPUs that were
    // available at the start of the benchmark.
    cpu_set_t availCPUs;
    if ((rv = sched_getaffinity(0, sizeof(availCPUs), &availCPUs)) != 0) {
        cerr << "sched_getaffinity failure, rv: " << rv
            << " errno: " << errno << endl;
        exit(1);
    }

    // Parse command line arguments
    int opt;
    while ((opt = getopt(argc, argv, "s:c:n:d:?")) != -1) {
        char *chptr; // character pointer for command-line parsing

        switch (opt) {
        case 'c': // client CPU
        case 's': { // server CPU
            // Parse the CPU number
            int cpu = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                cerr << "Invalid cpu specified for -" << (char) opt
                    << " option of: " << optarg << endl;
                exit(2);
            }

            // Is the CPU available?
            if (!CPU_ISSET(cpu, &availCPUs)) {
                cerr << "CPU " << optarg << " not currently available" << endl;
                cerr << "  Available CPUs: " << availCPUs << endl;
                exit(3);
            }

            // Record the choice
            *((opt == 'c') ? &options.clientCPU : &options.serverCPU) = cpu;
            break;
        }

        case 'n': // iterations
            options.iterations = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                cerr << "Invalid iterations specified of: " << optarg << endl;
                exit(4);
            }
            if (options.iterations < 1) {
                cerr << "Less than 1 iteration specified by: "
                    << optarg << endl;
                exit(5);
            }
            break;

        case 'd': // Delay between each iteration
            options.iterDelay = strtod(optarg, &chptr);
            if ((*chptr != '\0') || (options.iterDelay < 0.0)) {
                cerr << "Invalid delay specified of: " << optarg << endl;
                exit(6);
            }
            break;

        case '?':
        default:
            cerr << basename(argv[0]) << " [options]" << endl;
            cerr << "  options:" << endl;
            cerr << "    -s cpu - server CPU number" << endl;
            cerr << "    -c cpu - client CPU number" << endl;
            cerr << "    -n num - iterations" << endl;
            cerr << "    -d time - delay after operation in seconds" << endl;
            exit(((optopt == 0) || (optopt == '?')) ? 0 : 7);
        }
    }

    // Display selected options
    cout << "serverCPU: ";
    if (options.serverCPU == unbound) {
        cout << " unbound";
    } else {
        cout << options.serverCPU;
    }
    cout << endl;
    cout << "clientCPU: ";
    if (options.clientCPU == unbound) {
        cout << " unbound";
    } else {
        cout << options.clientCPU;
    }
    cout << endl;
    cout << "iterations: " << options.iterations << endl;
    cout << "iterDelay: " << options.iterDelay << endl;

    // Fork client, use this process as server
    fflush(stdout);
    switch (pid_t pid = fork()) {
    case 0: // Child
        client();
        return 0;

    default: // Parent
        server();

        // Wait for all children to end
        do {
            int stat;
            rv = wait(&stat);
            if ((rv == -1) && (errno == ECHILD)) { break; }
            if (rv == -1) {
                cerr << "wait failed, rv: " << rv << " errno: "
                    << errno << endl;
                perror(NULL);
                exit(8);
            }
        } while (1);
        return 0;

    case -1: // Error
        exit(9);
    }

    return 0;
}

static void server(void)
{
    int rv;

    // Add the service
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    if ((rv = sm->addService(serviceName,
        new AddIntsService(options.serverCPU))) != 0) {
        cerr << "addService " << serviceName << " failed, rv: " << rv
            << " errno: " << errno << endl;
    }

    // Start threads to handle server work
    proc->startThreadPool();
}

static void client(void)
{
    int rv;
    sp<IServiceManager> sm = defaultServiceManager();
    double min = FLT_MAX, max = 0.0, total = 0.0; // Time in seconds for all
                                                  // the IPC calls.

    // If needed bind to client CPU
    if (options.clientCPU != unbound) { bindCPU(options.clientCPU); }

    // Attach to service
    sp<IBinder> binder;
    do {
        binder = sm->getService(serviceName);
        if (binder != 0) break;
        cout << serviceName << " not published, waiting..." << endl;
        usleep(500000); // 0.5 s
    } while(true);

    // Perform the IPC operations
    for (unsigned int iter = 0; iter < options.iterations; iter++) {
        Parcel send, reply;

        // Create parcel to be sent.  Will use the iteration cound
        // and the iteration count + 3 as the two integer values
        // to be sent.
        int val1 = iter;
        int val2 = iter + 3;
        int expected = val1 + val2;  // Expect to get the sum back
        send.writeInt32(val1);
        send.writeInt32(val2);

        // Send the parcel, while timing how long it takes for
        // the answer to return.
        struct timespec start;
        clock_gettime(CLOCK_MONOTONIC, &start);
        if ((rv = binder->transact(AddIntsService::ADD_INTS,
            send, &reply)) != 0) {
            cerr << "binder->transact failed, rv: " << rv
                << " errno: " << errno << endl;
            exit(10);
        }
        struct timespec current;
        clock_gettime(CLOCK_MONOTONIC, &current);

        // Calculate how long this operation took and update the stats
        struct timespec deltaTimespec = tsDelta(&start, &current);
        double delta = ts2double(&deltaTimespec);
        min = (delta < min) ? delta : min;
        max = (delta > max) ? delta : max;
        total += delta;
        int result = reply.readInt32();
        if (result != (int) (iter + iter + 3)) {
            cerr << "Unexpected result for iteration " << iter << endl;
            cerr << "  result: " << result << endl;
            cerr << "expected: " << expected << endl;
        }

        if (options.iterDelay > 0.0) { testDelaySpin(options.iterDelay); }
    }

    // Display the results
    cout << "Time per iteration min: " << min
        << " avg: " << (total / options.iterations)
        << " max: " << max
        << endl;
}

AddIntsService::AddIntsService(int cpu): cpu_(cpu) {
    if (cpu != unbound) { bindCPU(cpu); }
}

// Server function that handles parcels received from the client
status_t AddIntsService::onTransact(uint32_t code, const Parcel &data,
                                    Parcel* reply, uint32_t /* flags */) {
    int val1, val2;
    status_t rv(0);
    int cpu;

    // If server bound to a particular CPU, check that
    // were executing on that CPU.
    if (cpu_ != unbound) {
        cpu = sched_getcpu();
        if (cpu != cpu_) {
            cerr << "server onTransact on CPU " << cpu << " expected CPU "
                  << cpu_ << endl;
            exit(20);
        }
    }

    // Perform the requested operation
    switch (code) {
    case ADD_INTS:
        val1 = data.readInt32();
        val2 = data.readInt32();
        reply->writeInt32(val1 + val2);
        break;

    default:
      cerr << "server onTransact unknown code, code: " << code << endl;
      exit(21);
    }

    return rv;
}

static void bindCPU(unsigned int cpu)
{
    int rv;
    cpu_set_t cpuset;

    CPU_ZERO(&cpuset);
    CPU_SET(cpu, &cpuset);
    rv = sched_setaffinity(0, sizeof(cpuset), &cpuset);

    if (rv != 0) {
        cerr << "bindCPU failed, rv: " << rv << " errno: " << errno << endl;
        perror(NULL);
        exit(30);
    }
}

static ostream &operator<<(ostream &stream, const String16& str)
{
    for (unsigned int n1 = 0; n1 < str.size(); n1++) {
        if ((str[n1] > 0x20) && (str[n1] < 0x80)) {
            stream << (char) str[n1];
        } else {
            stream << '~';
        }
    }

    return stream;
}

static ostream &operator<<(ostream &stream, const cpu_set_t& set)
{
    for (unsigned int n1 = 0; n1 < CPU_SETSIZE; n1++) {
        if (CPU_ISSET(n1, &set)) {
            if (n1 != 0) { stream << ' '; }
            stream << n1;
        }
    }

    return stream;
}
