summaryrefslogtreecommitdiffstats
path: root/include/framework/DynamicExtension.h
diff options
context:
space:
mode:
authorDouglas Rumbaugh <dbr4@psu.edu>2024-02-08 12:40:13 -0500
committerDouglas Rumbaugh <dbr4@psu.edu>2024-02-08 12:40:13 -0500
commitded1f979d101a5df37a65370f6c18803212edb66 (patch)
tree89a86bacfb92177832f3a0a8ea8262f214baed17 /include/framework/DynamicExtension.h
parent26a43e9b76e0041d192379b1343aeace4587dcc9 (diff)
downloaddynamic-extension-ded1f979d101a5df37a65370f6c18803212edb66.tar.gz
Fixed a slight synchronization bug in Epoch retirement "properly"
Diffstat (limited to 'include/framework/DynamicExtension.h')
-rw-r--r--include/framework/DynamicExtension.h37
1 files changed, 27 insertions, 10 deletions
diff --git a/include/framework/DynamicExtension.h b/include/framework/DynamicExtension.h
index d88a945..e7dd774 100644
--- a/include/framework/DynamicExtension.h
+++ b/include/framework/DynamicExtension.h
@@ -293,6 +293,12 @@ private:
epoch_ptr old, new_ptr;
do {
+ /*
+ * during an epoch transition, a nullptr will installed in the
+ * current_epoch. At this moment, the "new" current epoch will
+ * soon be installed, but the "current" current epoch has been
+ * moved back to m_previous_epoch.
+ */
if (m_current_epoch.load().epoch == nullptr) {
old = m_previous_epoch;
new_ptr = {old.epoch, old.refcnt+1};
@@ -308,6 +314,8 @@ private:
}
} while (true);
+ assert(new_ptr.refcnt > 0);
+
return new_ptr.epoch;
}
@@ -388,7 +396,6 @@ private:
epoch_ptr old, new_ptr;
new_ptr = {nullptr, 0};
- size_t i=0;
do {
old = m_previous_epoch.load();
@@ -397,9 +404,7 @@ private:
break;
}
usleep(1);
- i++;
- if (i > 600) break;
} while(true);
delete epoch;
@@ -656,9 +661,15 @@ private:
do {
if (m_previous_epoch.load().epoch == epoch) {
old = m_previous_epoch;
- if (old.refcnt <= 0) {
- return;
- }
+ /*
+ * This could happen if we get into the system during a
+ * transition. In this case, we can just back out and retry
+ */
+ if (old.epoch == nullptr) {
+ continue;
+ }
+
+ assert(old.refcnt > 0);
new_ptr = {old.epoch, old.refcnt - 1};
if (m_previous_epoch.compare_exchange_strong(old, new_ptr)) {
@@ -666,10 +677,16 @@ private:
}
} else {
old = m_current_epoch;
- if (old.refcnt <= 0) {
- return;
- }
- //assert(old.refcnt > 0);
+ /*
+ * This could happen if we get into the system during a
+ * transition. In this case, we can just back out and retry
+ */
+ if (old.epoch == nullptr) {
+ continue;
+ }
+
+ assert(old.refcnt > 0);
+
new_ptr = {old.epoch, old.refcnt - 1};
if (m_current_epoch.compare_exchange_strong(old, new_ptr)) {
break;