181ad6265SDimitry Andric //===-- TaskTimer.h ---------------------------------------------*- C++ -*-===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric 
981ad6265SDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TASKTIMER_H
1081ad6265SDimitry Andric #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TASKTIMER_H
1181ad6265SDimitry Andric 
1281ad6265SDimitry Andric #include "lldb/lldb-types.h"
1381ad6265SDimitry Andric #include "llvm/ADT/DenseMap.h"
1481ad6265SDimitry Andric #include "llvm/ADT/StringRef.h"
1581ad6265SDimitry Andric #include <chrono>
1681ad6265SDimitry Andric #include <functional>
1781ad6265SDimitry Andric #include <unordered_map>
1881ad6265SDimitry Andric 
1981ad6265SDimitry Andric namespace lldb_private {
2081ad6265SDimitry Andric namespace trace_intel_pt {
2181ad6265SDimitry Andric 
2281ad6265SDimitry Andric /// Class used to track the duration of long running tasks related to a single
2381ad6265SDimitry Andric /// scope for reporting.
2481ad6265SDimitry Andric class ScopedTaskTimer {
2581ad6265SDimitry Andric public:
2681ad6265SDimitry Andric   /// Execute the given \p task and record its duration.
2781ad6265SDimitry Andric   ///
2881ad6265SDimitry Andric   /// \param[in] name
2981ad6265SDimitry Andric   ///     The name used to identify this task for reporting.
3081ad6265SDimitry Andric   ///
3181ad6265SDimitry Andric   /// \param[in] task
3281ad6265SDimitry Andric   ///     The task function.
3381ad6265SDimitry Andric   ///
3481ad6265SDimitry Andric   /// \return
3581ad6265SDimitry Andric   ///     The return value of the task.
TimeTask(llvm::StringRef name,C task)36*753f127fSDimitry Andric   template <typename C> auto TimeTask(llvm::StringRef name, C task) {
3781ad6265SDimitry Andric     auto start = std::chrono::steady_clock::now();
38*753f127fSDimitry Andric     auto result = task();
3981ad6265SDimitry Andric     auto end = std::chrono::steady_clock::now();
4081ad6265SDimitry Andric     std::chrono::milliseconds duration =
4181ad6265SDimitry Andric         std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
4281ad6265SDimitry Andric     m_timed_tasks.insert({name.str(), duration});
4381ad6265SDimitry Andric     return result;
4481ad6265SDimitry Andric   }
4581ad6265SDimitry Andric 
4681ad6265SDimitry Andric   /// Executive the given \p callback on each recorded task.
4781ad6265SDimitry Andric   ///
4881ad6265SDimitry Andric   /// \param[in] callback
4981ad6265SDimitry Andric   ///     The first parameter of the callback is the name of the recorded task,
5081ad6265SDimitry Andric   ///     and the second parameter is the duration of that task.
5181ad6265SDimitry Andric   void ForEachTimedTask(std::function<void(const std::string &name,
5281ad6265SDimitry Andric                                            std::chrono::milliseconds duration)>
5381ad6265SDimitry Andric                             callback);
5481ad6265SDimitry Andric 
5581ad6265SDimitry Andric private:
5681ad6265SDimitry Andric   std::unordered_map<std::string, std::chrono::milliseconds> m_timed_tasks;
5781ad6265SDimitry Andric };
5881ad6265SDimitry Andric 
5981ad6265SDimitry Andric /// Class used to track the duration of long running tasks for reporting.
6081ad6265SDimitry Andric class TaskTimer {
6181ad6265SDimitry Andric public:
6281ad6265SDimitry Andric   /// \return
6381ad6265SDimitry Andric   ///     The timer object for the given thread.
6481ad6265SDimitry Andric   ScopedTaskTimer &ForThread(lldb::tid_t tid);
6581ad6265SDimitry Andric 
6681ad6265SDimitry Andric   /// \return
6781ad6265SDimitry Andric   ///     The timer object for global tasks.
6881ad6265SDimitry Andric   ScopedTaskTimer &ForGlobal();
6981ad6265SDimitry Andric 
7081ad6265SDimitry Andric private:
7181ad6265SDimitry Andric   llvm::DenseMap<lldb::tid_t, ScopedTaskTimer> m_thread_timers;
7281ad6265SDimitry Andric   ScopedTaskTimer m_global_timer;
7381ad6265SDimitry Andric };
7481ad6265SDimitry Andric 
7581ad6265SDimitry Andric } // namespace trace_intel_pt
7681ad6265SDimitry Andric } // namespace lldb_private
7781ad6265SDimitry Andric 
7881ad6265SDimitry Andric #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TASKTIMER_H
79