1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2019-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 #pragma once 10 11 #include "types.h" 12 13 #if defined _WIN32 14 # include <wtypes.h> 15 # include <winbase.h> 16 # include <intrin.h> 17 #else 18 # include <time.h> 19 # include <x86intrin.h> 20 # ifndef NSEC_PER_SEC 21 # define NSEC_PER_SEC 1000000000L 22 # endif 23 #endif 24 25 namespace iSTD 26 { 27 /*****************************************************************************\ 28 Inline Function: 29 Pause 30 31 Description: 32 executes __asm pause 33 \*****************************************************************************/ Pause(void)34__forceinline void Pause( void ) 35 { 36 _mm_pause(); 37 } 38 39 #if defined _WIN32 40 /*****************************************************************************\ 41 Inline Function: 42 GetTimestampCounter 43 44 Description: 45 Returns the number of CPU clock cycles since the last reset. 46 \*****************************************************************************/ GetTimestampCounter(void)47__forceinline QWORD GetTimestampCounter( void ) 48 { 49 #ifdef ISTDLIB_UMD 50 { 51 QWORD count = 0; 52 ::QueryPerformanceCounter( (LARGE_INTEGER*)&count ); 53 return count; 54 } 55 #else // !ISTDLIB_UMD 56 { 57 #ifdef _WIN64 58 { 59 return __rdtsc(); 60 } 61 #else // !_WIN64 62 { 63 __asm rdtsc; 64 } 65 #endif // _WIN64 66 } 67 #endif // ISTDLIB_UMD 68 } 69 70 /*****************************************************************************\ 71 Inline Function: 72 GetTimestampFrequency 73 74 Description: 75 Returns the frequency of the CPU clock cycles 76 \*****************************************************************************/ GetTimestampFrequency(void)77__forceinline QWORD GetTimestampFrequency( void ) 78 { 79 #ifdef ISTDLIB_UMD 80 { 81 QWORD frequency = 0; 82 ::QueryPerformanceFrequency( (LARGE_INTEGER*)&frequency ); 83 return frequency; 84 } 85 #else // !ISTDLIB_UMD 86 { 87 // Note: Use the following for Conroe 2.4GHz 88 // return 2394050000; 89 90 return 0; 91 } 92 #endif // ISTDLIB_UMD 93 } 94 95 /*****************************************************************************\ 96 Inline Function: 97 Wait 98 99 Description: 100 Waits for some number of milliseconds to complete 101 \*****************************************************************************/ Wait(const DWORD milliseconds)102__forceinline void Wait( const DWORD milliseconds ) 103 { 104 const QWORD clocksPerSecond = GetTimestampFrequency(); 105 const QWORD clocksPerMilliSecond = ( clocksPerSecond > 1000 ) ? clocksPerSecond / 1000 : 1; 106 const QWORD clocks = milliseconds * clocksPerMilliSecond; 107 108 const QWORD start = GetTimestampCounter(); 109 while( clocks < ( GetTimestampCounter() - start ) ) 110 { 111 Pause(); 112 }; 113 } 114 115 #else 116 117 /*****************************************************************************\ 118 Inline Function: 119 GetTimestampCounter 120 121 Description: 122 Returns the value of high resolution performance counter 123 \*****************************************************************************/ GetTimestampCounter(void)124__forceinline QWORD GetTimestampCounter( void ) 125 { 126 struct timespec time; 127 clock_gettime(CLOCK_MONOTONIC, &time); 128 return (QWORD)time.tv_nsec + 129 (QWORD)time.tv_sec * (QWORD)NSEC_PER_SEC; 130 131 } 132 133 /*****************************************************************************\ 134 Inline Function: 135 GetTimestampFrequency 136 137 Description: 138 Returns the frequency of high resolution performance counter. 139 On Linux/Android we use timer with nsec accuracy 140 \*****************************************************************************/ GetTimestampFrequency(void)141__forceinline QWORD GetTimestampFrequency( void ) 142 { 143 return NSEC_PER_SEC; 144 } 145 146 #endif 147 148 } // iSTD 149