1 | //===-- Timer.h -------------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_UTILITY_TIMER_H |
10 | #define LLDB_UTILITY_TIMER_H |
11 | |
12 | #include "lldb/lldb-defines.h" |
13 | #include "llvm/Support/Chrono.h" |
14 | #include <atomic> |
15 | #include <cstdint> |
16 | |
17 | namespace lldb_private { |
18 | class Stream; |
19 | |
20 | /// \class Timer Timer.h "lldb/Utility/Timer.h" |
21 | /// A timer class that simplifies common timing metrics. |
22 | |
23 | class Timer { |
24 | public: |
25 | class Category { |
26 | public: |
27 | explicit Category(const char *category_name); |
28 | llvm::StringRef GetName() { return m_name; } |
29 | |
30 | private: |
31 | friend class Timer; |
32 | const char *m_name; |
33 | std::atomic<uint64_t> m_nanos; |
34 | std::atomic<uint64_t> m_nanos_total; |
35 | std::atomic<uint64_t> m_count; |
36 | std::atomic<Category *> m_next; |
37 | |
38 | Category(const Category &) = delete; |
39 | const Category &operator=(const Category &) = delete; |
40 | }; |
41 | |
42 | /// Default constructor. |
43 | Timer(Category &category, const char *format, ...) |
44 | #if !defined(_MSC_VER) |
45 | // MSVC appears to have trouble recognizing the this argument in the constructor. |
46 | __attribute__((format(printf, 3, 4))) |
47 | #endif |
48 | ; |
49 | |
50 | /// Destructor |
51 | ~Timer(); |
52 | |
53 | void Dump(); |
54 | |
55 | static void SetDisplayDepth(uint32_t depth); |
56 | |
57 | static void SetQuiet(bool value); |
58 | |
59 | static void DumpCategoryTimes(Stream &s); |
60 | |
61 | static void ResetCategoryTimes(); |
62 | |
63 | protected: |
64 | using TimePoint = std::chrono::steady_clock::time_point; |
65 | void ChildDuration(TimePoint::duration dur) { m_child_duration += dur; } |
66 | |
67 | Category &m_category; |
68 | TimePoint m_total_start; |
69 | TimePoint::duration m_child_duration{0}; |
70 | |
71 | static std::atomic<bool> g_quiet; |
72 | static std::atomic<unsigned> g_display_depth; |
73 | |
74 | private: |
75 | Timer(const Timer &) = delete; |
76 | const Timer &operator=(const Timer &) = delete; |
77 | }; |
78 | |
79 | } // namespace lldb_private |
80 | |
81 | // Use a format string because LLVM_PRETTY_FUNCTION might not be a string |
82 | // literal. |
83 | #define LLDB_SCOPED_TIMER() \ |
84 | static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ |
85 | ::lldb_private::Timer _scoped_timer(_cat, "%s", LLVM_PRETTY_FUNCTION) |
86 | #define LLDB_SCOPED_TIMERF(...) \ |
87 | static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ |
88 | ::lldb_private::Timer _scoped_timer(_cat, __VA_ARGS__) |
89 | |
90 | #endif // LLDB_UTILITY_TIMER_H |
91 | |