YSTest: Timer.cpp 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
Timer.cpp
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2012 - 2013.
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/Timer.h"
29 #include "YCLib/NativeAPI.h"
30 #if YCL_MINGW32
31 # include <mmsystem.h> // for multimedia timers;
32 #endif
33
34 namespace platform
35 {
36
37 namespace
38 {
39 bool bUninitializedTimers(true);
40 #if YCL_DS
41 volatile std::uint32_t system_tick;
42
43 void
44 timer_callback()
45 {
46 ++system_tick;
47 }
48 #elif YCL_MINGW32
49 std::uint32_t(*p_tick_getter)();
50 std::uint64_t(*p_tick_getter_nano)();
51 union
52 {
53 ::DWORD start;
54 struct
55 {
56 ::LARGE_INTEGER start;
57 ::LARGE_INTEGER tps;
58 } hi;
59 } g_ticks;
60
61 std::uint32_t
62 get_ticks_hi_res()
63 {
64 ::LARGE_INTEGER now;
65
66 ::QueryPerformanceCounter(&now);
67 now.QuadPart -= g_ticks.hi.start.QuadPart;
68 now.QuadPart *= 1000;
69 return ::DWORD(now.QuadPart / g_ticks.hi.tps.QuadPart);
70 }
71
72 std::uint64_t
73 get_ticks_hi_res_nano()
74 {
75 ::LARGE_INTEGER now;
76
77 ::QueryPerformanceCounter(&now);
78 now.QuadPart -= g_ticks.hi.start.QuadPart;
79 now.QuadPart *= 1000000000;
80 return now.QuadPart / g_ticks.hi.tps.QuadPart;
81 }
82
83 std::uint32_t
84 get_ticks_mm()
85 {
86 ::DWORD now(::timeGetTime());
87
88 return now < g_ticks.start ? (~::DWORD(0) - g_ticks.start) + now
89 : now - g_ticks.start;
90 }
91
92 std::uint64_t
93 get_ticks_mm_nano()
94 {
95 return get_ticks_mm() * 1000000;
96 }
97 #endif
98 }
99
100 void
101 StartTicks()
102 {
103 if(bUninitializedTimers)
104 {
105 #if YCL_DS
106 // f = 33.513982MHz;
107 // BUS_CLOCK = 33513982 = 2*311*53881;
108 #if 0
109 ::irqSet(IRQ_TIMER(2), timer_callback);
110 ::irqEnable(IRQ_TIMER(2));
111 TIMER2_DATA = 0;
112 TIMER2_CR = TIMER_ENABLE | ::ClockDivider_1;
113 #endif
114 ::timerStart(2, ::ClockDivider_1, u16(TIMER_FREQ(1000)),
115 timer_callback);
116 #elif YCL_MINGW32
117 if(::QueryPerformanceFrequency(&g_ticks.hi.tps))
118 {
119 yunseq(p_tick_getter = get_ticks_hi_res,
120 p_tick_getter_nano = get_ticks_hi_res_nano),
121 ::QueryPerformanceCounter(&g_ticks.hi.start);
122 }
123 else
124 {
125 yunseq(p_tick_getter = get_ticks_mm,
126 p_tick_getter_nano = get_ticks_mm_nano),
127 ::timeBeginPeriod(1); //精度 1 毫秒。
128 // FIXME: ::timeEndPeriod shall be used at exit;
129 g_ticks.start = ::timeGetTime();
130 }
131 #else
132 # error Unsupported platform found!
133 #endif
134 bUninitializedTimers = false;
135 };
136 }
137
138 std::uint32_t
139 GetTicks()
140 {
141 StartTicks();
142 #if YCL_DS
143 return system_tick;
144 #elif YCL_MINGW32
145 return p_tick_getter();
146 #else
147 # error Unsupported platform found!
148 #endif
149 }
150
151 std::uint64_t
152 GetHighResolutionTicks()
153 {
154 StartTicks();
155 #if YCL_DS
156 return system_tick * 1000000ULL
157 + TIMER2_DATA * 1000000ULL / BUS_CLOCK;
158 #elif YCL_MINGW32
159 return p_tick_getter_nano();
160 #else
161 # error Unsupported platform found!
162 #endif
163 }
164
165 }
166