124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Timer.h -------------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef liblldb_Timer_h_
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define liblldb_Timer_h_
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#if defined(__cplusplus)
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1421120ece120034450279001ff18937eb4fe1aaecGreg Clayton#include <stdarg.h>
15382eb3a60d25409612e0bb33fd4db7f848fb2c55Eli Friedman#include <stdio.h>
16f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton#include <string>
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Host/TimeValue.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnernamespace lldb_private {
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// @class Timer Timer.h "lldb/Core/Timer.h"
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// @brief A timer class that simplifies common timing metrics.
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner///
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// A scoped timer class that allows a variety of pthread mutex
27a00ca6dca3e2031387d2c651b5b42423f05bd50eJohnny Chen/// objects to have a mutex locked when a Timer::Locker
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// object is created, and unlocked when it goes out of scope or
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// when the Timer::Locker::Reset(pthread_mutex_t *)
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// is called. This provides an exception safe way to lock a mutex
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner/// in a scope.
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass Timer
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static void
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Initialize ();
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //--------------------------------------------------------------
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Default constructor.
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //--------------------------------------------------------------
437e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda    Timer(const char *category, const char *format, ...)  __attribute__ ((format (printf, 3, 4)));
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //--------------------------------------------------------------
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Desstructor
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //--------------------------------------------------------------
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ~Timer();
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Dump ();
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static void
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SetDisplayDepth (uint32_t depth);
554ba3999e714c73ef52a21b0d59f705c0cad98810Jim Ingham
564ba3999e714c73ef52a21b0d59f705c0cad98810Jim Ingham    static void
574ba3999e714c73ef52a21b0d59f705c0cad98810Jim Ingham    SetQuiet (bool value);
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static void
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DumpCategoryTimes (Stream *s);
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static void
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ResetCategoryTimes ();
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprotected:
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ChildStarted (const TimeValue& time);
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ChildStopped (const TimeValue& time);
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetTotalElapsedNanoSeconds();
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    GetTimerElapsedNanoSeconds();
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //--------------------------------------------------------------
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    /// Member variables
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //--------------------------------------------------------------
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *m_category;
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    TimeValue m_total_start;
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    TimeValue m_timer_start;
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t m_total_ticks; // Total running time for this timer including when other timers below this are running
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t m_timer_ticks; // Ticks for this timer that do not include when other timers below this one are running
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static uint32_t g_depth;
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static uint32_t g_display_depth;
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static FILE * g_file;
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprivate:
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Timer();
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DISALLOW_COPY_AND_ASSIGN (Timer);
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
94f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
95ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonclass IntervalTimer
96ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
97ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonpublic:
98ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    IntervalTimer() :
99ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_start (TimeValue::Now())
100ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
101ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
102ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
103ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ~IntervalTimer()
104ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
105ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
106ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
107ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    uint64_t
108ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    GetElapsedNanoSeconds() const
109ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
110ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return TimeValue::Now() - m_start;
111ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
112ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
113ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    void
114ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    Reset ()
115ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
116ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_start = TimeValue::Now();
117ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
118ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
119ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    int
120ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    PrintfElapsed (const char *format, ...)  __attribute__ ((format (printf, 2, 3)))
121ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
122ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        TimeValue now (TimeValue::Now());
123ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        const uint64_t elapsed_nsec = now - m_start;
124ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        const char *unit = NULL;
125ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        float elapsed_value;
126ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (elapsed_nsec < 1000)
127ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
128ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            unit = "ns";
129ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            elapsed_value = (float)elapsed_nsec;
130ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
131ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        else if (elapsed_nsec < 1000000)
132ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
133ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            unit = "us";
134ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            elapsed_value = (float)elapsed_nsec/1000.0f;
135ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
136ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        else if (elapsed_nsec < 1000000000)
137ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
138ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            unit = "ms";
139ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            elapsed_value = (float)elapsed_nsec/1000000.0f;
140ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
141ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        else
142ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
143ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            unit = "sec";
144ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            elapsed_value = (float)elapsed_nsec/1000000000.0f;
145ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
146ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        int result = printf ("%3.2f %s: ", elapsed_value, unit);
147ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        va_list args;
148ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        va_start (args, format);
149ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        result += vprintf (format, args);
150ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        va_end (args);
151ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return result;
152ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
153ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonprotected:
154ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    TimeValue m_start;
155ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton};
156ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} // namespace lldb_private
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif  // #if defined(__cplusplus)
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif // #ifndef liblldb_Timer_h_
161