summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2022-05-03 13:10:19 +0200
committerTor Egge <Tor.Egge@online.no>2022-05-03 13:10:19 +0200
commit4d3cfd423b71e5e3a036c186efd3398a478d7798 (patch)
tree7e9449d00e7231ef9ad41f3ad442f905fe61e6a4 /vespalib
parent2c65997f743e5c80619b8fb58b78dac146ecb0c9 (diff)
Use atomic _generation in vespalib::GenerationHandler.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/vespa/vespalib/util/generationhandler.cpp8
-rw-r--r--vespalib/src/vespa/vespalib/util/generationhandler.h14
2 files changed, 12 insertions, 10 deletions
diff --git a/vespalib/src/vespa/vespalib/util/generationhandler.cpp b/vespalib/src/vespa/vespalib/util/generationhandler.cpp
index 7797978d187..d1cc0271068 100644
--- a/vespalib/src/vespa/vespalib/util/generationhandler.cpp
+++ b/vespalib/src/vespa/vespalib/util/generationhandler.cpp
@@ -138,7 +138,7 @@ GenerationHandler::GenerationHandler()
{
_last = _first = new GenerationHold;
++_numHolds;
- _first->_generation.store(_generation, std::memory_order_relaxed);
+ _first->_generation.store(getCurrentGeneration(), std::memory_order_relaxed);
_first->setValid();
}
@@ -188,7 +188,7 @@ GenerationHandler::incGeneration()
// the typical case when no readers are present.
// Note: atomic thread fence above is needed to avoid stale data in
// reader
- _generation = ngen;
+ set_generation(ngen);
last->_generation.store(ngen, std::memory_order_relaxed);
updateFirstUsedGeneration();
return;
@@ -205,7 +205,7 @@ GenerationHandler::incGeneration()
nhold->_next = nullptr;
nhold->setValid();
last->_next = nhold;
- _generation = ngen;
+ set_generation(ngen);
_last.store(nhold, std::memory_order_release);
updateFirstUsedGeneration();
}
@@ -213,7 +213,7 @@ GenerationHandler::incGeneration()
uint32_t
GenerationHandler::getGenerationRefCount(generation_t gen) const
{
- if (static_cast<sgeneration_t>(gen - _generation) > 0)
+ if (static_cast<sgeneration_t>(gen - getCurrentGeneration()) > 0)
return 0u;
if (static_cast<sgeneration_t>(getFirstUsedGeneration() - gen) > 0)
return 0u;
diff --git a/vespalib/src/vespa/vespalib/util/generationhandler.h b/vespalib/src/vespa/vespalib/util/generationhandler.h
index 2aeb4c2f886..9637ad0e414 100644
--- a/vespalib/src/vespa/vespalib/util/generationhandler.h
+++ b/vespalib/src/vespa/vespalib/util/generationhandler.h
@@ -72,13 +72,15 @@ public:
};
private:
- generation_t _generation;
+ std::atomic<generation_t> _generation;
std::atomic<generation_t> _firstUsedGeneration;
std::atomic<GenerationHold *> _last; // Points to "current generation" entry
GenerationHold *_first; // Points to "firstUsedGeneration" entry
GenerationHold *_free; // List of free entries
uint32_t _numHolds; // Number of allocated generation hold entries
+ void set_generation(generation_t generation) noexcept { _generation.store(generation, std::memory_order_relaxed); }
+
public:
/**
* Creates a new generation handler.
@@ -108,19 +110,19 @@ public:
* Returns the first generation guarded by a reader. It might be too low
* if writer hasn't updated first used generation after last reader left.
*/
- generation_t getFirstUsedGeneration() const {
+ generation_t getFirstUsedGeneration() const noexcept {
return _firstUsedGeneration.load(std::memory_order_relaxed);
}
/**
* Returns the current generation.
**/
- generation_t getCurrentGeneration() const {
- return _generation;
+ generation_t getCurrentGeneration() const noexcept {
+ return _generation.load(std::memory_order_relaxed);
}
- generation_t getNextGeneration() const {
- return _generation + 1;
+ generation_t getNextGeneration() const noexcept {
+ return getCurrentGeneration() + 1;
}
/**