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
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
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
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