YSTest: Timer.cpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
Timer.cpp
浏览该文件的文档.
1 /*
2 © 2012-2014 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "YCLib/YModules.h"
29 #include YFM_YCLib_Timer
30 #include YFM_YCLib_NativeAPI
31 #if YCL_Win32
32 # include <mmsystem.h> // for multimedia timers;
33 #endif
34
35 namespace platform
36 {
37
38 namespace
39 {
40 bool bUninitializedTimers(true);
41 #if YCL_DS
42 volatile std::uint32_t system_tick;
43
44 void
45 timer_callback()
46 {
47 ++system_tick;
48 }
49 #elif YCL_Win32
50 std::uint32_t(*p_tick_getter)();
51 std::uint64_t(*p_tick_getter_nano)();
52 union
53 {
54 ::DWORD start;
55 struct
56 {
57 ::LARGE_INTEGER start;
58 ::LARGE_INTEGER tps;
59 } hi;
60 } g_ticks;
61
62 std::uint32_t
63 get_ticks_hi_res()
64 {
65 ::LARGE_INTEGER now;
66
67 ::QueryPerformanceCounter(&now);
68 now.QuadPart -= g_ticks.hi.start.QuadPart;
69 now.QuadPart *= 1000;
70 return ::DWORD(now.QuadPart / g_ticks.hi.tps.QuadPart);
71 }
72
73 std::uint64_t
74 get_ticks_hi_res_nano()
75 {
76 ::LARGE_INTEGER now;
77
78 ::QueryPerformanceCounter(&now);
79 now.QuadPart -= g_ticks.hi.start.QuadPart;
80 now.QuadPart *= 1000000000;
81 return now.QuadPart / g_ticks.hi.tps.QuadPart;
82 }
83
84 std::uint32_t
85 get_ticks_mm()
86 {
87 ::DWORD now(::timeGetTime());
88
89 return now < g_ticks.start ? (~::DWORD(0) - g_ticks.start) + now
90 : now - g_ticks.start;
91 }
92
93 std::uint64_t
94 get_ticks_mm_nano()
95 {
96 return get_ticks_mm() * 1000000;
97 }
98 #endif
99 }
100
101 void
102 StartTicks()
103 {
104 if(YB_UNLIKELY(bUninitializedTimers))
105 {
106 #if YCL_DS
107 // f = 33.513982MHz;
108 // BUS_CLOCK = 33513982 = 2*311*53881;
109 #if 0
110 ::irqSet(IRQ_TIMER(2), timer_callback);
111 ::irqEnable(IRQ_TIMER(2));
112 TIMER2_DATA = 0;
113 TIMER2_CR = TIMER_ENABLE | ::ClockDivider_1;
114 #endif
115 ::timerStart(2, ::ClockDivider_1, u16(TIMER_FREQ(1000)),
116 timer_callback);
117 #elif YCL_Win32
118 if(::QueryPerformanceFrequency(&g_ticks.hi.tps))
119 {
120 yunseq(p_tick_getter = get_ticks_hi_res,
121 p_tick_getter_nano = get_ticks_hi_res_nano),
122 ::QueryPerformanceCounter(&g_ticks.hi.start);
123 }
124 else
125 {
126 yunseq(p_tick_getter = get_ticks_mm,
127 p_tick_getter_nano = get_ticks_mm_nano),
128 ::timeBeginPeriod(1); //精度 1 毫秒。
129 // FIXME: ::timeEndPeriod shall be used at exit;
130 g_ticks.start = ::timeGetTime();
131 }
132 #elif YCL_Android
133 #else
134 # error "Unsupported platform found."
135 #endif
136 bUninitializedTimers = {};
137 };
138 }
139
140 std::uint32_t
141 GetTicks()
142 {
143 StartTicks();
144 #if YCL_DS
145 return system_tick;
146 #elif YCL_Win32
147 return p_tick_getter();
148 #elif YCL_Android
149 ::timespec now;
150
151 ::clock_gettime(CLOCK_MONOTONIC, &now);
152 return now.tv_sec * 1000ULL + now.tv_nsec / 1000000;
153 #endif
154 }
155
156 std::uint64_t
157 GetHighResolutionTicks()
158 {
159 StartTicks();
160 #if YCL_DS
161 return system_tick * 1000000ULL + TIMER2_DATA * 1000000ULL / BUS_CLOCK;
162 #elif YCL_Win32
163 return p_tick_getter_nano();
164 #elif YCL_Android
165 ::timespec now;
166
167 ::clock_gettime(CLOCK_MONOTONIC, &now);
168 return now.tv_sec * 1000000000ULL + now.tv_nsec;
169 #endif
170 }
171
172 }
173
platform::StartTicks
YF_API void StartTicks()
开始 tick 计时。
Definition: Timer.cpp:102
YModules.h
YB_UNLIKELY
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
platform::GetHighResolutionTicks
YF_API std::uint64_t GetHighResolutionTicks()
取高精度 tick 数。
Definition: Timer.cpp:157
platform::GetTicks
YF_API std::uint32_t GetTicks()
取 tick 数。
Definition: Timer.cpp:141
YSLib::u16
std::uint16_t u16
Definition: yadaptor.h:68