]>
Commit | Line | Data |
---|---|---|
070fa3bf OM |
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 | ||
83b9df32 O |
24 | #include <atomic> |
25 | ||
12b9a1f0 | 26 | #ifndef DISABLE_FALSE_SHARING_PADDING |
070fa3bf OM |
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: | |
eca5db9f OM |
33 | using base_t = T; |
34 | using atomic_t = std::atomic<base_t>; | |
070fa3bf OM |
35 | |
36 | stat_t_trait() : stat_t_trait(base_t(0)) { | |
37 | } | |
eca5db9f OM |
38 | stat_t_trait(const base_t value) |
39 | { | |
40 | new(&counter) atomic_t(value); | |
41 | } | |
42 | stat_t_trait& operator=(const base_t& value) { | |
43 | ref().store(value); | |
44 | return *this; | |
070fa3bf OM |
45 | } |
46 | ~stat_t_trait() { | |
eca5db9f | 47 | ref().~atomic_t(); |
070fa3bf | 48 | } |
eca5db9f OM |
49 | stat_t_trait(stat_t_trait&&) = delete; |
50 | stat_t_trait& operator=(const stat_t_trait&) = delete; | |
51 | stat_t_trait& operator=(stat_t_trait&&) = delete; | |
070fa3bf OM |
52 | stat_t_trait(const stat_t_trait&) = delete; |
53 | base_t operator++(int) { | |
eca5db9f | 54 | return ref()++; |
070fa3bf OM |
55 | } |
56 | base_t operator++() { | |
eca5db9f | 57 | return ++(ref()); |
070fa3bf OM |
58 | } |
59 | base_t operator--(int) { | |
eca5db9f | 60 | return ref()--; |
070fa3bf OM |
61 | } |
62 | base_t operator--() { | |
eca5db9f | 63 | return --(ref()); |
070fa3bf | 64 | } |
4c62c610 OM |
65 | base_t operator+=(base_t arg) { |
66 | return ref() += arg; | |
070fa3bf | 67 | } |
4c62c610 OM |
68 | base_t operator-=(base_t arg) { |
69 | return ref() -= arg; | |
070fa3bf OM |
70 | } |
71 | base_t load() const { | |
eca5db9f | 72 | return ref().load(); |
070fa3bf | 73 | } |
eca5db9f OM |
74 | void store(base_t value) { |
75 | ref().store(value); | |
070fa3bf OM |
76 | } |
77 | operator base_t() const { | |
eca5db9f | 78 | return ref().load(); |
070fa3bf OM |
79 | } |
80 | ||
81 | private: | |
eca5db9f OM |
82 | atomic_t& ref() { |
83 | return *reinterpret_cast<atomic_t *>(&counter); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) | |
84 | } | |
85 | const atomic_t& ref() const { | |
86 | return *reinterpret_cast<const atomic_t *>(&counter); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) | |
87 | } | |
4c62c610 | 88 | typename std::aligned_storage_t<sizeof(atomic_t), CPU_LEVEL1_DCACHE_LINESIZE> counter; |
070fa3bf OM |
89 | }; |
90 | ||
eca5db9f OM |
91 | using stat_t = stat_t_trait<uint64_t>; |
92 | using stat32_t = stat_t_trait<uint32_t>; | |
93 | using stat16_t = stat_t_trait<uint16_t>; | |
070fa3bf | 94 | } |
12b9a1f0 RG |
95 | #else |
96 | namespace pdns { | |
97 | using stat_t = std::atomic<uint64_t>; | |
98 | using stat32_t = std::atomic<uint32_t>; | |
99 | using stat16_t = std::atomic<uint16_t>; | |
100 | template <class T> | |
101 | using stat_t_trait = std::atomic<T>; | |
102 | } | |
103 | #endif |