Skip to content

Commit 858f31b

Browse files
committed
Fixes #530, replaces the dangerous recursive strategy in HDRF with a safer backoff one. Stop the unlocking of unowned mutexes with the implementation of the owns_lock member variable.
1 parent 6fab592 commit 858f31b

3 files changed

Lines changed: 31 additions & 23 deletions

File tree

include/CXXGraph/Partitioning/CoordinatedRecord.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,18 @@ bool CoordinatedRecord<T>::hasReplicaInPartition(const int m) const {
116116
}
117117
template <typename T>
118118
bool CoordinatedRecord<T>::getLock() {
119-
return lock->try_lock();
119+
owns_lock = lock->try_lock();
120+
return owns_lock;
120121
}
122+
121123
template <typename T>
122124
bool CoordinatedRecord<T>::releaseLock() {
123-
lock->unlock();
124-
return true;
125+
if (owns_lock) {
126+
lock->unlock();
127+
owns_lock = false;
128+
return true;
129+
}
130+
return false;
125131
}
126132
template <typename T>
127133
int CoordinatedRecord<T>::getReplicas() const {

include/CXXGraph/Partitioning/HDRF.hpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -78,30 +78,30 @@ void HDRF<T>::performStep(shared<const Edge<T>> e,
7878
std::shared_ptr<Record<T>> u_record = state->getRecord(u);
7979
std::shared_ptr<Record<T>> v_record = state->getRecord(v);
8080

81-
//*** ASK FOR LOCK
82-
bool locks_taken = false;
83-
while (!locks_taken) {
84-
srand((unsigned)time(NULL));
85-
int usleep_time = 2;
86-
while (!u_record->getLock()) {
87-
std::this_thread::sleep_for(std::chrono::microseconds(usleep_time));
88-
usleep_time = (int)pow(usleep_time, 2);
89-
}
90-
usleep_time = 2;
91-
if (u != v) {
92-
while (!v_record->getLock()) {
93-
std::this_thread::sleep_for(std::chrono::microseconds(usleep_time));
94-
usleep_time = (int)pow(usleep_time, 2);
95-
96-
if (usleep_time > GLOBALS.SLEEP_LIMIT) {
81+
//*** OBTAIN LOCK
82+
int backoff = 10; // microseconds
83+
while (true) {
84+
bool got_u = u_record->getLock();
85+
bool got_v = false;
86+
87+
if (got_u) {
88+
if (u != v) {
89+
got_v = v_record->getLock();
90+
if (got_v) {
91+
break;
92+
} else {
9793
u_record->releaseLock();
98-
performStep(e, state);
99-
return;
100-
} // TO AVOID DEADLOCK
94+
}
95+
} else {
96+
got_v = true;
97+
break;
10198
}
10299
}
103-
locks_taken = true;
100+
101+
std::this_thread::sleep_for(std::chrono::microseconds(backoff));
102+
if (backoff < GLOBALS.SLEEP_LIMIT) backoff *= 2;
104103
}
104+
105105
//*** LOCK TAKEN
106106
int machine_id = -1;
107107

include/CXXGraph/Partitioning/Record.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ namespace CXXGraph {
2828
namespace Partitioning {
2929
template <typename T>
3030
class Record {
31+
protected:
32+
bool owns_lock = false;
3133
public:
3234
virtual ~Record() = default;
3335

0 commit comments

Comments
 (0)