MicroLogger/include/logger.hh
Artur Mukhamadiev 4c008aa77c memory_orders on load operations
:Release Notes:
removed jthread, either way explicit join
additional bench test (separate mutex and unordered map)

:Detailed Notes:
-

:Testing Performed:
just tests/bench run - output is correct, no data races detected
(-fsanitize=thread)

:QA Notes:
-

:Issues Addressed:
-
2025-06-23 15:17:49 +03:00

61 lines
1.6 KiB
C++

#pragma once
#include <atomic>
#include <iostream>
#include <memory>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <variant>
#include <vector>
namespace vptyp {
static constexpr std::string_view configErrorMsg =
"Bruh, incorrect configuration";
class Logger {
// helper class for handling worker thread
class Worker;
using map_type =
std::unordered_map<std::string, std::variant<int64_t, double>>;
public:
virtual ~Logger();
Logger();
explicit Logger(std::ostream& out);
Logger(Logger&) = delete;
Logger(Logger&&) = delete;
Logger& operator=(Logger&) = delete;
Logger& operator=(Logger&&) = delete;
/// @return success or not (already configured)
bool configure(const std::vector<std::string>& d);
template <typename Metric,
typename = std::enable_if_t<std::is_arithmetic_v<Metric>>>
void add(const std::string& field, Metric metric) {
auto locked = active.load(std::memory_order_acquire);
// auto locked = active;
auto it = locked->find(field);
if (it == locked->end()) {
throw configErrorMsg; // additional 30ns on bench ?
}
it->second = metric;
}
bool isConfigured() { return configured == CONFIGURED; }
private:
friend Worker;
enum Configuration { NOT_CONFIGURED, CONFIG_IN_PROGRESS, CONFIGURED };
std::atomic<int> configured{NOT_CONFIGURED};
std::unique_ptr<Worker> worker;
std::shared_ptr<map_type> m1, m2;
std::atomic<std::shared_ptr<map_type>> active; // impl may use mutex!
// std::shared_ptr<map_type> active; // data race without atomic on swap
// operation
};
} // namespace vptyp