From 94dcb13dd452d8161773216c0ffaf99f59365248 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 2 May 2014 11:23:34 -0700 Subject: [PATCH] Pathfinding dispatch improvements * Simplify decision whether to update a path * Prevent pathfinding threads from blocking each other --- src/ripple_app/paths/PathRequest.cpp | 60 +++++++++++++++------------ src/ripple_app/paths/PathRequest.h | 5 ++- src/ripple_app/paths/PathRequests.cpp | 1 + 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/ripple_app/paths/PathRequest.cpp b/src/ripple_app/paths/PathRequest.cpp index 7dc6e058199..7ff93e85ff9 100644 --- a/src/ripple_app/paths/PathRequest.cpp +++ b/src/ripple_app/paths/PathRequest.cpp @@ -29,7 +29,8 @@ const boost::shared_ptr& subscriber, int id, PathRequests& owner, , wpSubscriber (subscriber) , jvStatus (Json::objectValue) , bValid (false) - , iLastIndex (0) + , mLastIndex (0) + , mInProgress (false) , iLastLevel (0) , bLastSuccess (false) , iIdentifier (id) @@ -77,38 +78,43 @@ bool PathRequest::isValid () bool PathRequest::isNew () { - // does this path request still need its first full path - return iLastIndex.load() == 0; + ScopedLockType sl (mIndexLock); + + // does this path request still need its first full path + return mLastIndex == 0; } bool PathRequest::needsUpdate (bool newOnly, LedgerIndex index) { - LedgerIndex lastIndex = iLastIndex.load(); - for (;;) + ScopedLockType sl (mIndexLock); + + if (mInProgress) { - if (newOnly) - { - // Is this request new - if (lastIndex != 0) - return false; - - // This thread marks this request handled - if (iLastIndex.compare_exchange_weak (lastIndex, 1, - std::memory_order_release, std::memory_order_relaxed)) - return true; - } - else - { - // Has the request already been handled? - if (lastIndex >= index) - return false; - - // This thread marks this request handled - if (iLastIndex.compare_exchange_weak (lastIndex, index, - std::memory_order_release, std::memory_order_relaxed)) - return true; - } + // Another thread is handling this + return false; + } + + if (newOnly && (mLastIndex != 0)) + { + // Only handling new requests, this isn't new + return false; } + + if (mLastIndex >= index) + { + return false; + } + + mInProgress = true; + return true; +} + +void PathRequest::updateComplete () +{ + ScopedLockType sl (mIndexLock); + + assert (mInProgress); + mInProgress = false; } bool PathRequest::isValid (RippleLineCache::ref crCache) diff --git a/src/ripple_app/paths/PathRequest.h b/src/ripple_app/paths/PathRequest.h index 42eac806ff8..e1a93fbce70 100644 --- a/src/ripple_app/paths/PathRequest.h +++ b/src/ripple_app/paths/PathRequest.h @@ -57,6 +57,7 @@ class PathRequest : bool isValid (); bool isNew (); bool needsUpdate (bool newOnly, LedgerIndex index); + void updateComplete (); Json::Value getStatus (); Json::Value doCreate (const boost::shared_ptr&, const RippleLineCache::pointer&, @@ -93,7 +94,9 @@ class PathRequest : bool bValid; - std::atomic iLastIndex; + LockType mIndexLock; + LedgerIndex mLastIndex; + bool mInProgress; int iLastLevel; bool bLastSuccess; diff --git a/src/ripple_app/paths/PathRequests.cpp b/src/ripple_app/paths/PathRequests.cpp index c6e36e817ca..629568f86d1 100644 --- a/src/ripple_app/paths/PathRequests.cpp +++ b/src/ripple_app/paths/PathRequests.cpp @@ -90,6 +90,7 @@ void PathRequests::updateAll (Ledger::ref inLedger, CancelCallback shouldCancel) if (!ipSub->getConsumer ().warn ()) { Json::Value update = pRequest->doUpdate (cache, false); + pRequest->updateComplete (); update["type"] = "path_find"; ipSub->send (update, false); remove = false;