diff options
| author | Douglas Rumbaugh <dbr4@psu.edu> | 2024-02-08 12:40:13 -0500 |
|---|---|---|
| committer | Douglas Rumbaugh <dbr4@psu.edu> | 2024-02-08 12:40:13 -0500 |
| commit | ded1f979d101a5df37a65370f6c18803212edb66 (patch) | |
| tree | 89a86bacfb92177832f3a0a8ea8262f214baed17 /include/framework/DynamicExtension.h | |
| parent | 26a43e9b76e0041d192379b1343aeace4587dcc9 (diff) | |
| download | dynamic-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.h | 37 |
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; |