mediapipe/mediapipe/framework/deps/monotonic_clock.h
MediaPipe Team 2b58cceec9 Project import generated by Copybara.
GitOrigin-RevId: d8caa66de45839696f5bd0786ad3bfbcb9cff632
2020-12-09 22:43:33 -05:00

101 lines
4.3 KiB
C++

// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MEDIAPIPE_DEPS_MONOTONIC_CLOCK_H_
#define MEDIAPIPE_DEPS_MONOTONIC_CLOCK_H_
#include "absl/time/time.h"
#include "mediapipe/framework/deps/clock.h"
namespace mediapipe {
// MonotonicClock is an interface for a Clock that never goes backward.
// Successive returned values from Now() are guaranteed to be monotonically
// non-decreasing, although they may not be monotonic with respect to values
// returned from other instances of MonotonicClock.
//
// You can wrap any Clock object in a MonotonicClock using the
// CreateMonotonicClock() factory method, including Clock::RealClock().
// However, if you want a monotonic version of real time, it is strongly
// recommended that you use the CreateSynchronizedMonotonicClock() factory
// method, which wraps Clock::RealClock() and guarantees that values returned
// from Now() are monotonic ACROSS instances of the class that are created by
// CreateSynchronizedMonotonicClock().
//
// All methods support concurrent access.
class MonotonicClock : public Clock {
public:
// The MonotonicClock state, which may be shared between MonotonicClocks.
struct State;
~MonotonicClock() override {}
// The Clock interface (see util/time/clock.h).
//
// Return a monotonically non-decreasing time.
absl::Time TimeNow() override = 0;
// Sleep and SleepUntil guarantee only that the caller will sleep for at
// least as long as specified in monotonic time. The caller may sleep for
// much longer (in monotonic time) if monotonic time jumps far into the
// future. Whether or not this happens depends on the behavior of the raw
// clock.
void Sleep(absl::Duration d) override = 0;
void SleepUntil(absl::Time wakeup_time) override = 0;
// Get metrics about time corrections.
virtual void GetCorrectionMetrics(int* correction_count,
double* max_correction) = 0;
// Reset values returned by GetCorrectionMetrics().
virtual void ResetCorrectionMetrics() = 0;
// Factory methods.
//
// Create a MonotonicClock based on the given raw_clock. This clock will
// return monotonically non-decreasing values from Now(), but may not behave
// monotonically with respect to other instances created by this function,
// even if they are based on the same raw_clock. Caller owns raw_clock.
static MonotonicClock* CreateMonotonicClock(Clock* raw_clock);
// Create an instance of MonotonicClock that is based on Clock::RealClock().
// All such instance are synced with each other such that return values from
// Now() are monotonic across instances. This allows independently developed
// code bases to have private instances of the synchronized MonotonicClock
// and know that they will never see time anomalies when calling from one
// code base to another. Each instance can have its own correction callback.
// Unlike Clock::RealClock(), caller owns this object and should delete it
// when no longer needed.
static MonotonicClock* CreateSynchronizedMonotonicClock();
};
class MonotonicClockTest;
// Provides access to MonotonicClock::State for unit-testing.
class MonotonicClockAccess {
private:
using State = MonotonicClock::State;
// Reset internal global state. Should only be called by test code.
static void SynchronizedMonotonicClockReset();
static State* CreateMonotonicClockState(Clock* raw_clock);
static void DeleteMonotonicClockState(State* state);
// Create a monotonic clock based on the given state. Caller owns state
// so that multiple such clocks can be created from the same state.
static MonotonicClock* CreateMonotonicClock(State* state);
friend class mediapipe::MonotonicClockTest;
};
} // namespace mediapipe
#endif // MEDIAPIPE_DEPS_MONOTONIC_CLOCK_H_