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
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
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
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 
YF_API void StartTicks()
开始 tick 计时。
Definition: Timer.cpp:102
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
YF_API std::uint64_t GetHighResolutionTicks()
取高精度 tick 数。
Definition: Timer.cpp:157
YF_API std::uint32_t GetTicks()
取 tick 数。
Definition: Timer.cpp:141
std::uint16_t u16
Definition: yadaptor.h:68