64 lines
1.9 KiB
C++
64 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include "ConflictSet.h"
|
|
#include "Internal.h"
|
|
|
|
#include <assert.h>
|
|
#include <atomic>
|
|
#include <tuple>
|
|
|
|
struct Metric {
|
|
Metric *prev;
|
|
const char *name;
|
|
const char *help;
|
|
weaselab::ConflictSet::MetricsV1::Type type;
|
|
std::atomic<int64_t> value;
|
|
|
|
protected:
|
|
Metric(Metric *&metricList, int &metricsCount, const char *name,
|
|
const char *help, weaselab::ConflictSet::MetricsV1::Type type)
|
|
: prev(std::exchange(metricList, this)), name(name), help(help),
|
|
type(type), value(0) {
|
|
++metricsCount;
|
|
}
|
|
};
|
|
|
|
struct Gauge : private Metric {
|
|
Gauge(Metric *&metricList, int &metricsCount, const char *name,
|
|
const char *help)
|
|
: Metric(metricList, metricsCount, name, help,
|
|
weaselab::ConflictSet::MetricsV1::Gauge) {}
|
|
|
|
void set(int64_t value) {
|
|
this->value.store(value, std::memory_order_relaxed);
|
|
}
|
|
};
|
|
|
|
struct Counter : private Metric {
|
|
Counter(Metric *&metricList, int &metricsCount, const char *name,
|
|
const char *help)
|
|
: Metric(metricList, metricsCount, name, help,
|
|
weaselab::ConflictSet::MetricsV1::Counter) {}
|
|
// Expensive. Accumulate locally and then call add instead of repeatedly
|
|
// calling add.
|
|
void add(int64_t value) {
|
|
assert(value >= 0);
|
|
static_assert(std::atomic<int64_t>::is_always_lock_free);
|
|
this->value.fetch_add(value, std::memory_order_relaxed);
|
|
}
|
|
};
|
|
|
|
inline weaselab::ConflictSet::MetricsV1 *initMetrics(Metric *metricsList,
|
|
int metricsCount) {
|
|
weaselab::ConflictSet::MetricsV1 *metrics =
|
|
(weaselab::ConflictSet::MetricsV1 *)safe_malloc(metricsCount *
|
|
sizeof(metrics[0]));
|
|
for (auto [i, m] = std::make_tuple(metricsCount - 1, metricsList); i >= 0;
|
|
--i, m = m->prev) {
|
|
metrics[i].name = m->name;
|
|
metrics[i].help = m->help;
|
|
metrics[i].p = m;
|
|
metrics[i].type = m->type;
|
|
}
|
|
return metrics;
|
|
} |