#include <stdlib.h>
#include <mutex>
+#include "common.h"
+#include "sc_annotation.h"
+
#define relaxed memory_order_relaxed
#define release memory_order_release
#define acquire memory_order_acquire
Value *res = NULL;
// Should be a load acquire
+ // This load action here makes it problematic for the SC analysis, what
+ // we need to do is as follows: if the get() method ever acquires the
+ // lock, we ignore this operation for the SC analysis, and otherwise we
+ // take it into consideration
+
+ SC_BEGIN();
Entry *firstPtr = first->load(acquire);
+ SC_END();
+
e = firstPtr;
while (e != NULL) {
if (e->hash == hash && eq(key, e->key)) {
return res;
else
break;
- // Loading the next entry
- e = e->next.load(acquire);
}
+ // Loading the next entry, this can be relaxed because the
+ // synchronization has been established by the load of head
+ e = e->next.load(relaxed);
}
// Recheck under synch if key apparently not there or interference
e = newFirstPtr;
while (e != NULL) {
if (e->hash == hash && eq(key, e->key)) {
- res = e->value.load(seq_cst);
+ // Protected by lock, no need to be SC
+ res = e->value.load(relaxed);
+ seg->unlock(); // Critical region ends
return res;
}
// Synchronized by locking
while (e != NULL) {
if (e->hash == hash && eq(key, e->key)) {
// FIXME: This could be a relaxed (because locking synchronize
- // with the previous put())??
- oldValue = e->value.load(acquire);
+ // with the previous put())?? no need to be acquire
+ oldValue = e->value.load(relaxed);
e->value.store(value, seq_cst);
seg->unlock(); // Don't forget to unlock before return
return oldValue;
}
// FIXME: This could be a relaxed (because locking synchronize
- // with the previous put())??
- oldValue = e->value.load(acquire);
+ // with the previous put())?? No need to be acquire
+ oldValue = e->value.load(relaxed);
// If the value parameter is NULL, we will remove the entry anyway
- if (value != NULL && value->equals(oldValue))
+ if (value != NULL && value->equals(oldValue)) {
+ seg->unlock();
return NULL;
+ }
// Force the get() to grab the lock and retry
e->value.store(NULL, relaxed);