HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
counters.hpp
1// Copyright Take Vos 2019-2020.
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 "wfree_unordered_map.hpp"
11#include "architecture.hpp"
12#include "fixed_string.hpp"
13#include "statistics.hpp"
14#include <span>
15#include <typeinfo>
16#include <typeindex>
17#include <string>
18
19namespace tt {
20
21constexpr int MAX_NR_COUNTERS = 1024;
22
24 std::atomic<int64_t> *counter;
25 int64_t previous_value;
26};
27
29
30// To reduce number of executed instruction this is a global variable.
31// The wfree_unordered_map does not need to be initialized.
32inline counter_map_type counter_map;
33
34template<basic_fixed_string Tag>
36 // Make sure non of the counters are false sharing cache-lines.
37 alignas(hardware_destructive_interference_size) inline static std::atomic<int64_t> counter = 0;
38
39 tt_no_inline void add_to_map() const noexcept
40 {
41 counter_map.insert(Tag, counter_map_value_type{&counter, 0});
42 statistics_start();
43 }
44
45 int64_t increment() const noexcept
46 {
47 ttlet value = counter.fetch_add(1, std::memory_order::relaxed);
48
49 if (value == 0) {
50 [[unlikely]] add_to_map();
51 }
52
53 return value + 1;
54 }
55
56 [[nodiscard]] int64_t read() const noexcept
57 {
58 return counter.load(std::memory_order::relaxed);
59 }
60
61 // Don't implement readAndSet, a set to zero would cause the counters to be reinserted.
62};
63
64template<basic_fixed_string Tag>
65inline int64_t increment_counter() noexcept
66{
67 return counter_functor<Tag>{}.increment();
68}
69
70template<basic_fixed_string Tag>
71[[nodiscard]] inline int64_t read_counter() noexcept
72{
73 return counter_functor<Tag>{}.read();
74}
75
79[[nodiscard]] inline std::pair<int64_t, int64_t> read_counter(std::string tag) noexcept
80{
81 auto &item = counter_map[tag];
82
83 ttlet *const count_ptr = item.counter;
84 ttlet count = count_ptr != nullptr ? item.counter->load(std::memory_order::relaxed) : 0;
85 ttlet count_since_last_read = count - item.previous_value;
86 item.previous_value = count;
87 return {count, count_since_last_read};
88}
89
90} // namespace tt
Definition counters.hpp:23
Definition counters.hpp:35
Definition wfree_unordered_map.hpp:56
T count(T... args)
T fetch_add(T... args)
T load(T... args)