HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
counters.hpp
1// Copyright Take Vos 2019-2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
8#pragma once
9
10#include "architecture.hpp"
11#include "fixed_string.hpp"
12#include "time_stamp_count.hpp"
13#include "atomic.hpp"
14#include <span>
15#include <typeinfo>
16#include <typeindex>
17#include <string>
18#include <map>
19
20namespace tt {
21namespace detail {
22
23class counter {
24public:
25 static inline std::map<std::string, counter *> map = {};
26
27 counter(counter const &) = delete;
28 counter(counter &&) = delete;
29 counter &operator=(counter const &) = delete;
30 counter &operator=(counter &&) = delete;
31
32 constexpr counter() noexcept {}
33
34 operator uint64_t() const noexcept
35 {
36 return _total_count.load(std::memory_order::relaxed);
37 }
38
39 static void log() noexcept
40 {
41 log_header();
42 for (ttlet &[string, counter]: map) {
43 tt_axiom(counter);
44 counter->log(string);
45 }
46 }
47
48 static void log_header() noexcept;
49
52 void log(std::string const &tag) noexcept;
53
54 counter &operator++() noexcept
55 {
56 _total_count.fetch_add(1, std::memory_order::relaxed);
57 return *this;
58 }
59
60 uint64_t operator++(int) noexcept
61 {
62 return _total_count.fetch_add(1, std::memory_order::relaxed);
63 }
64
67 void add_duration(uint64_t duration) noexcept
68 {
69 _total_count.fetch_add(1, std::memory_order::relaxed);
70 fetch_max(_duration_max, duration, std::memory_order::relaxed);
71 fetch_min(_duration_min, duration, std::memory_order::relaxed);
72
73 // Combine duration with count in a single atomic.
74 tt_axiom(duration <= (std::numeric_limits<uint64_t>::max() >> 10));
75 duration <<= 16;
76 ++duration;
77 _duration_avg.fetch_add(duration, std::memory_order::relaxed);
78 }
79
80protected:
81 std::atomic<uint64_t> _total_count = 0;
82 std::atomic<uint64_t> _prev_count = 0;
83 std::atomic<uint64_t> _duration_max = 0;
85
91 std::atomic<uint64_t> _duration_avg = 0;
92};
93
94template<basic_fixed_string Tag>
95class tagged_counter : public counter {
96public:
97 tagged_counter() noexcept : counter()
98 {
99 map[std::string{Tag}] = this;
100 }
101};
102
103} // namespace detail
104
105template<basic_fixed_string Tag>
106inline detail::tagged_counter<Tag> global_counter;
107
108[[nodiscard]] inline detail::counter *get_global_counter(std::string const &name)
109{
110 ttlet it = detail::counter::map.find(name);
111 if (it == detail::counter::map.cend()) {
112 return nullptr;
113 } else {
114 tt_axiom(it->second);
115 return it->second;
116 }
117}
118
119} // namespace tt
Definition counters.hpp:23
void log(std::string const &tag) noexcept
Log the counter.
void add_duration(uint64_t duration) noexcept
Add a duration.
Definition counters.hpp:67
Definition counters.hpp:95
Definition log.hpp:113
T fetch_add(T... args)
T load(T... args)
T max(T... args)