From: Otto Moerbeek Date: Wed, 9 Sep 2020 12:34:51 +0000 (+0200) Subject: Use atomics aligned to CPU_LEVEL1_DCACHE_LINESIZE for stats X-Git-Tag: dnsdist-1.6.0-alpha1~15^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d06a9b484a438b9c1adc97ac27c684f06db90687;p=thirdparty%2Fpdns.git Use atomics aligned to CPU_LEVEL1_DCACHE_LINESIZE for stats --- diff --git a/pdns/dnsdist-snmp.cc b/pdns/dnsdist-snmp.cc index 8d776836ac..53ac8051bd 100644 --- a/pdns/dnsdist-snmp.cc +++ b/pdns/dnsdist-snmp.cc @@ -87,7 +87,7 @@ static int handleCounter64Stats(netsnmp_mib_handler* handler, return SNMP_ERR_GENERR; } -static void registerCounter64Stat(const char* name, const oid statOID[], size_t statOIDLength, std::atomic* ptr) +static void registerCounter64Stat(const char* name, const oid statOID[], size_t statOIDLength, DNSDistStats::stat_t* ptr) { if (statOIDLength != OID_LENGTH(queriesOID)) { errlog("Invalid OID for SNMP Counter64 statistic %s", name); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 56cbcceefa..3ac73f9ac4 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -299,7 +299,41 @@ extern uint64_t getLatencyCount(const std::string&); struct DNSDistStats { - using stat_t=std::atomic; // aww yiss ;-) +#define CPU_LEVEL1_DCACHE_LINESIZE 64 // Until we know better via configure/getconf + + class stat_t { + public: + typedef uint64_t base_t; + typedef std::atomic atomic_t; + stat_t() : stat_t(0) { + } + stat_t(const base_t x) { + new(&counter) atomic_t(x); + } + ~stat_t() { + reinterpret_cast(&counter)->~atomic_t(); + } + stat_t(const stat_t&) = delete; + base_t operator++(int) { + return (*reinterpret_cast(&counter))++; + } + base_t operator++() { + return ++(*reinterpret_cast(&counter)); + } + base_t operator+=(const stat_t& v) { + return (*reinterpret_cast(&counter)) += *reinterpret_cast(&v.counter); + } + base_t load() const { + return reinterpret_cast(&counter)->load(); + } + operator base_t() const { + return reinterpret_cast(&counter)->load(); + } + //const atomic_t& operator()() { return *reinterpret_cast(&counter); } + private: + typename std::aligned_storage::type counter; + }; + stat_t responses{0}; stat_t servfailResponses{0}; stat_t queries{0};