1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_
6 #define CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_
8 #include "base/time/time.h"
9 #include "content/common/content_export.h"
15 class RemoteTimeDelta
;
16 class RemoteTimeTicks
;
18 // On Windows, TimeTicks are not consistent between processes. Often, the values
19 // on one process have a static offset relative to another. Occasionally, these
20 // offsets shift while running.
22 // To combat this, any TimeTicks values sent from the remote process to the
23 // local process must be tweaked in order to appear monotonic.
25 // In order to properly tweak ticks, we need 4 reference points:
27 // - |local_lower_bound|: A known point, recorded on the local process, that
28 // occurs before any remote values that will be
30 // - |remote_lower_bound|: The equivalent point on the remote process. This
31 // should be recorded immediately after
32 // |local_lower_bound|.
33 // - |local_upper_bound|: A known point, recorded on the local process, that
34 // occurs after any remote values that will be
36 // - |remote_upper_bound|: The equivalent point on the remote process. This
37 // should be recorded immediately before
38 // |local_upper_bound|.
40 // Once these bounds are determined, values within the remote process's range
41 // can be converted to the local process's range. The values are converted as
44 // 1. If the remote's range exceeds the local's range, it is scaled to fit.
45 // Any values converted will have the same scale factor applied.
47 // 2. The remote's range is shifted so that it is centered within the
48 // local's range. Any values converted will be shifted the same amount.
49 class CONTENT_EXPORT InterProcessTimeTicksConverter
{
51 InterProcessTimeTicksConverter(const LocalTimeTicks
& local_lower_bound
,
52 const LocalTimeTicks
& local_upper_bound
,
53 const RemoteTimeTicks
& remote_lower_bound
,
54 const RemoteTimeTicks
& remote_upper_bound
);
56 // Returns the value within the local's bounds that correlates to
58 LocalTimeTicks
ToLocalTimeTicks(const RemoteTimeTicks
& remote_ms
) const;
60 // Returns the equivalent delta after applying remote-to-local scaling to
62 LocalTimeDelta
ToLocalTimeDelta(const RemoteTimeDelta
& remote_delta
) const;
64 // Returns true iff the TimeTicks are converted by adding a constant, without
65 // scaling. This is the case whenever the remote timespan is smaller than the
66 // local timespan, which should be the majority of cases due to IPC overhead.
67 bool IsSkewAdditiveForMetrics() const;
69 // Returns the (remote time) - (local time) difference estimated by the
70 // converter. This is the constant that is subtracted from remote TimeTicks to
71 // get local TimeTicks when no scaling is applied.
72 base::TimeDelta
GetSkewForMetrics() const;
75 int64
Convert(int64 value
) const;
77 // The local time which |remote_lower_bound_| is mapped to.
78 int64 local_base_time_
;
83 int64 remote_lower_bound_
;
84 int64 remote_upper_bound_
;
87 class CONTENT_EXPORT LocalTimeDelta
{
89 int ToInt32() const { return value_
; }
92 friend class InterProcessTimeTicksConverter
;
93 friend class LocalTimeTicks
;
95 LocalTimeDelta(int value
) : value_(value
) {}
100 class CONTENT_EXPORT LocalTimeTicks
{
102 static LocalTimeTicks
FromTimeTicks(const base::TimeTicks
& value
) {
103 return LocalTimeTicks(value
.ToInternalValue());
106 base::TimeTicks
ToTimeTicks() {
107 return base::TimeTicks::FromInternalValue(value_
);
110 LocalTimeTicks
operator+(const LocalTimeDelta
& delta
) {
111 return LocalTimeTicks(value_
+ delta
.value_
);
115 friend class InterProcessTimeTicksConverter
;
117 LocalTimeTicks(int64 value
) : value_(value
) {}
122 class CONTENT_EXPORT RemoteTimeDelta
{
124 static RemoteTimeDelta
FromRawDelta(int delta
) {
125 return RemoteTimeDelta(delta
);
129 friend class InterProcessTimeTicksConverter
;
130 friend class RemoteTimeTicks
;
132 RemoteTimeDelta(int value
) : value_(value
) {}
137 class CONTENT_EXPORT RemoteTimeTicks
{
139 static RemoteTimeTicks
FromTimeTicks(const base::TimeTicks
& ticks
) {
140 return RemoteTimeTicks(ticks
.ToInternalValue());
143 RemoteTimeDelta
operator-(const RemoteTimeTicks
& rhs
) const {
144 return RemoteTimeDelta(value_
- rhs
.value_
);
148 friend class InterProcessTimeTicksConverter
;
150 RemoteTimeTicks(int64 value
) : value_(value
) {}
155 } // namespace content
157 #endif // CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_