Comme je fais quelques recherches 'crossplatform' pour mon projet, je me permets de poster ma solution pour avoir un timer précis à la nanoseconde fonctionnant sur Windows, Linux et Mac OS X:
N'hésitez pas à m'indiquer si vous avez un soucis avec. Je l'ai testé sur:
- Windows 7 - 64bit
- Linux Ubuntu 12.04.1 - 64bit
- Mac OSX Lion 10.7.2 - 64bit
Code : Tout sélectionner
; ============================================================================
; IMPORT
; ============================================================================
;{
CompilerSelect #PB_Compiler_OS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; WINDOWS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CompilerCase #PB_OS_Windows
; NOP
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; LINUX
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CompilerCase #PB_OS_Linux
#CLOCK_MONOTONIC = 1
Structure timespec_t
tv_sec.i
tv_nsec.i
EndStructure
ImportC ""
clock_getres.i ( clock_id.i, *res.timespec_t )
clock_gettime.i( clock_id.i, *tp.timespec_t )
EndImport
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; MAC OS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CompilerCase #PB_OS_MacOS
Structure mach_timebase_info_t
numer.l
denom.l
EndStructure
ImportC ""
mach_timebase_info.i( *info.mach_timebase_info_t )
mach_absolute_time.q()
EndImport
CompilerEndSelect
;}
; ============================================================================
; GLOBALS
; ============================================================================
;{
Global s_qpc_start.d
Global s_qpc_res .d
;}
; ============================================================================
; PROCEDURES
; ============================================================================
;{
; ----------------------------------------------------------------------------
; raaQPCInitOnce
; ----------------------------------------------------------------------------
Procedure raaQPCInitOnce()
CompilerSelect #PB_Compiler_OS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; WINDOWS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;{
CompilerCase #PB_OS_Windows
Protected v.q = 0
If Not QueryPerformanceFrequency_( @v )
MessageRequester( "Performance Counter", "High-Resolution Performance Counter NOT Supported!" )
End
EndIf
If Not v
MessageRequester( "Performance Counter", "High-Resolution Performance Counter NOT Supported!" )
End
EndIf
s_qpc_res = 1.0/v
QueryPerformanceCounter_( @v )
s_qpc_start = v*s_qpc_res
;}
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; LINUX
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;{
CompilerCase #PB_OS_Linux
Protected v.timespec_t
If clock_getres( #CLOCK_MONOTONIC, @v )
MessageRequester( "Performance Counter", "High-Resolution Performance Counter NOT Supported!" )
End
EndIf
s_qpc_res = 1.0e-9*v\tv_nsec
If clock_gettime( #CLOCK_MONOTONIC, @v )
MessageRequester( "Performance Counter", "High-Resolution Performance Counter NOT Supported!" )
End
EndIf
s_qpc_start = v\tv_sec + v\tv_nsec*s_qpc_res
;}
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; MAC OS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;{
CompilerCase #PB_OS_MacOS
Protected v.mach_timebase_info_t
mach_timebase_info( @v ) ; returned error ?
s_qpc_res = 1.0e-9 * v\numer / v\denom
s_qpc_start = mach_absolute_time()*s_qpc_res
;}
CompilerEndSelect
EndProcedure
; ----------------------------------------------------------------------------
; raaQPCGetAppTime
; ----------------------------------------------------------------------------
Procedure.d raaQPCGetAppTime()
CompilerSelect #PB_Compiler_OS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; WINDOWS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;{
CompilerCase #PB_OS_Windows
Protected time.q = 0
QueryPerformanceCounter_( @time )
ProcedureReturn time*s_qpc_res - s_qpc_start
;}
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; LINUX
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;{
CompilerCase #PB_OS_Linux
Protected v.timespec_t
clock_gettime( #CLOCK_MONOTONIC, @v )
ProcedureReturn v\tv_sec + v\tv_nsec*s_qpc_res - s_qpc_start
;}
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; MAC OS
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;{
CompilerCase #PB_OS_MacOS
ProcedureReturn mach_absolute_time()*s_qpc_res - s_qpc_start
;}
CompilerEndSelect
EndProcedure
;}
; ============================================================================
; MAIN
; ============================================================================
raaQPCInitOnce()
Delay( 1000 )
MessageRequester( "Query Performance Counter", "Delay after ~1sec : "+ StrD(raaQPCGetAppTime()) )
End
; ============================================================================
; EOF
; ============================================================================
Guy.