1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: lyt_Stopwatch.h 4 5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. 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 $Revision: 18342 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_LYT_STOPWATCH_H_ 17 #define NW_LYT_STOPWATCH_H_ 18 19 #include <climits> 20 #include <math.h> 21 #include <nw/sdk.h> 22 #include <nw/ut/ut_LinkList.h> 23 24 #ifdef NW_PLATFORM_CTR 25 #include <nn/os/os_Tick.h> 26 #endif 27 28 namespace nw { 29 namespace lyt { 30 namespace internal { 31 32 #define NW_LYT_PROFILE 1 33 34 #ifdef NW_LYT_PROFILE 35 # define NW_LYT_JOIN(x, y) NW_LYT_JOIN_AGAIN(x, y) 36 # define NW_LYT_JOIN_AGAIN(x, y) x ## y 37 38 # define NW_LYT_STOPWATCH_MEASURE(no, label) \ 39 nw::lyt::internal::Measure NW_LYT_JOIN(measure, __LINE__) ( \ 40 nw::lyt::internal::Stopwatch::Instance<no>(label), no) 41 42 # define NW_LYT_STOPWATCH_START(no, label) \ 43 if(nw::lyt::internal::Stopwatch::IsTarget(no)) \ 44 nw::lyt::internal::Stopwatch::Instance<no>().Start(label) 45 46 # define NW_LYT_STOPWATCH_STOP(no) \ 47 if(nw::lyt::internal::Stopwatch::IsTarget(no)) \ 48 nw::lyt::internal::Stopwatch::Instance<no>().Stop() 49 #else 50 # define NW_LYT_STOPWATCH_MEASURE(no, label) 51 # define NW_LYT_STOPWATCH_START(no, label) 52 # define NW_LYT_STOPWATCH_STOP(no) 53 #endif 54 55 #ifdef NW_PLATFORM_CTR 56 using nn::fnd::TimeSpan; 57 using nn::os::Tick; 58 #endif 59 60 //--------------------------------------------------------------------------- 61 //! 経過時間を計測します。 62 //--------------------------------------------------------------------------- 63 class Stopwatch : public nw::ut::LinkListNode 64 { 65 public: 66 static const s64 S64_MAX = (s64)(((u64)-1) >> 1); 67 68 //! インスタンスを保持するリストです。 69 typedef nw::ut::LinkList<Stopwatch, 0> List; 70 71 //! @brief コンストラクタです。 72 Stopwatch(int no = 0, const char* label = NULL); 73 74 //! @brief 計測を開始します。 75 //! 76 //! @param label 計測対象を示すラベルを指定できます。 77 //! 78 void Start(const char* label = NULL) 79 { 80 #ifndef NW_PLATFORM_CTR 81 NW_UNUSED_VARIABLE(label) 82 #else 83 if (label != NULL) 84 { 85 this->SetLabel(label); 86 } 87 88 NW_ASSERT(!this->IsRunning()); 89 90 m_StartTick = Tick::GetSystemCurrent(); 91 #endif 92 } 93 94 //! @brief 計測を停止します。 Stop()95 void Stop() 96 { 97 #ifdef NW_PLATFORM_CTR 98 Tick stopTick = Tick::GetSystemCurrent(); 99 100 NW_ASSERT(this->IsRunning()); 101 102 Tick elapsed = stopTick - m_StartTick; 103 m_StartTick = Tick(); 104 105 if (s64(elapsed) < m_MinSample) 106 { 107 m_MinSample = s64(elapsed); 108 } 109 110 if (s64(elapsed) > m_MaxSample) 111 { 112 m_MaxSample = s64(elapsed); 113 } 114 115 m_TotalTick += elapsed; 116 ++m_Count; 117 #endif 118 } 119 120 void Reset(); 121 122 static void ResetAll(); 123 124 //! @brief 番号を設定します。 SetNo(int no)125 void SetNo(int no) 126 { 127 #ifndef NW_PLATFORM_CTR 128 NW_UNUSED_VARIABLE(no); 129 #else 130 m_No = no; 131 #endif 132 } 133 134 //! @brief ラベルを設定します。 SetLabel(const char * label)135 void SetLabel(const char* label) 136 { 137 #ifndef NW_PLATFORM_CTR 138 NW_UNUSED_VARIABLE(label); 139 #else 140 m_Label = label; 141 #endif 142 } 143 144 #ifdef NW_PLATFORM_CTR 145 //! @brief 計測中か調べます。 IsRunning()146 bool IsRunning() const 147 { 148 return m_StartTick != Tick(); 149 } 150 151 //! @brief 番号を取得します。 GetNo()152 int GetNo() const 153 { 154 return m_No; 155 } 156 157 //! @brief ラベルを取得します。 GetLabel()158 const char* GetLabel() const 159 { 160 return m_Label; 161 } 162 163 //! @brief 経過時間の合計を取得します。 GetElapsedTime()164 const TimeSpan GetElapsedTime() const 165 { 166 return m_TotalTick; 167 } 168 169 //! @brief 測定回数を取得します。 GetCount()170 int GetCount() const 171 { 172 return m_Count; 173 } 174 175 //! @brief 最小値のサンプルを取得します。 GetMinSample()176 TimeSpan GetMinSample() const 177 { 178 if (m_Count == 0) 179 { 180 return Tick(0).ToTimeSpan(); 181 } 182 else 183 { 184 return Tick(m_MinSample).ToTimeSpan(); 185 } 186 } 187 188 //! @brief 最大値のサンプルを取得します。 GetMaxSample()189 TimeSpan GetMaxSample() const 190 { 191 if (m_Count == 0) 192 { 193 return Tick(0).ToTimeSpan(); 194 } 195 else 196 { 197 return Tick(m_MaxSample).ToTimeSpan(); 198 } 199 } 200 #endif 201 202 //! @brief インスタンスを取得します。 203 //! 204 //! @tparam no 計測対象に固有の番号を指定します。 205 //! @param label 計測対象を示すラベルが指定できます。 206 //! 207 template <int no> 208 static Stopwatch& Instance(const char* label = NULL) 209 { 210 static Stopwatch obj(no); 211 212 if (label != NULL) 213 { 214 obj.SetLabel(label); 215 } 216 217 return obj; 218 } 219 220 //! @brief インスタンスのリストを取得します。 GetList()221 static List& GetList() 222 { 223 static List list; 224 return list; 225 } 226 227 //! @brief 計測を有効にします。 228 //! @details 229 //! SetTargetNo() で全インスタンス番号を指定するのと等価です。 230 static void Enable(); 231 232 //! @brief 計測を無効にします。 233 //! @details 234 //! SetTargetNo() で min > max を指定するのと等価です。 235 static void Disable(); 236 237 //! @brief インスタンス番号が計測対象かどうかを判定します。 IsTarget(int no)238 static bool IsTarget(int no) 239 { 240 return s_TargetNoMin <= no && no <= s_TargetNoMax; 241 } 242 243 //! @brief 計測対象とするインスタンス番号の範囲を設定します。 SetTargetNo(int min,int max)244 static void SetTargetNo(int min, int max) 245 { 246 s_TargetNoMin = min; 247 s_TargetNoMax = max; 248 } 249 250 //! @brief 計測対象とするインスタンス番号を設定します。 SetTargetNo(int no)251 static void SetTargetNo(int no) 252 { 253 SetTargetNo(no, no); 254 } 255 256 //! @brief 計測結果をコンソールに出力します。 257 static void Dump(const Stopwatch& stopwatch); 258 259 //! @brief すべての計測結果をコンソールに出力します。 260 static void Dump(); 261 262 //! @brief 計測結果のヘッダを出力します。 263 static void DumpHeader(); 264 265 private: 266 #ifdef NW_PLATFORM_CTR 267 int m_Count; 268 int m_No; 269 const char* m_Label; 270 Tick m_TotalTick; 271 Tick m_StartTick; 272 s64 m_MinSample; 273 s64 m_MaxSample; 274 #endif 275 static int s_TargetNoMin; 276 static int s_TargetNoMax; 277 }; 278 279 //--------------------------------------------------------------------------- 280 //! 計測の開始と終了を自動化します。 281 //--------------------------------------------------------------------------- 282 class Measure 283 { 284 public: Measure(Stopwatch & stopwatch,int no)285 Measure(Stopwatch& stopwatch, int no) 286 : m_Stopwatch(stopwatch) 287 { 288 #ifdef NW_PLATFORM_CTR 289 if(Stopwatch::IsTarget(no)) 290 { 291 m_Stopwatch.Start(); 292 } 293 #endif 294 } 295 ~Measure()296 ~Measure() 297 { 298 #ifdef NW_PLATFORM_CTR 299 if(m_Stopwatch.IsRunning()) 300 { 301 m_Stopwatch.Stop(); 302 } 303 #endif 304 } 305 306 private: 307 Stopwatch& m_Stopwatch; 308 }; 309 310 } // namespace internal 311 } // namespace lyt 312 } // namespace nw 313 314 #endif // NW_LYT_STOPWATCH_H_ 315