1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     os_Tick.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 23609 $
14  *---------------------------------------------------------------------------*/
15 
16 /*! @file
17     @brief      Tick に関する API の宣言
18 
19     :include nn/os.h
20 */
21 
22 #ifndef NN_OS_OS_TICK_H_
23 #define NN_OS_OS_TICK_H_
24 
25 #include <nn/svc.h>
26 #include <nn/os/os_HardwareParamsSelect.h>
27 #include <nn/fnd/fnd_TimeSpan.h>
28 #include <nn/math/math_Misccellaneous.h>
29 
30 #ifdef __cplusplus
31 
32 namespace nn { namespace os {
33 
34 /*!
35     @brief システムチックを扱う為のクラスです。
36 
37            システムチックは、CPU の 1 クロックの時間を表します。
38            変換コンストラクタ・変換演算子を使うことで、実際の時間を表す @ref nn::fnd::TimeSpan との相互変換ができます。
39            システムが立ち上がってからのチック数を取得するには @ref GetSystemCurrent を使います。
40 
41 */
42 class Tick
43 {
44 public:
45 
46     /*!
47         @brief チック数を取ってオブジェクトを初期化するコンストラクタです。
48 
49         @param[in] tick チック数
50     */
m_Tick(tick)51     explicit Tick(s64 tick = 0) : m_Tick(tick) {}
52 
53     /*!
54         @brief TimeSpan を取ってオブジェクトを初期化するコンストラクタです。
55 
56         @param[in] span 初期化する時間の値
57     */
58     Tick(nn::fnd::TimeSpan span);
59 
60     /*!
61         @brief 64bit のチック値に変換します。
62     */
s64()63     operator s64() const { return m_Tick; }
64 
65     /*!
66         @brief @ref nn::fnd::TimeSpan の値に変換します。
67     */
68     operator nn::fnd::TimeSpan() const;
69 
70     /*!
71         @brief @ref nn::fnd::TimeSpan の値に変換します。
72 
73         @return チックと同じ時間を表す @ref nn::fnd::TimeSpan オブジェクトを返します。
74     */
75     nn::fnd::TimeSpan ToTimeSpan() const;
76 
77     /*!
78         @brief      システムが起動してからのチック数を返します。
79 
80         @return     システムの Tick 値。
81     */
82     static Tick GetSystemCurrent();
83 
84     /*!
85         @brief 1秒間のチック数を表す定数です。
86     */
87     static const s64 TICKS_PER_SECOND  = NN_HW_TICKS_PER_SECOND;
88 
89     Tick& operator-=(Tick rhs) { this->m_Tick -= rhs.m_Tick; return *this; }
90     Tick operator-(Tick rhs) const { Tick ret(*this); return ret -= rhs; }
91 
92     Tick& operator+=(Tick rhs) { this->m_Tick += rhs.m_Tick; return *this; }
93     Tick operator+(Tick rhs) const { Tick ret(*this); return ret += rhs; }
94 
95     inline Tick& operator+=(fnd::TimeSpan rhs);
96     Tick operator+(fnd::TimeSpan rhs) const { Tick ret(*this); return ret += rhs; }
97 
98 private:
99     s64 m_Tick;
100 };
101 
102 
GetSystemCurrent()103 inline Tick Tick::GetSystemCurrent()
104 {
105     return Tick(nn::svc::GetSystemTick());
106 }
107 
Tick(nn::fnd::TimeSpan span)108 inline Tick::Tick(nn::fnd::TimeSpan span) : m_Tick(nnmathMultiplyAndDivide(span.GetNanoSeconds(), TICKS_PER_SECOND, 1000 * 1000 * 1000))
109 {
110 }
111 
TimeSpan()112 inline Tick::operator nn::fnd::TimeSpan() const
113 {
114     return nn::fnd::TimeSpan::FromNanoSeconds(nnmathMultiplyAndDivide(m_Tick, 1000 * 1000 * 1000, TICKS_PER_SECOND));
115 }
116 
ToTimeSpan()117 inline nn::fnd::TimeSpan Tick::ToTimeSpan() const
118 {
119     return *this;
120 }
121 
122 inline Tick& Tick::operator+=(fnd::TimeSpan rhs)
123 {
124     const s64 tick = nnmathMultiplyAndDivide(rhs.GetNanoSeconds(), TICKS_PER_SECOND, 1000 * 1000 * 1000);
125     this->m_Tick += tick;
126     return *this;
127 }
128 
129 }}
130 
131 #endif // __cplusplus
132 
133 // 以下、C 用宣言
134 
135 #include <nn/util/detail/util_CLibImpl.h>
136 
137 /*!
138   @addtogroup   nn_os
139   @{
140 
141   @defgroup     nn_os_Tick_c     Tick (C)
142 
143   @brief        @ref nn::os::Tick の C インタフェースモジュールです。
144 
145   @{
146 */
147 
148 /*!
149     @brief      ナノ秒から Tick 値へ変換します。
150 
151     @param[in]  ns        変換元の値(ナノ秒)
152 
153     @return     変換の結果を Tick 値で返します。
154 */
nnosTickConvertFromNanoSeconds(s64 ns)155 NN_EXTERN_C inline s64 nnosTickConvertFromNanoSeconds(s64 ns)
156 {
157     return nnmathMultiplyAndDivide(ns, NN_HW_TICKS_PER_SECOND, 1000 * 1000 * 1000);
158 }
159 
160 /*!
161     @brief      マイクロ秒から Tick 値へ変換します。
162 
163     @param[in]  us        変換元の値(マイクロ秒)
164 
165     @return     変換の結果を Tick 値で返します。
166 */
nnosTickConvertFromMicroSeconds(s64 us)167 NN_EXTERN_C inline s64 nnosTickConvertFromMicroSeconds(s64 us)
168 {
169     return nnmathMultiplyAndDivide(us, NN_HW_TICKS_PER_SECOND, 1000 * 1000);
170 }
171 
172 /*!
173     @brief      ミリ秒から Tick 値へ変換します。
174 
175     @param[in]  ms        変換元の値(ミリ秒)
176 
177     @return     変換の結果を Tick 値で返します。
178 */
nnosTickConvertFromMilliSeconds(s64 ms)179 NN_EXTERN_C inline s64 nnosTickConvertFromMilliSeconds(s64  ms)
180 {
181     return nnmathMultiplyAndDivide(ms, NN_HW_TICKS_PER_SECOND, 1000);
182 }
183 
184 /*!
185     @brief      秒から Tick 値へ変換します。
186 
187     @param[in]  s         変換元の値(秒)
188 
189     @return     変換の結果を Tick 値で返します。
190 */
nnosTickConvertFromSeconds(s64 s)191 NN_EXTERN_C inline s64 nnosTickConvertFromSeconds(s64 s)
192 {
193     return nnmathMultiplyAndDivide(s, NN_HW_TICKS_PER_SECOND, 1);
194 }
195 
196 /*!
197     @brief      Tick 値をナノ秒へ変換します。
198 
199     @param[in]  tick      変換元のTick 値
200 
201     @return     変換の結果を ナノ秒で返します。
202 */
nnosTickConvertToNanoSeconds(s64 tick)203 NN_EXTERN_C inline s64 nnosTickConvertToNanoSeconds(s64 tick)
204 {
205     return nnmathMultiplyAndDivide(tick, 1000 * 1000 * 1000, NN_HW_TICKS_PER_SECOND);
206 }
207 
208 /*!
209     @brief      Tick 値をマイクロ秒へ変換します。
210 
211     @param[in]  tick      変換元のTick 値
212 
213     @return     変換の結果を マイクロ秒で返します。
214 */
nnosTickConvertToMicroSeconds(s64 tick)215 NN_EXTERN_C inline s64 nnosTickConvertToMicroSeconds(s64 tick)
216 {
217     return nnmathMultiplyAndDivide(tick, 1000 * 1000, NN_HW_TICKS_PER_SECOND);
218 }
219 
220 /*!
221     @brief      Tick 値をミリ秒へ変換します。
222 
223     @param[in]  tick      変換元のTick 値
224 
225     @return     変換の結果をミリ秒で返します。
226 */
nnosTickConvertToMilliSeconds(s64 tick)227 NN_EXTERN_C inline s64 nnosTickConvertToMilliSeconds(s64 tick)
228 {
229     return nnmathMultiplyAndDivide(tick, 1000, NN_HW_TICKS_PER_SECOND);
230 }
231 
232 /*!
233     @brief      Tick 値を秒へ変換します。
234 
235     @param[in]  tick      変換元のTick 値
236 
237     @return     変換の結果を秒で返します。
238 */
nnosTickConvertToSeconds(s64 tick)239 NN_EXTERN_C inline s64 nnosTickConvertToSeconds(s64 tick)
240 {
241     return nnmathMultiplyAndDivide(tick, 1, NN_HW_TICKS_PER_SECOND);
242 }
243 
244 /*!
245   @brief 対応する C++ 関数 @ref nn::os::Tick::GetSystemCurrent を参照してください。
246 */
247 NN_EXTERN_C s64 nnosTickGetSystemCurrent(void);
248 
249 /*!
250   @}
251 
252   @}
253 */
254 
255 #endif /* NN_OS_OS_TICK_H_ */
256