Introduce AtomicDuration

This commit is contained in:
Alexander A. Klimov 2020-07-09 10:47:54 +02:00 committed by Julian Brost
parent c2c9b6b159
commit 4b2b45c8a1
3 changed files with 73 additions and 0 deletions

View File

@ -4,6 +4,7 @@
#define ATOMIC_H
#include <atomic>
#include <chrono>
#include <mutex>
#include <type_traits>
#include <utility>
@ -34,6 +35,43 @@ public:
}
};
/**
* Accumulates time durations atomically.
*
* @ingroup base
*/
class AtomicDuration
{
public:
using Clock = std::chrono::steady_clock;
/**
* Adds the elapsedTime to this instance.
*
* May be called multiple times to accumulate time.
*
* @param elapsedTime The distance between two time points
*
* @return This instance for method chaining
*/
AtomicDuration& operator+=(const Clock::duration& elapsedTime) noexcept
{
m_Sum.fetch_add(elapsedTime.count(), std::memory_order_relaxed);
return *this;
}
/**
* @return The total accumulated time in seconds
*/
operator double() const noexcept
{
return std::chrono::duration<double>(Clock::duration(m_Sum.load(std::memory_order_relaxed))).count();
}
private:
Atomic<Clock::duration::rep> m_Sum {0};
};
/**
* Wraps any T into a std::atomic<T>-like interface that locks using a mutex.
*

View File

@ -89,6 +89,7 @@ set(base_test_SOURCES
icingaapplication-fixture.cpp
utils.cpp
base-array.cpp
base-atomic.cpp
base-base64.cpp
base-convert.cpp
base-dictionary.cpp

34
test/base-atomic.cpp Normal file
View File

@ -0,0 +1,34 @@
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
#include "base/atomic.hpp"
#include <BoostTestTargetConfig.h>
using namespace icinga;
BOOST_AUTO_TEST_SUITE(base_atomic)
BOOST_AUTO_TEST_CASE(duration_none)
{
BOOST_CHECK_EQUAL(static_cast<double>(AtomicDuration()), 0);
}
BOOST_AUTO_TEST_CASE(duration_one)
{
AtomicDuration sum;
sum += std::chrono::seconds(1);
BOOST_CHECK_EQUAL(static_cast<double>(sum), 1);
}
BOOST_AUTO_TEST_CASE(duration_two)
{
AtomicDuration sum;
sum += std::chrono::seconds(1);
sum += std::chrono::seconds(2);
BOOST_CHECK_EQUAL(static_cast<double>(sum), 3);
}
BOOST_AUTO_TEST_SUITE_END()