//===-- Timer.cpp -----------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Core/Timer.h"

#include <map>
#include <vector>
#include <algorithm>

#include "lldb/Core/Stream.h"
#include "lldb/Host/Mutex.h"

#include <stdio.h>

using namespace lldb_private;

#define TIMER_INDENT_AMOUNT 2
static bool g_quiet = true;
uint32_t Timer::g_depth = 0;
uint32_t Timer::g_display_depth = 0;
FILE * Timer::g_file = NULL;
typedef std::vector<Timer *> TimerStack;
typedef std::map<const char *, uint64_t> TimerCategoryMap;
static pthread_key_t g_key;

static Mutex &
GetCategoryMutex()
{
    static Mutex g_category_mutex(Mutex::eMutexTypeNormal);
    return g_category_mutex;
}

static TimerCategoryMap &
GetCategoryMap()
{
    static TimerCategoryMap g_category_map;
    return g_category_map;
}


static TimerStack *
GetTimerStackForCurrentThread ()
{
    void *timer_stack = ::pthread_getspecific (g_key);
    if (timer_stack == NULL)
    {
        ::pthread_setspecific (g_key, new TimerStack);
        timer_stack = ::pthread_getspecific (g_key);
    }
    return (TimerStack *)timer_stack;
}

void
ThreadSpecificCleanup (void *p)
{
    delete (TimerStack *)p;
}

void
Timer::SetQuiet (bool value)
{
    g_quiet = value;
}

void
Timer::Initialize ()
{
    Timer::g_file = stdout;
    ::pthread_key_create (&g_key, ThreadSpecificCleanup);

}

Timer::Timer (const char *category, const char *format, ...) :
    m_category (category),
    m_total_start (),
    m_timer_start (),
    m_total_ticks (0),
    m_timer_ticks (0)
{
    if (g_depth++ < g_display_depth)
    {
        if (g_quiet == false)
        {
            // Indent
            ::fprintf (g_file, "%*s", g_depth * TIMER_INDENT_AMOUNT, "");
            // Print formatted string
            va_list args;
            va_start (args, format);
            ::vfprintf (g_file, format, args);
            va_end (args);

            // Newline
            ::fprintf (g_file, "\n");
        }
        TimeValue start_time(TimeValue::Now());
        m_total_start = start_time;
        m_timer_start = start_time;
        TimerStack *stack = GetTimerStackForCurrentThread ();
        if (stack)
        {
            if (stack->empty() == false)
                stack->back()->ChildStarted (start_time);
            stack->push_back(this);
        }
    }
}


Timer::~Timer()
{
    if (m_total_start.IsValid())
    {
        TimeValue stop_time = TimeValue::Now();
        if (m_total_start.IsValid())
        {
            m_total_ticks += (stop_time - m_total_start);
            m_total_start.Clear();
        }
        if (m_timer_start.IsValid())
        {
            m_timer_ticks += (stop_time - m_timer_start);
            m_timer_start.Clear();
        }

        TimerStack *stack = GetTimerStackForCurrentThread ();
        if (stack)
        {
            assert (stack->back() == this);
            stack->pop_back();
            if (stack->empty() == false)
                stack->back()->ChildStopped(stop_time);
        }

        const uint64_t total_nsec_uint = GetTotalElapsedNanoSeconds();
        const uint64_t timer_nsec_uint = GetTimerElapsedNanoSeconds();
        const double total_nsec = total_nsec_uint;
        const double timer_nsec = timer_nsec_uint;

        if (g_quiet == false)
        {

            ::fprintf (g_file,
                       "%*s%.9f sec (%.9f sec)\n",
                       (g_depth - 1) *TIMER_INDENT_AMOUNT, "",
                       total_nsec / 1000000000.0,
                       timer_nsec / 1000000000.0);
        }

        // Keep total results for each category so we can dump results.
        Mutex::Locker locker (GetCategoryMutex());
        TimerCategoryMap &category_map = GetCategoryMap();
        category_map[m_category] += timer_nsec_uint;
    }
    if (g_depth > 0)
        --g_depth;
}

uint64_t
Timer::GetTotalElapsedNanoSeconds()
{
    uint64_t total_ticks = m_total_ticks;

    // If we are currently running, we need to add the current
    // elapsed time of the running timer...
    if (m_total_start.IsValid())
        total_ticks += (TimeValue::Now() - m_total_start);

    return total_ticks;
}

uint64_t
Timer::GetTimerElapsedNanoSeconds()
{
    uint64_t timer_ticks = m_timer_ticks;

    // If we are currently running, we need to add the current
    // elapsed time of the running timer...
    if (m_timer_start.IsValid())
        timer_ticks += (TimeValue::Now() - m_timer_start);

    return timer_ticks;
}

void
Timer::ChildStarted (const TimeValue& start_time)
{
    if (m_timer_start.IsValid())
    {
        m_timer_ticks += (start_time - m_timer_start);
        m_timer_start.Clear();
    }
}

void
Timer::ChildStopped (const TimeValue& stop_time)
{
    if (!m_timer_start.IsValid())
        m_timer_start = stop_time;
}

void
Timer::SetDisplayDepth (uint32_t depth)
{
    g_display_depth = depth;
}


/* binary function predicate:
 * - returns whether a person is less than another person
 */
static bool
CategoryMapIteratorSortCriterion (const TimerCategoryMap::const_iterator& lhs, const TimerCategoryMap::const_iterator& rhs)
{
    return lhs->second > rhs->second;
}


void
Timer::ResetCategoryTimes ()
{
    Mutex::Locker locker (GetCategoryMutex());
    TimerCategoryMap &category_map = GetCategoryMap();
    category_map.clear();
}

void
Timer::DumpCategoryTimes (Stream *s)
{
    Mutex::Locker locker (GetCategoryMutex());
    TimerCategoryMap &category_map = GetCategoryMap();
    std::vector<TimerCategoryMap::const_iterator> sorted_iterators;
    TimerCategoryMap::const_iterator pos, end = category_map.end();
    for (pos = category_map.begin(); pos != end; ++pos)
    {
        sorted_iterators.push_back (pos);
    }
    std::sort (sorted_iterators.begin(), sorted_iterators.end(), CategoryMapIteratorSortCriterion);

    const size_t count = sorted_iterators.size();
    for (size_t i=0; i<count; ++i)
    {
        const double timer_nsec = sorted_iterators[i]->second;
        s->Printf("%.9f sec for %s\n", timer_nsec / 1000000000.0, sorted_iterators[i]->first);
    }
}
