Coverage Report

Created: 2023-03-26 07:18

/src/pdns/pdns/stat_t.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * This file is part of PowerDNS or dnsdist.
3
 * Copyright -- PowerDNS.COM B.V. and its contributors
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of version 2 of the GNU General Public License as
7
 * published by the Free Software Foundation.
8
 *
9
 * In addition, for the avoidance of any doubt, permission is granted to
10
 * link this program with OpenSSL and to (re)distribute the binaries
11
 * produced as the result of such linking.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22
#pragma once
23
24
#include <atomic>
25
26
#ifndef DISABLE_FALSE_SHARING_PADDING
27
#define CPU_LEVEL1_DCACHE_LINESIZE 64 // Until we know better via configure/getconf
28
29
namespace pdns {
30
  template <typename T>
31
  class stat_t_trait {
32
  public:
33
    typedef T base_t;
34
    typedef std::atomic<base_t> atomic_t;
35
36
    stat_t_trait() : stat_t_trait(base_t(0)) {
37
    }
38
18.8k
    stat_t_trait(const base_t x) {
39
18.8k
      new(&counter) atomic_t(x);
40
18.8k
    }
41
18.8k
    ~stat_t_trait() {
42
18.8k
      reinterpret_cast<atomic_t *>(&counter)->~atomic_t();
43
18.8k
    }
44
    stat_t_trait(const stat_t_trait&) = delete;
45
    base_t operator++(int) {
46
      return (*reinterpret_cast<atomic_t *>(&counter))++;
47
    }
48
0
    base_t operator++() {
49
0
      return ++(*reinterpret_cast<atomic_t *>(&counter));
50
0
    }
51
    base_t operator--(int) {
52
      return (*reinterpret_cast<atomic_t *>(&counter))--;
53
    }
54
    base_t operator--() {
55
      return --(*reinterpret_cast<atomic_t *>(&counter));
56
    }
57
    base_t operator+=(const stat_t_trait& v) {
58
      return *reinterpret_cast<atomic_t *>(&counter) += *reinterpret_cast<const atomic_t *>(&v.counter);
59
    }
60
    base_t operator-=(const stat_t_trait& v) {
61
      return *reinterpret_cast<atomic_t *>(&counter) -= *reinterpret_cast<const atomic_t *>(&v.counter);
62
    }
63
    base_t load() const {
64
      return reinterpret_cast<const atomic_t *>(&counter)->load();
65
    }
66
    void store(base_t v) {
67
      reinterpret_cast<atomic_t *>(&counter)->store(v);
68
    }
69
0
    operator base_t() const {
70
0
      return reinterpret_cast<const atomic_t *>(&counter)->load();
71
0
    }
Unexecuted instantiation: pdns::stat_t_trait<unsigned long>::operator unsigned long() const
Unexecuted instantiation: pdns::stat_t_trait<double>::operator double() const
72
73
  private:
74
    typename std::aligned_storage<sizeof(base_t), CPU_LEVEL1_DCACHE_LINESIZE>::type counter;
75
  };
76
77
  typedef stat_t_trait<uint64_t> stat_t;
78
  typedef stat_t_trait<uint32_t> stat32_t;
79
  typedef stat_t_trait<uint16_t> stat16_t;
80
}
81
#else
82
namespace pdns {
83
  using stat_t = std::atomic<uint64_t>;
84
  using stat32_t = std::atomic<uint32_t>;
85
  using stat16_t = std::atomic<uint16_t>;
86
  template <class T>
87
  using stat_t_trait = std::atomic<T>;
88
}
89
#endif