diff options
-rw-r--r-- | src/mongo/db/prepare_conflict_tracker.cpp | 8 | ||||
-rw-r--r-- | src/mongo/util/tick_source.h | 14 | ||||
-rw-r--r-- | src/mongo/util/tick_source_test.cpp | 14 |
3 files changed, 29 insertions, 7 deletions
diff --git a/src/mongo/db/prepare_conflict_tracker.cpp b/src/mongo/db/prepare_conflict_tracker.cpp index 7dc8123e282..e8e031a1405 100644 --- a/src/mongo/db/prepare_conflict_tracker.cpp +++ b/src/mongo/db/prepare_conflict_tracker.cpp @@ -51,14 +51,8 @@ void PrepareConflictTracker::endPrepareConflict(OperationContext* opCtx) { auto tickSource = opCtx->getServiceContext()->getTickSource(); auto curTick = tickSource->getTicks(); - invariant(_prepareConflictStartTime <= curTick, - str::stream() << "Prepare conflict start time (" - << tickSource->ticksTo<Microseconds>(_prepareConflictStartTime) - << ") is somehow greater than current time (" - << tickSource->ticksTo<Microseconds>(curTick) << ")"); - auto curConflictDuration = - tickSource->ticksTo<Microseconds>(curTick - _prepareConflictStartTime); + tickSource->spanTo<Microseconds>(_prepareConflictStartTime, curTick); _prepareConflictDuration.store(_prepareConflictDuration.load() + curConflictDuration); _prepareConflictStartTime = 0; diff --git a/src/mongo/util/tick_source.h b/src/mongo/util/tick_source.h index f77ea9d1d6f..5b0abc88aca 100644 --- a/src/mongo/util/tick_source.h +++ b/src/mongo/util/tick_source.h @@ -29,6 +29,7 @@ #pragma once +#include <algorithm> #include <cstdint> namespace mongo { @@ -64,5 +65,18 @@ public: static_cast<double>(getTicksPerSecond()) * D::period::num / D::period::den; return D(static_cast<int64_t>(ticks / ticksPerD)); } + + /** + * Measures the length of the span from the start tick to the end tick and returns the result + * using duration type D. + * If the start tick is after (greater than) the end tick, returns a duration equivalent to 0 + * ticks. + * + * e.g. tickSource->spanTo<Milliseconds>(start, end); + */ + template <typename D> + D spanTo(Tick start, Tick end) { + return ticksTo<D>(std::max((end - start), Tick{0})); + } }; } // namespace mongo diff --git a/src/mongo/util/tick_source_test.cpp b/src/mongo/util/tick_source_test.cpp index aef28a7e97c..cf08b69cbdc 100644 --- a/src/mongo/util/tick_source_test.cpp +++ b/src/mongo/util/tick_source_test.cpp @@ -52,5 +52,19 @@ TEST(TickSourceTest, TicksToDurationConversion) { tsMicros.reset(1); ASSERT_EQ(tsMicros.ticksTo<Microseconds>(tsMicros.getTicks()).count(), 1); } + +TEST(TickSourceTest, SpansToDurationConversion) { + TickSourceMock<Seconds> tsSecs; + tsSecs.reset(0); + TickSource::Tick zero = tsSecs.getTicks(); + tsSecs.reset(10); + TickSource::Tick ten = tsSecs.getTicks(); + ASSERT_EQ(tsSecs.spanTo<Seconds>(zero, ten).count(), 10); + ASSERT_EQ(tsSecs.spanTo<Seconds>(ten, zero).count(), 0); + ASSERT_EQ(tsSecs.spanTo<Milliseconds>(zero, ten).count(), 10 * 1000); + ASSERT_EQ(tsSecs.spanTo<Milliseconds>(ten, zero).count(), 0); + ASSERT_EQ(tsSecs.spanTo<Microseconds>(zero, ten).count(), 10 * 1000 * 1000); + ASSERT_EQ(tsSecs.spanTo<Microseconds>(ten, zero).count(), 0); +} } // namespace } // namespace mongo |