]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/stat_t.hh
pkcs11signers: Use emplace_back for attributes
[thirdparty/pdns.git] / pdns / stat_t.hh
CommitLineData
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
29namespace 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 stat_t_trait(const base_t x) {
39 new(&counter) atomic_t(x);
40 }
41 ~stat_t_trait() {
42 reinterpret_cast<atomic_t *>(&counter)->~atomic_t();
43 }
44 stat_t_trait(const stat_t_trait&) = delete;
45 base_t operator++(int) {
46 return (*reinterpret_cast<atomic_t *>(&counter))++;
47 }
48 base_t operator++() {
49 return ++(*reinterpret_cast<atomic_t *>(&counter));
50 }
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 operator base_t() const {
70 return reinterpret_cast<const atomic_t *>(&counter)->load();
71 }
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}
12b9a1f0
RG
81#else
82namespace 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