Chromium Code Reviews| Index: content/common/inter_process_time_ticks_converter.h |
| diff --git a/content/common/inter_process_time_ticks_converter.h b/content/common/inter_process_time_ticks_converter.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b99f6a7354fa7bf4fa38807d26b413756f123a4c |
| --- /dev/null |
| +++ b/content/common/inter_process_time_ticks_converter.h |
| @@ -0,0 +1,151 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ |
| +#define CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ |
| + |
| +#include "base/time.h" |
| + |
| +namespace content { |
| + |
| +class LocalTimeDelta; |
| +class LocalTimeTicks; |
| +class RemoteTimeDelta; |
| +class RemoteTimeTicks; |
| + |
| +// On Windows, TimeTicks are not consistent between processes. Often, the values |
| +// on one process have a static offset relative to another. Occasionally, these |
| +// offsets shift while running. |
| +// |
| +// To combat this, any TimeTicks values sent from the remote process to the |
| +// local process must be tweaked in order to appear monotonic. |
| +// |
| +// In order to properly tweak ticks, we need 4 reference points: |
| +// |
| +// - |local_lower_bound|: A known point, recorded on the local process, that |
| +// occurs before any remote values that will be |
| +// converted. |
| +// - |remote_lower_bound|: The equivalent point on the remote process. This |
| +// should be recorded immediately after |
| +// |local_lower_bound|. |
| +// - |local_upper_bound|: A known point, recorded on the local process, that |
| +// occurs after any remote values that will be |
| +// converted. |
| +// - |remote_upper_bound|: The equivalent point on the remote process. This |
| +// should be recorded immediately before |
| +// |local_upper_bound|. |
| +// |
| +// Once these bounds are determined, values within the remote process's range |
| +// can be converted to the local process's range. The values are converted as |
| +// follows: |
| +// |
| +// 1. If the remote's range exceeds the local's range, it is scaled to fit. |
| +// Any values converted will have the same scale factor applied. |
| +// |
| +// 2. The remote's range is shifted so that it is centered within the |
| +// local's range. Any values converted will be shifted the same amount. |
| +class InterProcessTimeTicksConverter { |
| + public: |
| + InterProcessTimeTicksConverter(const LocalTimeTicks& local_lower_bound, |
| + const LocalTimeTicks& local_upper_bound, |
| + const RemoteTimeTicks& remote_lower_bound, |
| + const RemoteTimeTicks& remote_upper_bound); |
| + |
| + // Returns the value within the local's bounds that correlates to |
| + // |remote_ms|. |
| + LocalTimeTicks ConvertMilliseconds(const RemoteTimeTicks& remote_ms); |
|
darin (slow to review)
2011/12/12 22:25:46
nit: What do you think about renaming this ToLocal
James Simonsen
2011/12/12 23:35:34
Agreed. Done.
|
| + |
| + // Returns the equivalent delta after applying remote-to-local scaling to |
| + // |remote_delta|. |
| + LocalTimeDelta ConvertDelta(const RemoteTimeDelta& remote_delta); |
|
darin (slow to review)
2011/12/12 22:25:46
nit: ToLocalTimeDelta?
James Simonsen
2011/12/12 23:35:34
Done.
|
| + |
| + // Returns |remote_value| after it has been clamped within the range |
| + // [lower_bound, upper_bound]. This function is useful when we lack tight |
| + // enough bounds to use ConvertMilliseconds(). |
| + static LocalTimeTicks ClampTimeInRange(const RemoteTimeTicks& remote_value, |
|
darin (slow to review)
2011/12/12 22:25:46
This function feels like a small, orthogonal appen
James Simonsen
2011/12/12 23:35:34
It's too simple to worry about unit testing and I
|
| + const LocalTimeTicks& lower_bound, |
| + const LocalTimeTicks& upper_bound); |
| + |
| + private: |
| + int64 Convert(int64 value); |
| + |
| + int64 offset_; |
| + int64 numerator_; |
| + int64 denominator_; |
| + |
| + int64 remote_lower_bound_; |
| + int64 remote_upper_bound_; |
| +}; |
| + |
| +class LocalTimeDelta { |
| + public: |
| + int ToInt32() const { return value_; } |
| + |
| + private: |
| + friend class InterProcessTimeTicksConverter; |
| + friend class LocalTimeTicks; |
| + |
| + LocalTimeDelta(int value) : value_(value) {} |
| + |
| + int value_; |
| +}; |
| + |
| +class LocalTimeTicks { |
| + public: |
| + static LocalTimeTicks FromTimeTicks(const base::TimeTicks& value) { |
| + return LocalTimeTicks(value.ToInternalValue()); |
| + } |
| + |
| + base::TimeTicks ToTimeTicks() { |
| + return base::TimeTicks::FromInternalValue(value_); |
| + } |
| + |
| + LocalTimeTicks operator+(const LocalTimeDelta& delta) { |
| + return LocalTimeTicks(value_ + delta.value_); |
| + } |
| + |
| + private: |
| + friend class InterProcessTimeTicksConverter; |
| + |
| + LocalTimeTicks(int64 value) : value_(value) {} |
| + |
| + int64 value_; |
| +}; |
| + |
| +class RemoteTimeDelta { |
| + public: |
| + static RemoteTimeDelta FromRawDelta(int delta) { |
| + return RemoteTimeDelta(delta); |
| + } |
| + |
| + private: |
| + friend class InterProcessTimeTicksConverter; |
| + friend class RemoteTimeTicks; |
| + |
| + RemoteTimeDelta(int value) : value_(value) {} |
| + |
| + int value_; |
| +}; |
| + |
| +class RemoteTimeTicks { |
| + public: |
| + static RemoteTimeTicks FromTimeTicks(const base::TimeTicks& ticks) { |
| + return RemoteTimeTicks(ticks.ToInternalValue()); |
| + } |
| + |
| + RemoteTimeDelta operator-(const RemoteTimeTicks& rhs) const { |
| + return RemoteTimeDelta(value_ - rhs.value_); |
| + } |
| + |
| + private: |
| + friend class InterProcessTimeTicksConverter; |
| + |
| + RemoteTimeTicks(int64 value) : value_(value) {} |
| + |
| + int64 value_; |
| +}; |
| + |
| +} // namespace content |
| + |
| +#endif // CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ |