2022-12-23 13:50:27 -05:00
|
|
|
/*
|
|
|
|
* Created by Brett on 23/12/22.
|
|
|
|
* Licensed under GNU General Public License V3.0
|
|
|
|
* See LICENSE file for license detail
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef BLT_PROFILER_H
|
|
|
|
#define BLT_PROFILER_H
|
|
|
|
|
2022-12-25 23:19:44 -05:00
|
|
|
#include <string>
|
|
|
|
#include <string_view>
|
2022-12-29 00:56:37 -05:00
|
|
|
#include <mutex>
|
2023-01-04 14:35:57 -05:00
|
|
|
#include <queue>
|
2023-01-05 01:52:56 -05:00
|
|
|
#include <blt/std/time.h>
|
2022-12-23 13:50:27 -05:00
|
|
|
|
2022-12-26 00:31:00 -05:00
|
|
|
namespace BLT {
|
|
|
|
struct CapturePoint {
|
2023-01-05 01:52:56 -05:00
|
|
|
std::string_view name;
|
2022-12-26 00:31:00 -05:00
|
|
|
long point;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CaptureInterval {
|
2023-01-05 01:52:56 -05:00
|
|
|
long start;
|
|
|
|
long end;
|
2022-12-26 00:31:00 -05:00
|
|
|
};
|
|
|
|
|
2023-01-05 01:52:56 -05:00
|
|
|
/**
|
|
|
|
* @tparam HASHMAP_TYPE
|
|
|
|
*/
|
|
|
|
template <template<typename, typename> class HASHMAP_TYPE>
|
|
|
|
class profile {
|
2022-12-26 00:31:00 -05:00
|
|
|
private:
|
2023-01-05 01:52:56 -05:00
|
|
|
// profiling intervals.
|
|
|
|
HASHMAP_TYPE<std::string_view, CaptureInterval> intervals{};
|
|
|
|
|
|
|
|
// profiling points
|
|
|
|
std::vector<std::queue<CapturePoint>> cyclicPointsHistory{};
|
2023-01-04 14:35:57 -05:00
|
|
|
std::queue<CapturePoint> points{};
|
|
|
|
std::queue<CapturePoint> cyclicPoints{};
|
2022-12-29 00:56:37 -05:00
|
|
|
|
|
|
|
std::mutex timerLock{};
|
2022-12-26 23:36:34 -05:00
|
|
|
public:
|
2023-01-05 01:52:56 -05:00
|
|
|
profile() = default;
|
|
|
|
void finishCycle() {
|
|
|
|
cyclicPointsHistory.push_back(cyclicPoints);
|
|
|
|
// im not sure if this is the correct way to clear a queue, there is no function to do so.
|
|
|
|
cyclicPoints = {};
|
|
|
|
}
|
|
|
|
void startInterval(const std::string_view& name) {
|
|
|
|
std::scoped_lock lock(timerLock);
|
|
|
|
CaptureInterval interval{};
|
|
|
|
interval.start = System::getCurrentTimeNanoseconds();
|
|
|
|
intervals[name] = interval;
|
|
|
|
}
|
|
|
|
void endInterval(const std::string_view& name) {
|
|
|
|
std::scoped_lock lock(timerLock);
|
|
|
|
intervals[name].end = System::getCurrentTimeNanoseconds();
|
|
|
|
}
|
2023-01-04 14:35:57 -05:00
|
|
|
/**
|
2023-01-05 01:52:56 -05:00
|
|
|
* Records the current time for the purpose of reconstructing the execution time between points, in order to find the most common cause for performance issues.
|
|
|
|
* @param name a common name for the point which you are trying to profile. This name should be meaningful as it will be displayed in the output.
|
2023-01-04 14:35:57 -05:00
|
|
|
*/
|
2023-01-05 01:52:56 -05:00
|
|
|
void profilerPoint(const std::string_view& name) {
|
|
|
|
points.push(CapturePoint{name, System::getCurrentTimeNanoseconds()});
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Records the current time for the purpose of reconstructing the execution time between points, in order to find the most common cause for performance issues.
|
|
|
|
* Uses a separate tracking device that will be reset when finishCycle(); is called.
|
|
|
|
* @param name a common name for the point which you are trying to profile. This name should be meaningful as it will be displayed in the output.
|
|
|
|
*/
|
|
|
|
void profilerPointCyclic(const std::string_view& name) {
|
|
|
|
cyclicPoints.push(CapturePoint{name, System::getCurrentTimeNanoseconds()});
|
|
|
|
}
|
2022-12-26 00:31:00 -05:00
|
|
|
};
|
|
|
|
}
|
2022-12-23 13:50:27 -05:00
|
|
|
|
|
|
|
#endif //BLT_PROFILER_H
|