1 : // Copyright 2013 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #ifndef SYZYGY_TRACE_COMMON_CLOCK_H_
16 : #define SYZYGY_TRACE_COMMON_CLOCK_H_
17 :
18 : #include <intrin.h>
19 : #include <stdint.h>
20 : #include <windows.h>
21 :
22 : #include "syzygy/common/assertions.h"
23 :
24 : namespace trace {
25 : namespace common {
26 :
27 : // A structure representing information about a timer. This can be used
28 : // (along with reference times) to translate between timers and clocks.
29 : // Both values will be set to zero for a timer that is not valid on a given
30 : // system.
31 : // NOTE: This is meant to be POD so that it can be written directly as is to and
32 : // from disk.
33 : struct TimerInfo {
34 : // The frequency of this timer, in counts per second.
35 : uint64_t frequency;
36 : // The resolution of this timer, in counts.
37 : uint64_t resolution;
38 : };
39 : COMPILE_ASSERT_IS_POD(TimerInfo);
40 :
41 : // Gets timer information about the various timers. A timer whose information
42 : // can not be found will have the frequency set to 0.
43 : // @param timer_info Will be populated with the information about the timer.
44 : void GetTickTimerInfo(TimerInfo* timer_info);
45 : void GetTscTimerInfo(TimerInfo* timer_info);
46 :
47 : // @returns the current value of the ticks timer.
48 : uint64_t GetTicks();
49 :
50 : // @returns the current value of the TSC register using RDTSC.
51 E : inline uint64_t GetTsc() {
52 E : return ::__rdtsc();
53 E : }
54 :
55 : // Given a file time, a reference time and TimerInfo, convert the given
56 : // timer value to the corresponding file time. This can fail if the timer
57 : // info is invalid (frequency is 0, ie: unknown).
58 : // @param file_time_ref A reference file time.
59 : // @param timer_info Information regarding the timer frequency.
60 : // @param timer_ref The corresponding reference timer value.
61 : // @param timer_value The timer value to be converted.
62 : // @param file_time The file time to be populated.
63 : // @returns true on success, false otherwise.
64 : bool TimerToFileTime(const FILETIME& file_time_ref,
65 : const TimerInfo& timer_info,
66 : const uint64_t& timer_ref,
67 : const uint64_t& timer_value,
68 : FILETIME* file_time);
69 :
70 : // Information about the system clock and various timers.
71 : // NOTE: This is meant to be POD so that it can be written directly as is to and
72 : // from disk.
73 : struct ClockInfo {
74 : // Reference times. Used for converting between time formats.
75 : FILETIME file_time;
76 : uint64_t ticks_reference;
77 : uint64_t tsc_reference;
78 :
79 : // Information about the timers at our disposal.
80 : TimerInfo ticks_info;
81 : TimerInfo tsc_info;
82 : };
83 : COMPILE_ASSERT_IS_POD(ClockInfo);
84 :
85 : // Populates a ClockInfo struct with information about the system clock and
86 : // timers.
87 : // NOTE: This requires read access to the registry to get full information, and
88 : // is intended to be run from a process that has no restrictions. For
89 : // example, if this is run from a sandboxed process the TSC timer
90 : // information will be incomplete. A warning will be logged if this is the
91 : // case.
92 : // @param clock_info The struct to be populated.
93 : void GetClockInfo(ClockInfo* clock_info);
94 :
95 : // Converts a timer value to a file time given the clock info. This can fail if
96 : // the given timer has an invalid corresponding TimerInfo in @p clock_info.
97 : // @param clock_info The system clock information.
98 : // @param ticks The value of the tick counter.
99 : // @param tsc The value of the TSC counter.
100 : // @param file_time The file time to be populated.
101 : // @returns true on success, false otherwise.
102 : bool TicksToFileTime(const ClockInfo& clock_info,
103 : uint64_t ticks,
104 : FILETIME* file_time);
105 : bool TscToFileTime(const ClockInfo& clock_info,
106 : uint64_t tsc,
107 : FILETIME* file_time);
108 :
109 : } // namespace common
110 : } // namespace trace
111 :
112 : #endif // SYZYGY_TRACE_COMMON_CLOCK_H_
|