]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Use atomics aligned to CPU_LEVEL1_DCACHE_LINESIZE for stats
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 9 Sep 2020 12:34:51 +0000 (14:34 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 21 Jan 2021 13:48:24 +0000 (14:48 +0100)
pdns/dnsdist-snmp.cc
pdns/dnsdist.hh

index 8d776836ac4dd4a99d3b373d56b48a722579ab90..53ac8051bdeaff1c5f5d2cb86792634b1f2e0684 100644 (file)
@@ -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<uint64_t>* 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);
index 56cbcceefa0d8d79404ec6eeac4d9b7f3fbea17f..3ac73f9ac4a6446dd5c6b69a750c066893c765c0 100644 (file)
@@ -299,7 +299,41 @@ extern uint64_t getLatencyCount(const std::string&);
 
 struct DNSDistStats
 {
-  using stat_t=std::atomic<uint64_t>; // 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<base_t> atomic_t;
+    stat_t() : stat_t(0) {
+    }
+    stat_t(const base_t x) {
+      new(&counter) atomic_t(x);
+    }
+    ~stat_t() {
+      reinterpret_cast<atomic_t *>(&counter)->~atomic_t();
+    }
+    stat_t(const stat_t&) = delete;
+    base_t operator++(int) {
+      return (*reinterpret_cast<atomic_t *>(&counter))++;
+    }
+    base_t operator++() {
+      return ++(*reinterpret_cast<atomic_t *>(&counter));
+    }
+    base_t operator+=(const stat_t& v) {
+      return (*reinterpret_cast<atomic_t *>(&counter)) += *reinterpret_cast<const atomic_t *>(&v.counter);
+    }
+    base_t load() const {
+      return reinterpret_cast<const atomic_t *>(&counter)->load();
+    }
+    operator base_t() const {
+      return reinterpret_cast<const atomic_t *>(&counter)->load();
+    }
+    //const atomic_t& operator()() { return *reinterpret_cast<const atomic_t*>(&counter); }
+  private:
+    typename std::aligned_storage<sizeof(base_t), CPU_LEVEL1_DCACHE_LINESIZE>::type counter;
+  };
+
   stat_t responses{0};
   stat_t servfailResponses{0};
   stat_t queries{0};