Introduce AtomicDuration

This commit is contained in:
Alexander A. Klimov 2020-07-09 10:47:54 +02:00 committed by Julian Brost
parent 7a26dea9ff
commit 002d422738
5 changed files with 85 additions and 1 deletions

View File

@ -16,7 +16,7 @@ set(base_SOURCES
i2-base.hpp
application.cpp application.hpp application-ti.hpp application-version.cpp application-environment.cpp
array.cpp array.hpp array-script.cpp
atomic.hpp
atomic.cpp atomic.hpp
atomic-file.cpp atomic-file.hpp
base64.cpp base64.hpp
boolean.cpp boolean.hpp boolean-script.cpp

20
lib/base/atomic.cpp Normal file
View File

@ -0,0 +1,20 @@
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
#include "base/atomic.hpp"
using namespace icinga;
/**
* 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& AtomicDuration::operator+=(const Clock::duration& elapsedTime) noexcept
{
m_Sum.fetch_add(elapsedTime.count(), std::memory_order_relaxed);
return *this;
}

View File

@ -4,6 +4,7 @@
#define ATOMIC_H
#include <atomic>
#include <chrono>
#include <mutex>
#include <type_traits>
#include <utility>
@ -41,6 +42,31 @@ public:
}
};
/**
* Accumulates time durations atomically.
*
* @ingroup base
*/
class AtomicDuration
{
public:
using Clock = std::chrono::steady_clock;
AtomicDuration& operator+=(const Clock::duration&) noexcept;
/**
* @return The total accumulated time in seconds
*/
template<class T>
operator T() const noexcept
{
return std::chrono::duration<T>(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

@ -5,6 +5,7 @@ include(BoostTestTargets)
set(base_test_SOURCES
icingaapplication-fixture.cpp
base-array.cpp
base-atomic.cpp
base-base64.cpp
base-convert.cpp
base-dictionary.cpp
@ -60,6 +61,9 @@ add_boost_test(base
base_array/foreach
base_array/clone
base_array/json
base_atomic/duration_none
base_atomic/duration_one
base_atomic/duration_two
base_base64/base64
base_convert/tolong
base_convert/todouble

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((double)AtomicDuration(), 0);
}
BOOST_AUTO_TEST_CASE(duration_one)
{
AtomicDuration sum;
sum += std::chrono::seconds(1);
BOOST_CHECK_EQUAL((double)sum, 1);
}
BOOST_AUTO_TEST_CASE(duration_two)
{
AtomicDuration sum;
sum += std::chrono::seconds(1);
sum += std::chrono::seconds(2);
BOOST_CHECK_EQUAL((double)sum, 3);
}
BOOST_AUTO_TEST_SUITE_END()