using namespace ::boost::multi_index;
#include "dns.hh"
+#include <atomic>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
return true;
}
-// lifted from boost, with thanks
-class AtomicCounter
-{
-public:
- typedef unsigned long native_t;
- explicit AtomicCounter( native_t v = 0) : value_( v ) {}
-
- native_t operator++()
- {
- return atomic_exchange_and_add( &value_, +1 ) + 1;
- }
-
- native_t operator++(int)
- {
- return atomic_exchange_and_add( &value_, +1 );
- }
-
- native_t operator+=(native_t val)
- {
- return atomic_exchange_and_add( &value_, val );
- }
-
- native_t operator-=(native_t val)
- {
- return atomic_exchange_and_add( &value_, -val );
- }
- native_t operator--()
- {
- return atomic_exchange_and_add( &value_, -1 ) - 1;
- }
-
- operator native_t() const
- {
- return atomic_exchange_and_add( &value_, 0);
- }
-
- AtomicCounter(AtomicCounter const &rhs) : value_(rhs)
- {
- }
-
-private:
- mutable native_t value_;
-
- static native_t atomic_exchange_and_add( native_t * pw, native_t dv )
- {
- return __sync_fetch_and_add(pw, dv);
- }
-};
+typedef std::atomic<unsigned long> AtomicCounter ;
-// FIXME400 this should probably go?
+// FIXME400 this should probably go?
struct CIStringCompare: public std::binary_function<string, string, bool>
{
bool operator()(const string& a, const string& b) const
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002 - 2014 PowerDNS.COM BV
+ Copyright (C) 2002 - 2016 PowerDNS.COM BV
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
if(d_ttl<0)
getTTLS();
- if(!((++d_ops) % 300000)) {
- cleanup();
- }
+ cleanupIfNeeded();
if(d_doRecursion && p->d.rd) { // wants recursion
if(!d_recursivettl) {
void PacketCache::insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const string& value, unsigned int ttl, int zoneID,
bool meritsRecursion, unsigned int maxReplyLen, bool dnssecOk, bool EDNS)
{
- if(!((++d_ops) % 300000)) {
- cleanup();
- }
+ cleanupIfNeeded();
if(!ttl)
return;
void PacketCache::insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const vector<DNSResourceRecord>& value, unsigned int ttl, int zoneID)
{
- if(!((++d_ops) % 300000)) {
- cleanup();
- }
+ cleanupIfNeeded();
if(!ttl)
return;
delcount+=mc.d_map.size();
mc.d_map.clear();
}
- *d_statnumentries=AtomicCounter(0);
+ d_statnumentries->store(0);
return delcount;
}
if(d_ttl<0)
getTTLS();
- if(!((++d_ops) % 300000)) {
- cleanup();
- }
+ cleanupIfNeeded();
auto& mc=getMap(qname);
/** readlock for figuring out which iterators to delete, upgrade to writelock when actually cleaning */
void PacketCache::cleanup()
{
- *d_statnumentries=AtomicCounter(0);
+ d_statnumentries->store(0);
for(auto& mc : d_maps) {
ReadLock l(&mc.d_mut);
unsigned int maxCached=::arg().asNum("max-cache-entries");
unsigned int toTrim=0;
- AtomicCounter::native_t cacheSize=*d_statnumentries;
+ unsigned long cacheSize=*d_statnumentries;
if(maxCached && cacheSize > maxCached) {
toTrim = cacheSize - maxCached;
// if(totErased)
// cerr<<"erased: "<<totErased<<endl;
- *d_statnumentries=AtomicCounter(0);
+ d_statnumentries->store(0);
for(auto& mc : d_maps) {
ReadLock l(&mc.d_mut);
*d_statnumentries+=mc.d_map.size();
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002 - 2011 PowerDNS.COM BV
+ Copyright (C) 2002 - 2016 PowerDNS.COM BV
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
int size(); //!< number of entries in the cache
+ void cleanupIfNeeded()
+ {
+ if(!(++d_ops % 300000))
+ cleanup();
+ }
void cleanup(); //!< force the cache to preen itself from expired packets
int purge();
int purge(const std::string& match); // could be $ terminated. Is not a dnsname!
time_t last_carbon=0;
time_t carbonInterval=::arg().asNum("carbon-interval");
- counter=AtomicCounter(0); // used to periodically execute certain tasks
+ counter.store(0); // used to periodically execute certain tasks
for(;;) {
while(MT->schedule(&g_now)); // MTasker letting the mthreads do their thing
#include "dnsparser.hh"
-ResponseStats::ResponseStats()
+ResponseStats::ResponseStats() : d_qtypecounters(65536)
{
- d_qtypecounters.resize(std::numeric_limits<uint16_t>::max()+1);
d_sizecounters.push_back(make_pair(20,0));
d_sizecounters.push_back(make_pair(40,0));
d_sizecounters.push_back(make_pair(60,0));
}
-void StatBag::set(const string &key, AtomicCounter::native_t value)
+void StatBag::set(const string &key, unsigned long value)
{
exists(key);
- *d_stats[key]=AtomicCounter(value);
+ d_stats[key]->store(value);
}
-AtomicCounter::native_t StatBag::read(const string &key)
+unsigned long StatBag::read(const string &key)
{
exists(key);
funcstats_t::const_iterator iter = d_funcstats.find(key);
return *d_stats[key];
}
-AtomicCounter::native_t StatBag::readZero(const string &key)
+unsigned long StatBag::readZero(const string &key)
{
exists(key);
- AtomicCounter::native_t tmp=*d_stats[key];
+ unsigned long tmp=*d_stats[key];
d_stats[key]=0;
return tmp;
}
void exists(const string &key); //!< call this function to throw an exception in case a key does not exist
inline void deposit(const string &key, int value); //!< increment the statistics behind this key by value amount
inline void inc(const string &key); //!< increase this key's value by one
- void set(const string &key, AtomicCounter::native_t value); //!< set this key's value
- AtomicCounter::native_t read(const string &key); //!< read the value behind this key
- AtomicCounter::native_t readZero(const string &key); //!< read the value behind this key, and zero it afterwards
+ void set(const string &key, unsigned long value); //!< set this key's value
+ unsigned long read(const string &key); //!< read the value behind this key
+ unsigned long readZero(const string &key); //!< read the value behind this key, and zero it afterwards
AtomicCounter *getPointer(const string &key); //!< get a direct pointer to the value behind a key. Use this for high performance increments
string getValueStr(const string &key); //!< read a value behind a key, and return it as a string
string getValueStrZero(const string &key); //!< read a value behind a key, and return it as a string, and zero afterwards