diff --git a/include/CXXGraph/Partitioning/CoordinatedRecord.hpp b/include/CXXGraph/Partitioning/CoordinatedRecord.hpp index 2bf547a8b..bb5a09d2c 100644 --- a/include/CXXGraph/Partitioning/CoordinatedRecord.hpp +++ b/include/CXXGraph/Partitioning/CoordinatedRecord.hpp @@ -116,12 +116,18 @@ bool CoordinatedRecord::hasReplicaInPartition(const int m) const { } template bool CoordinatedRecord::getLock() { - return lock->try_lock(); + this->owns_lock = lock->try_lock(); + return this->owns_lock; } + template bool CoordinatedRecord::releaseLock() { - lock->unlock(); - return true; + if (this->owns_lock) { + lock->unlock(); + this->owns_lock = false; + return true; + } + return false; } template int CoordinatedRecord::getReplicas() const { diff --git a/include/CXXGraph/Partitioning/HDRF.hpp b/include/CXXGraph/Partitioning/HDRF.hpp index 6f363c269..97f584a71 100644 --- a/include/CXXGraph/Partitioning/HDRF.hpp +++ b/include/CXXGraph/Partitioning/HDRF.hpp @@ -78,30 +78,30 @@ void HDRF::performStep(shared> e, std::shared_ptr> u_record = state->getRecord(u); std::shared_ptr> v_record = state->getRecord(v); - //*** ASK FOR LOCK - bool locks_taken = false; - while (!locks_taken) { - srand((unsigned)time(NULL)); - int usleep_time = 2; - while (!u_record->getLock()) { - std::this_thread::sleep_for(std::chrono::microseconds(usleep_time)); - usleep_time = (int)pow(usleep_time, 2); - } - usleep_time = 2; - if (u != v) { - while (!v_record->getLock()) { - std::this_thread::sleep_for(std::chrono::microseconds(usleep_time)); - usleep_time = (int)pow(usleep_time, 2); - - if (usleep_time > GLOBALS.SLEEP_LIMIT) { + //*** OBTAIN LOCK + int backoff = 10; // microseconds + while (true) { + bool got_u = u_record->getLock(); + bool got_v = false; + + if (got_u) { + if (u != v) { + got_v = v_record->getLock(); + if (got_v) { + break; + } else { u_record->releaseLock(); - performStep(e, state); - return; - } // TO AVOID DEADLOCK + } + } else { + got_v = true; + break; } } - locks_taken = true; + + std::this_thread::sleep_for(std::chrono::microseconds(backoff)); + if (backoff < GLOBALS.SLEEP_LIMIT) backoff *= 2; } + //*** LOCK TAKEN int machine_id = -1; diff --git a/include/CXXGraph/Partitioning/Record.hpp b/include/CXXGraph/Partitioning/Record.hpp index 38711d5eb..f81fc3e1e 100755 --- a/include/CXXGraph/Partitioning/Record.hpp +++ b/include/CXXGraph/Partitioning/Record.hpp @@ -28,6 +28,8 @@ namespace CXXGraph { namespace Partitioning { template class Record { + protected: + bool owns_lock = false; public: virtual ~Record() = default;