/*
 * Copyright (C) 2014 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "Benchmark.h"
#include "CPUCount.h"
#include "alloc_free.h"
#include "balloon.h"
#include "big.h"
#include "churn.h"
#include "facebook.h"
#include "flickr.h"
#include "fragment.h"
#include "list.h"
#include "medium.h"
#include "message.h"
#include "nimlang.h"
#include "reddit.h"
#include "realloc.h"
#include "stress.h"
#include "stress_aligned.h"
#include "theverge.h"
#include "tree.h"
#include <algorithm>
#include <iostream>
#include <map>
#include <stdio.h>
#include <string>
#include <strings.h>
#include <sys/time.h>
#include <thread>
#include <vector>

#ifdef __APPLE__
#include <dispatch/dispatch.h>
#endif

#include "mbmalloc.h"

using namespace std;

struct BenchmarkPair {
    const char* const name;
    const BenchmarkFunction function;
};

static const BenchmarkPair benchmarkPairs[] = {
    { "alloc_free", benchmark_alloc_free },
    { "balloon", benchmark_balloon },
    { "big", benchmark_big },
    { "churn", benchmark_churn },
    { "facebook", benchmark_facebook },
    { "flickr", benchmark_flickr },
    { "flickr_memory_warning", benchmark_flickr_memory_warning },
    { "fragment", benchmark_fragment },
    { "fragment_iterate", benchmark_fragment_iterate },
    { "list_allocate", benchmark_list_allocate },
    { "list_traverse", benchmark_list_traverse },
    { "medium", benchmark_medium },
    { "message_many", benchmark_message_many },
    { "message_one", benchmark_message_one },
    { "nimlang", benchmark_nimlang },
    { "realloc", benchmark_realloc },
    { "reddit", benchmark_reddit },
    { "reddit_memory_warning", benchmark_reddit_memory_warning },
    { "stress", benchmark_stress },
    { "stress_aligned", benchmark_stress_aligned },
    { "theverge", benchmark_theverge },
    { "theverge_memory_warning", benchmark_theverge_memory_warning },
    { "tree_allocate", benchmark_tree_allocate },
    { "tree_churn", benchmark_tree_churn },
    { "tree_traverse", benchmark_tree_traverse },
};

static const size_t benchmarksPairsCount = sizeof(benchmarkPairs) / sizeof(BenchmarkPair);

static inline bool operator==(const BenchmarkPair& benchmarkPair, const string& string)
{
    return string == benchmarkPair.name;
}

static void*** allocateHeap(size_t heapSize, size_t chunkSize, size_t objectSize)
{
    if (!heapSize)
        return 0;

    size_t chunkCount = heapSize / chunkSize;
    size_t objectCount = chunkSize / objectSize;
    void*** chunks = (void***)mbmalloc(chunkCount * sizeof(void**));
    for (size_t i = 0; i < chunkCount; ++i) {
        chunks[i] = (void**)mbmalloc(objectCount * sizeof(void*));
        for (size_t j = 0; j < objectCount; ++j) {
            chunks[i][j] = (void*)mbmalloc(objectSize);
            bzero(chunks[i][j], objectSize);
        }
    }
    return chunks;
}

static void deallocateHeap(void*** chunks, size_t heapSize, size_t chunkSize, size_t objectSize)
{
    if (!heapSize)
        return;

    size_t chunkCount = heapSize / chunkSize;
    size_t objectCount = chunkSize / objectSize;
    for (size_t i = 0; i < chunkCount; ++i) {
        for (size_t j = 0; j < objectCount; ++j)
            mbfree(chunks[i][j], objectSize);
        mbfree(chunks[i], objectCount * sizeof(void*));
    }
    mbfree(chunks, chunkCount * sizeof(void**));
}

Benchmark::Benchmark(CommandLine& commandLine)
    : m_commandLine(commandLine)
{
    const BenchmarkPair* benchmarkPair = std::find(
        benchmarkPairs, benchmarkPairs + benchmarksPairsCount, m_commandLine.benchmarkName());
    if (benchmarkPair == benchmarkPairs + benchmarksPairsCount)
        return;
    
    m_benchmarkPair = benchmarkPair;
}
    
void Benchmark::printBenchmarks()
{
    cout << "Benchmarks: " << endl;
    for (size_t i = 0; i < benchmarksPairsCount; ++i)
        cout << "\t" << benchmarkPairs[i].name << endl;
}

void Benchmark::runOnce()
{
    if (!m_commandLine.isParallel()) {
        m_benchmarkPair->function(m_commandLine);
        return;
    }

#ifdef __APPLE__
    dispatch_group_t group = dispatch_group_create();

    for (size_t i = 0; i < cpuCount(); ++i) {
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            m_benchmarkPair->function(m_commandLine);
        });
    }

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    dispatch_release(group);
#else
    std::vector<std::thread> threads;
    for (size_t i = 0; i < cpuCount(); ++i) {
        threads.emplace_back([&] {
            m_benchmarkPair->function(m_commandLine);
        });
    }
    for (auto& thread : threads)
        thread.join();
#endif
}

void Benchmark::run()
{
    static const size_t objectSize = 32;
    static const size_t chunkSize = 1024 * 1024;
    
    void*** heap = allocateHeap(m_commandLine.heapSize(), chunkSize, objectSize);

    if (m_commandLine.warmUp())
        runOnce(); // Warmup run.

    size_t runs = m_commandLine.runs();

    for (size_t i = 0; i < runs; ++i) {
        double start = currentTimeMS();
        runOnce();
        double end = currentTimeMS();
        double elapsed = end - start;
        m_elapsedTime += elapsed;
    }
    m_elapsedTime /= runs;

    deallocateHeap(heap, m_commandLine.heapSize(), chunkSize, objectSize);
    
    mbscavenge();
    m_memory = currentMemoryBytes();
}

void Benchmark::printReport()
{
    size_t kB = 1024;

    cout << "Time:       \t" << m_elapsedTime << "ms" << endl;
    cout << "Peak Memory:\t" << m_memory.residentMax / kB << "kB" << endl;
    cout << "Memory at End:     \t" << m_memory.resident / kB << "kB" << endl;
}

double Benchmark::currentTimeMS()
{
    struct timeval now;
    gettimeofday(&now, 0);
    return (now.tv_sec * 1000.0) + now.tv_usec / 1000.0;
}

