mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 14:35:52 +00:00
Use the new uptime code. Replace slow, non-monotonic 'time(NULL)' calls
with fast, almost-always-monotonic 'upTime()' calls.
This commit is contained in:
@@ -6,11 +6,13 @@
|
|||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
|
|
||||||
|
extern int upTime();
|
||||||
|
|
||||||
template <typename c_Key> class KeyCache
|
template <typename c_Key> class KeyCache
|
||||||
{ // Maintains a cache of keys with no associated data
|
{ // Maintains a cache of keys with no associated data
|
||||||
public:
|
public:
|
||||||
typedef c_Key key_type;
|
typedef c_Key key_type;
|
||||||
typedef boost::unordered_map<key_type, time_t> map_type;
|
typedef boost::unordered_map<key_type, int> map_type;
|
||||||
typedef typename map_type::iterator map_iterator;
|
typedef typename map_type::iterator map_iterator;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -65,7 +67,7 @@ public:
|
|||||||
if (it == mCache.end())
|
if (it == mCache.end())
|
||||||
return false;
|
return false;
|
||||||
if (refresh)
|
if (refresh)
|
||||||
it->second = time(NULL);
|
it->second = upTime();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,19 +90,19 @@ public:
|
|||||||
map_iterator it = mCache.find(key);
|
map_iterator it = mCache.find(key);
|
||||||
if (it != mCache.end())
|
if (it != mCache.end())
|
||||||
{
|
{
|
||||||
it->second = time(NULL);
|
it->second = upTime();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mCache.insert(std::make_pair(key, time(NULL)));
|
mCache.insert(std::make_pair(key, upTime()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sweep()
|
void sweep()
|
||||||
{ // Remove stale entries from the cache
|
{ // Remove stale entries from the cache
|
||||||
time_t now = time(NULL);
|
int now = upTime();
|
||||||
boost::mutex::scoped_lock sl(mNCLock);
|
boost::mutex::scoped_lock sl(mNCLock);
|
||||||
|
|
||||||
time_t target;
|
int target;
|
||||||
if ((mTargetSize == 0) || (mCache.size() <= mTargetSize))
|
if ((mTargetSize == 0) || (mCache.size() <= mTargetSize))
|
||||||
target = now - mTargetAge;
|
target = now - mTargetAge;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ DECLARE_INSTANCE(LedgerAcquire);
|
|||||||
PeerSet::PeerSet(const uint256& hash, int interval) : mHash(hash), mTimerInterval(interval), mTimeouts(0),
|
PeerSet::PeerSet(const uint256& hash, int interval) : mHash(hash), mTimerInterval(interval), mTimeouts(0),
|
||||||
mComplete(false), mFailed(false), mProgress(true), mAggressive(true), mTimer(theApp->getIOService())
|
mComplete(false), mFailed(false), mProgress(true), mAggressive(true), mTimer(theApp->getIOService())
|
||||||
{
|
{
|
||||||
mLastAction = time(NULL);
|
mLastAction = upTime();
|
||||||
assert((mTimerInterval > 10) && (mTimerInterval < 30000));
|
assert((mTimerInterval > 10) && (mTimerInterval < 30000));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,7 +890,7 @@ void LedgerAcquireMaster::sweep()
|
|||||||
{
|
{
|
||||||
mRecentFailures.sweep();
|
mRecentFailures.sweep();
|
||||||
|
|
||||||
time_t now = time(NULL);
|
int now = upTime();
|
||||||
boost::mutex::scoped_lock sl(mLock);
|
boost::mutex::scoped_lock sl(mLock);
|
||||||
|
|
||||||
std::map<uint256, LedgerAcquire::pointer>::iterator it = mLedgers.begin();
|
std::map<uint256, LedgerAcquire::pointer>::iterator it = mLedgers.begin();
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ protected:
|
|||||||
uint256 mHash;
|
uint256 mHash;
|
||||||
int mTimerInterval, mTimeouts;
|
int mTimerInterval, mTimeouts;
|
||||||
bool mComplete, mFailed, mProgress, mAggressive;
|
bool mComplete, mFailed, mProgress, mAggressive;
|
||||||
time_t mLastAction;
|
int mLastAction;
|
||||||
|
|
||||||
boost::recursive_mutex mLock;
|
boost::recursive_mutex mLock;
|
||||||
boost::asio::deadline_timer mTimer;
|
boost::asio::deadline_timer mTimer;
|
||||||
@@ -53,8 +53,8 @@ public:
|
|||||||
bool isActive();
|
bool isActive();
|
||||||
void progress() { mProgress = true; mAggressive = false; }
|
void progress() { mProgress = true; mAggressive = false; }
|
||||||
bool isProgress() { return mProgress; }
|
bool isProgress() { return mProgress; }
|
||||||
void touch() { mLastAction = time(NULL); }
|
void touch() { mLastAction = upTime(); }
|
||||||
time_t getLastAction() { return mLastAction; }
|
int getLastAction() { return mLastAction; }
|
||||||
|
|
||||||
void peerHas(Peer::ref);
|
void peerHas(Peer::ref);
|
||||||
void badPeer(Peer::ref);
|
void badPeer(Peer::ref);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ int upTime()
|
|||||||
static time_t firstCall = time(NULL);
|
static time_t firstCall = time(NULL);
|
||||||
if (uptimePtr != NULL)
|
if (uptimePtr != NULL)
|
||||||
return *uptimePtr;
|
return *uptimePtr;
|
||||||
cLog(lsWARNING) << "slow uptime";
|
cLog(lsTRACE) << "Slow uptime in use";
|
||||||
return static_cast<int>(time(NULL) - firstCall);
|
return static_cast<int>(time(NULL) - firstCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ void LoadManager::setDebitLimit(int r)
|
|||||||
mDebitLimit = r;
|
mDebitLimit = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadManager::canonicalize(LoadSource& source, const time_t now) const
|
void LoadManager::canonicalize(LoadSource& source, int now) const
|
||||||
{
|
{
|
||||||
if (source.mLastUpdate != now)
|
if (source.mLastUpdate != now)
|
||||||
{
|
{
|
||||||
@@ -133,9 +133,9 @@ void LoadManager::canonicalize(LoadSource& source, const time_t now) const
|
|||||||
|
|
||||||
bool LoadManager::shouldWarn(LoadSource& source) const
|
bool LoadManager::shouldWarn(LoadSource& source) const
|
||||||
{
|
{
|
||||||
time_t now = time(NULL);
|
|
||||||
boost::mutex::scoped_lock sl(mLock);
|
boost::mutex::scoped_lock sl(mLock);
|
||||||
|
|
||||||
|
int now = upTime();
|
||||||
canonicalize(source, now);
|
canonicalize(source, now);
|
||||||
if (source.isPrivileged() || (source.mBalance < mDebitWarn) || (source.mLastWarning == now))
|
if (source.isPrivileged() || (source.mBalance < mDebitWarn) || (source.mLastWarning == now))
|
||||||
return false;
|
return false;
|
||||||
@@ -146,9 +146,9 @@ bool LoadManager::shouldWarn(LoadSource& source) const
|
|||||||
|
|
||||||
bool LoadManager::shouldCutoff(LoadSource& source) const
|
bool LoadManager::shouldCutoff(LoadSource& source) const
|
||||||
{
|
{
|
||||||
time_t now = time(NULL);
|
|
||||||
boost::mutex::scoped_lock sl(mLock);
|
boost::mutex::scoped_lock sl(mLock);
|
||||||
|
|
||||||
|
int now = upTime();
|
||||||
canonicalize(source, now);
|
canonicalize(source, now);
|
||||||
return !source.isPrivileged() && (source.mBalance < mDebitLimit);
|
return !source.isPrivileged() && (source.mBalance < mDebitLimit);
|
||||||
}
|
}
|
||||||
@@ -161,10 +161,10 @@ bool LoadManager::adjust(LoadSource& source, LoadType t) const
|
|||||||
|
|
||||||
bool LoadManager::adjust(LoadSource& source, int credits) const
|
bool LoadManager::adjust(LoadSource& source, int credits) const
|
||||||
{ // return: true = need to warn/cutoff
|
{ // return: true = need to warn/cutoff
|
||||||
time_t now = time(NULL);
|
|
||||||
boost::mutex::scoped_lock sl(mLock);
|
boost::mutex::scoped_lock sl(mLock);
|
||||||
|
|
||||||
// We do it this way in case we want to add exponential decay later
|
// We do it this way in case we want to add exponential decay later
|
||||||
|
int now = upTime();
|
||||||
canonicalize(source, now);
|
canonicalize(source, now);
|
||||||
source.mBalance += credits;
|
source.mBalance += credits;
|
||||||
if (source.mBalance > mCreditLimit)
|
if (source.mBalance > mCreditLimit)
|
||||||
|
|||||||
@@ -63,12 +63,12 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
int mBalance;
|
int mBalance;
|
||||||
int mFlags;
|
int mFlags;
|
||||||
time_t mLastUpdate;
|
int mLastUpdate;
|
||||||
time_t mLastWarning;
|
int mLastWarning;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LoadSource() : mBalance(0), mFlags(0), mLastWarning(0)
|
LoadSource() : mBalance(0), mFlags(0), mLastWarning(0)
|
||||||
{ mLastUpdate = time(NULL); }
|
{ mLastUpdate = upTime(); }
|
||||||
|
|
||||||
bool isPrivileged() const { return (mFlags & lsfPrivileged) != 0; }
|
bool isPrivileged() const { return (mFlags & lsfPrivileged) != 0; }
|
||||||
void setPrivileged() { mFlags |= lsfPrivileged; }
|
void setPrivileged() { mFlags |= lsfPrivileged; }
|
||||||
@@ -89,11 +89,14 @@ protected:
|
|||||||
int mDebitLimit; // when a source drops below this, we cut it off (should be negative)
|
int mDebitLimit; // when a source drops below this, we cut it off (should be negative)
|
||||||
|
|
||||||
bool mShutdown;
|
bool mShutdown;
|
||||||
|
|
||||||
|
int mSpace1[4]; // We want mUptime to have its own cache line
|
||||||
int mUptime;
|
int mUptime;
|
||||||
|
int mSpace2[4];
|
||||||
|
|
||||||
mutable boost::mutex mLock;
|
mutable boost::mutex mLock;
|
||||||
|
|
||||||
void canonicalize(LoadSource&, const time_t now) const;
|
void canonicalize(LoadSource&, int upTime) const;
|
||||||
|
|
||||||
std::vector<LoadCost> mCosts;
|
std::vector<LoadCost> mCosts;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
void LoadMonitor::update()
|
void LoadMonitor::update()
|
||||||
{ // call with the mutex
|
{ // call with the mutex
|
||||||
time_t now = time(NULL);
|
int now = upTime();
|
||||||
|
|
||||||
if (now == mLastUpdate) // current
|
if (now == mLastUpdate) // current
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
extern int upTime();
|
||||||
|
|
||||||
// Monitors load levels and response times
|
// Monitors load levels and response times
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ protected:
|
|||||||
uint64 mLatencyMSPeak;
|
uint64 mLatencyMSPeak;
|
||||||
uint64 mTargetLatencyAvg;
|
uint64 mTargetLatencyAvg;
|
||||||
uint64 mTargetLatencyPk;
|
uint64 mTargetLatencyPk;
|
||||||
time_t mLastUpdate;
|
int mLastUpdate;
|
||||||
boost::mutex mLock;
|
boost::mutex mLock;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
@@ -27,7 +28,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
LoadMonitor() : mCounts(0), mLatencyEvents(0), mLatencyMSAvg(0), mLatencyMSPeak(0),
|
LoadMonitor() : mCounts(0), mLatencyEvents(0), mLatencyMSAvg(0), mLatencyMSPeak(0),
|
||||||
mTargetLatencyAvg(0), mTargetLatencyPk(0)
|
mTargetLatencyAvg(0), mTargetLatencyPk(0)
|
||||||
{ mLastUpdate = time(NULL); }
|
{ mLastUpdate = upTime(); }
|
||||||
|
|
||||||
void addCount(int counts);
|
void addCount(int counts);
|
||||||
void addLatency(int latency);
|
void addLatency(int latency);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
DECLARE_INSTANCE(Suppression);
|
DECLARE_INSTANCE(Suppression);
|
||||||
|
|
||||||
|
extern int upTime();
|
||||||
|
|
||||||
Suppression& SuppressionTable::findCreateEntry(const uint256& index, bool& created)
|
Suppression& SuppressionTable::findCreateEntry(const uint256& index, bool& created)
|
||||||
{
|
{
|
||||||
boost::unordered_map<uint256, Suppression>::iterator fit = mSuppressionMap.find(index);
|
boost::unordered_map<uint256, Suppression>::iterator fit = mSuppressionMap.find(index);
|
||||||
@@ -15,11 +17,11 @@ Suppression& SuppressionTable::findCreateEntry(const uint256& index, bool& creat
|
|||||||
}
|
}
|
||||||
created = true;
|
created = true;
|
||||||
|
|
||||||
time_t now = time(NULL);
|
int now = upTime();
|
||||||
time_t expireTime = now - mHoldTime;
|
int expireTime = now - mHoldTime;
|
||||||
|
|
||||||
// See if any supressions need to be expired
|
// See if any supressions need to be expired
|
||||||
std::map< time_t, std::list<uint256> >::iterator it = mSuppressionTimes.begin();
|
std::map< int, std::list<uint256> >::iterator it = mSuppressionTimes.begin();
|
||||||
if ((it != mSuppressionTimes.end()) && (it->first <= expireTime))
|
if ((it != mSuppressionTimes.end()) && (it->first <= expireTime))
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const uint256& lit, it->second)
|
BOOST_FOREACH(const uint256& lit, it->second)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ protected:
|
|||||||
boost::unordered_map<uint256, Suppression> mSuppressionMap;
|
boost::unordered_map<uint256, Suppression> mSuppressionMap;
|
||||||
|
|
||||||
// Stores all expiration times and the hashes indexed for them
|
// Stores all expiration times and the hashes indexed for them
|
||||||
std::map< time_t, std::list<uint256> > mSuppressionTimes;
|
std::map< int, std::list<uint256> > mSuppressionTimes;
|
||||||
|
|
||||||
int mHoldTime;
|
int mHoldTime;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
extern LogPartition TaggedCachePartition;
|
extern LogPartition TaggedCachePartition;
|
||||||
|
extern int upTime();
|
||||||
|
|
||||||
// This class implements a cache and a map. The cache keeps objects alive
|
// This class implements a cache and a map. The cache keeps objects alive
|
||||||
// in the map. The map allows multiple code paths that reference objects
|
// in the map. The map allows multiple code paths that reference objects
|
||||||
@@ -36,15 +37,15 @@ protected:
|
|||||||
class cache_entry
|
class cache_entry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
time_t last_use;
|
int last_use;
|
||||||
data_ptr ptr;
|
data_ptr ptr;
|
||||||
weak_data_ptr weak_ptr;
|
weak_data_ptr weak_ptr;
|
||||||
|
|
||||||
cache_entry(time_t l, const data_ptr& d) : last_use(l), ptr(d), weak_ptr(d) { ; }
|
cache_entry(int l, const data_ptr& d) : last_use(l), ptr(d), weak_ptr(d) { ; }
|
||||||
bool isCached() { return !!ptr; }
|
bool isCached() { return !!ptr; }
|
||||||
bool isExpired() { return weak_ptr.expired(); }
|
bool isExpired() { return weak_ptr.expired(); }
|
||||||
data_ptr lock() { return weak_ptr.lock(); }
|
data_ptr lock() { return weak_ptr.lock(); }
|
||||||
void touch() { last_use = time(NULL); }
|
void touch() { last_use = upTime(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<key_type, cache_entry> cache_pair;
|
typedef std::pair<key_type, cache_entry> cache_pair;
|
||||||
@@ -59,11 +60,11 @@ protected:
|
|||||||
int mCacheCount; // Number of items cached
|
int mCacheCount; // Number of items cached
|
||||||
|
|
||||||
cache_type mCache; // Hold strong reference to recent objects
|
cache_type mCache; // Hold strong reference to recent objects
|
||||||
time_t mLastSweep;
|
int mLastSweep;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TaggedCache(const char *name, int size, int age)
|
TaggedCache(const char *name, int size, int age)
|
||||||
: mName(name), mTargetSize(size), mTargetAge(age), mCacheCount(0), mLastSweep(time(NULL)) { ; }
|
: mName(name), mTargetSize(size), mTargetAge(age), mCacheCount(0), mLastSweep(upTime()) { ; }
|
||||||
|
|
||||||
int getTargetSize() const;
|
int getTargetSize() const;
|
||||||
int getTargetAge() const;
|
int getTargetAge() const;
|
||||||
@@ -128,8 +129,8 @@ template<typename c_Key, typename c_Data> void TaggedCache<c_Key, c_Data>::sweep
|
|||||||
{
|
{
|
||||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||||
|
|
||||||
time_t mLastSweep = time(NULL);
|
int mLastSweep = upTime();
|
||||||
time_t target = mLastSweep - mTargetAge;
|
int target = mLastSweep - mTargetAge;
|
||||||
int cacheRemovals = 0, mapRemovals = 0, cc = 0;
|
int cacheRemovals = 0, mapRemovals = 0, cc = 0;
|
||||||
|
|
||||||
if ((mTargetSize != 0) && (mCache.size() > mTargetSize))
|
if ((mTargetSize != 0) && (mCache.size() > mTargetSize))
|
||||||
@@ -243,7 +244,7 @@ bool TaggedCache<c_Key, c_Data>::canonicalize(const key_type& key, boost::shared
|
|||||||
cache_iterator cit = mCache.find(key);
|
cache_iterator cit = mCache.find(key);
|
||||||
if (cit == mCache.end())
|
if (cit == mCache.end())
|
||||||
{
|
{
|
||||||
mCache.insert(cache_pair(key, cache_entry(time(NULL), data)));
|
mCache.insert(cache_pair(key, cache_entry(upTime(), data)));
|
||||||
++mCacheCount;
|
++mCacheCount;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user