diff options
author | Tor Egge <Tor.Egge@online.no> | 2022-05-03 13:10:19 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2022-05-03 13:10:19 +0200 |
commit | 4d3cfd423b71e5e3a036c186efd3398a478d7798 (patch) | |
tree | 7e9449d00e7231ef9ad41f3ad442f905fe61e6a4 /vespalib | |
parent | 2c65997f743e5c80619b8fb58b78dac146ecb0c9 (diff) |
Use atomic _generation in vespalib::GenerationHandler.
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/vespa/vespalib/util/generationhandler.cpp | 8 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/generationhandler.h | 14 |
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; } /** |