13 ret.time = _time.exchange(0);
14 ret.count = _count.exchange(0);
18 std::shared_ptr<Profiler> Profiler::instance() {
19 static std::shared_ptr<Profiler> instance = std::make_shared<Profiler>();
23 std::shared_ptr<ProfilerTrack>
24 Profiler::track(
const std::shared_ptr<ProfilerTrack> &track) {
26 std::unique_lock<std::mutex> lock(_mutex);
27 _tracks.emplace_back(track);
32 std::vector<std::shared_ptr<ProfilerTrack>> Profiler::tracks()
const {
33 std::unique_lock<std::mutex> lock(_mutex);
34 std::vector<std::shared_ptr<ProfilerTrack>> ret;
35 for (
auto it = _tracks.begin(); it != _tracks.end();) {
36 if (
auto ptr = it->lock()) {
40 it = _tracks.erase(it);
43 return std::move(ret);
46 ProfilerTrack::ProfilerTrack(
const std::string &name) : _name(name) {
50 ProfilerTrack::~ProfilerTrack() {}
52 ProfilerThread::ProfilerThread(
const std::shared_ptr<Profiler> &profiler) {
53 _thread = std::thread([
this, profiler]() {
54 auto timeout = std::chrono::steady_clock::now();
56 std::vector<std::shared_ptr<ProfilerTrack>> tracks;
58 std::unique_lock<std::mutex> lock(_mutex);
63 if (std::chrono::steady_clock::now() >= timeout) {
66 _condition.wait_until(lock, timeout);
68 tracks = profiler->tracks();
70 std::vector<std::pair<ProfilerData, std::shared_ptr<ProfilerTrack>>> data;
71 for (
auto &t : tracks) {
72 data.emplace_back(t->swap(), t);
75 data.begin(), data.end(),
76 [](
const std::pair<ProfilerData, std::shared_ptr<ProfilerTrack>> &a,
77 const std::pair<ProfilerData, std::shared_ptr<ProfilerTrack>> &b) {
78 return a.first.time > b.first.time;
80 std::stringstream stream;
81 stream <<
"profiler\n";
82 for (
auto &row : data) {
83 if (row.first.count > 0) {
84 stream << row.first.time <<
" " << row.first.count <<
" " 85 << row.second->name() <<
"\n";
89 LOG_DEBUG(stream.str());
90 timeout = std::max(timeout + std::chrono::seconds(5),
91 std::chrono::steady_clock::now());
96 ProfilerThread::~ProfilerThread() {
98 std::unique_lock<std::mutex> lock(_mutex);
100 _condition.notify_all();