| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | |
| 5 | // |
| 6 | // CycleTimer has methods related to getting cycle timer values. |
| 7 | // It uses an all-statics class as a namespace mechanism. |
| 8 | // |
| 9 | |
| 10 | #ifndef _CYCLETIMER_H_ |
| 11 | #define _CYCLETIMER_H_ |
| 12 | |
| 13 | #include "windef.h" |
| 14 | |
| 15 | class CycleTimer |
| 16 | { |
| 17 | // This returns the value of the *non-thread-virtualized* cycle counter. |
| 18 | static unsigned __int64 GetCycleCount64(); |
| 19 | |
| 20 | |
| 21 | // This wraps GetCycleCount64 in the signature of QueryThreadCycleTime -- but note |
| 22 | // that it ignores the "thrd" argument. |
| 23 | static BOOL WINAPI DefaultQueryThreadCycleTime(__in HANDLE thrd, __out PULONG64 cyclesPtr); |
| 24 | |
| 25 | // The function pointer type for QueryThreadCycleTime. |
| 26 | typedef BOOL (WINAPI *QueryThreadCycleTimeSig)(__in HANDLE, __out PULONG64); |
| 27 | |
| 28 | // Returns a function pointer for QueryThreadCycleTime, or else BadFPtr. |
| 29 | static QueryThreadCycleTimeSig GetQueryThreadCycleTime(); |
| 30 | |
| 31 | // Initialized once from NULL to either BadFPtr or QueryThreadCycleTime. |
| 32 | static QueryThreadCycleTimeSig s_QueryThreadCycleTimeFPtr; |
| 33 | |
| 34 | public: |
| 35 | |
| 36 | // This method computes the number of cycles/sec for the current machine. The cycles are those counted |
| 37 | // by GetThreadCycleTime; we assume that these are of equal duration, though that is not necessarily true. |
| 38 | // If any OS interaction fails, returns 0.0. |
| 39 | static double CyclesPerSecond(); |
| 40 | |
| 41 | // Does a large number of queries, and returns the average of their overhead, so other measurements |
| 42 | // can adjust for this. |
| 43 | static unsigned __int64 QueryOverhead(); |
| 44 | |
| 45 | // There's no "native" atomic add for 64 bit, so we have this convenience function. |
| 46 | static void InterlockedAddU64(unsigned __int64* loc, unsigned __int64 amount); |
| 47 | |
| 48 | // Attempts to query the cycle counter of the current thread. If successful, returns "true" and sets |
| 49 | // *cycles to the cycle counter value. Otherwise, returns false. Note that the value returned is (currently) |
| 50 | // virtualized to the current thread only on Windows; on non-windows x86/x64 platforms, directly reads |
| 51 | // the cycle counter and returns that value. |
| 52 | static bool GetThreadCyclesS(unsigned __int64* cycles); |
| 53 | }; |
| 54 | |
| 55 | #endif // _CYCLETIMER_H_ |
| 56 | |
| 57 | |