PureBasic Forum
http://forums.purebasic.com/english/

High Resolution Timer Research
http://forums.purebasic.com/english/viewtopic.php?f=15&t=49365
Page 2 of 2

Author:  wilbert [ Mon Mar 05, 2012 8:01 pm ]
Post subject:  Re: High Resolution Timer Research

nanosleep does exist on both Linux and OS X if I'm correct
On OS X
Code:
Structure timespec
  tv_sec.i
  tv_nsec.l
EndStructure
   
ImportC ""
  nanosleep(*req.timespec, *rem.timespec = #Null)
EndImport

pause.timespec\tv_nsec = 300000
nanosleep(@pause)

On Linux you probably need to specify a library for ImportC and it's not very accurate.
There's also clock_delay_until(deadline.q)

Author:  Guimauve [ Mon Mar 05, 2012 8:14 pm ]
Post subject:  Re: High Resolution Timer Research

It's better and more safe to implement it this way :

Code:
Procedure NanoDelay(Nanoseconds.l)
 
  If Nanoseconds > 0 And Nanoseconds <= 999999999
    req.timespec\tv_nsec = Nanoseconds
    ProcedureReturn nanosleep(@req, #Null)
  Else
    ProcedureReturn -1
  EndIf
 
EndProcedure


But the Sleep will always be a little bit longer than expected. Maybe this is due to PureBasic Procedure calling time or the CPU load or both.

Best regards
Guimauve

Author:  infratec [ Sun Mar 16, 2014 1:03 am ]
Post subject:  Re: High Resolution Timer Research

An old thread, I know, but ...

I just tested this code on Win XP and ...
it failed.

A short debugging session found that
Code:
QueryPerformanceCounter_(@GetHighResTimerStartCount(*HighResTimerA))
failed with
LastError 998, which means No Access.

I tried it with
Code:
Define TimerQ.q

If QueryPerformanceFrequency_(@TimerQ) = 0
  Debug GetLastError_()
EndIf

Debug TimerQ

And it worked.

But with the structure it worked not.
I checked the address of \Frequency and it was Ok.

I need to use
Code:
Structure HighResTimer Align #PB_Structure_AlignC


Than it worked.

I have no explanation for that, since the single quad variable is also not aligned, or is it ?

Bernd

Author:  StarBootics [ Fri Jun 29, 2018 4:16 pm ]
Post subject:  Re: High Resolution Timer Research

Hello everyone,

Sorry to re-open a very old thread but it's fully related even after so many years. Since I'm a Module Addict I have converted Guimauve's HighResTimer into a Module.

Code:
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : HighResTimer
; File Name : HighResTimer - Module.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 29-06-2018
; Last Update : 29-06-2018
; PureBasic code : V5.70 beta 1
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Programming notes :
;
; Based on Guimauve's original code.
; https://www.purebasic.fr/english/viewtopic.php?f=15&t=49365
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule HighResTimer
 
  Declare Initialize()
  Declare Reset()
  Declare Start()
  Declare Stop()
  Declare.q Consult()
 
EndDeclareModule

Module HighResTimer
 
  CompilerSelect #PB_Compiler_OS
     
    CompilerCase #PB_OS_Linux
     
      #CLOCK_MONOTONIC = 1
     
      Structure TimeSpec
        Second.i
        NanoSecond.l
      EndStructure
     
      ImportC "-lrt"
        clock_gettime(ClockID.l, *TimeSpecA.TimeSpec)
      EndImport
     
    CompilerCase #PB_OS_MacOS
     
      Structure TimeBase
        Numerator.l
        Denominator.l
      EndStructure
     
      ImportC ""
        mach_absolute_time.q()
        mach_timebase_info(*TimeBaseA.TimeBase)
      EndImport
     
  CompilerEndSelect
 
  Structure Instance
   
    IsRunning.b
    StartMicroSec.q
    StopMicroSec.q
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        Frequency.q
        StartCount.q
        EndCount.q
       
      CompilerCase #PB_OS_Linux
        StartCount.TimeSpec
        EndCount.TimeSpec
       
      CompilerCase #PB_OS_MacOS
        MicroSecConversion.d
        TimeBase.TimeBase
        StartCount.q
        EndCount.q
       
    CompilerEndSelect
   
  EndStructure
 
  Global Instance.Instance
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The New Operator <<<<<
 
  Procedure Initialize()
   
    Instance\IsRunning = #False
    Instance\StartMicroSec = 0
    Instance\StopMicroSec = 0
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        QueryPerformanceFrequency_(@Instance\Frequency)
        Instance\StartCount = 0
        Instance\EndCount = 0
       
      CompilerCase #PB_OS_Linux
        Instance\StartCount\Second = 0
        Instance\StartCount\NanoSecond = 0
        Instance\EndCount\Second = 0
        Instance\EndCount\NanoSecond = 0
       
      CompilerCase #PB_OS_MacOS
        mach_timebase_info(@Instance\TimeBase)
        Instance\MicroSecConversion = 1e-3 * Instance\TimeBase\Numerator / Instance\TimeBase\Denominator
        Instance\StartCount = 0
        Instance\EndCount = 0
       
    CompilerEndSelect
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Reset Operator <<<<<
 
  Procedure Reset()
   
    Instance\IsRunning = 0
    Instance\StartMicroSec = 0
    Instance\StopMicroSec = 0
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        Instance\Frequency = 0
        Instance\StartCount = 0
        Instance\EndCount = 0
       
      CompilerCase #PB_OS_Linux
        Instance\StartCount\Second = 0
        Instance\StartCount\NanoSecond = 0
        Instance\EndCount\Second = 0
        Instance\EndCount\NanoSecond = 0
       
      CompilerCase #PB_OS_MacOS
        Instance\MicroSecConversion = 0.0
        Instance\TimeBase\Numerator = 0
        Instance\TimeBase\Denominator = 0
        Instance\StartCount = 0
        Instance\EndCount = 0
       
    CompilerEndSelect
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Start operator <<<<<
 
  Procedure Start()
   
    Instance\IsRunning = #True
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        QueryPerformanceCounter_(@Instance\StartCount)
       
      CompilerCase #PB_OS_Linux
        clock_gettime(#CLOCK_MONOTONIC, @Instance\StartCount)
       
      CompilerCase #PB_OS_MacOS
        Instance\StartCount = mach_absolute_time() * Instance\MicroSecConversion
       
    CompilerEndSelect
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The Stop operator <<<<<
 
  Procedure Stop()
   
    Instance\IsRunning = #False
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
        QueryPerformanceCounter_(@Instance\EndCount)
       
      CompilerCase #PB_OS_Linux
        clock_gettime(#CLOCK_MONOTONIC, @Instance\EndCount)
       
      CompilerCase #PB_OS_MacOS
        Instance\EndCount = mach_absolute_time() * Instance\MicroSecConversion
       
    CompilerEndSelect
   
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< The ElapsedMicroSec <<<<<
 
  Procedure.q Consult()
   
    CompilerSelect #PB_Compiler_OS
       
      CompilerCase #PB_OS_Windows
       
        If Instance\IsRunning = #True
          QueryPerformanceCounter_(@Instance\EndCount)
        EndIf
       
        Instance\StartMicroSec = Instance\StartCount * (1000000.0 / Instance\Frequency)
        Instance\StopMicroSec = Instance\EndCount * (1000000.0 / Instance\Frequency)
       
      CompilerCase #PB_OS_Linux
       
        If Instance\IsRunning = #True
          clock_gettime(#CLOCK_MONOTONIC, @Instance\EndCount)
        EndIf
       
        Instance\StartMicroSec = Instance\StartCount\Second * 1000000 + Instance\StartCount\NanoSecond / 1000
        Instance\StopMicroSec = Instance\EndCount\Second * 1000000 + Instance\EndCount\NanoSecond / 1000
       
      CompilerCase #PB_OS_MacOS
       
        If Instance\IsRunning = #True
          Instance\EndCount = mach_absolute_time() * Instance\MicroSecConversion
        EndIf
       
        Instance\StartMicroSec = Instance\StartCount
        Instance\StopMicroSec = Instance\EndCount
       
    CompilerEndSelect
   
    ProcedureReturn Instance\StopMicroSec - Instance\StartMicroSec
  EndProcedure
 
EndModule

CompilerIf #PB_Compiler_IsMainFile
 
  HighResTimer::Initialize()
 
  HighResTimer::Start()
 
  Delay(1)
  Debug HighResTimer::Consult()
 
  Delay(5)
  Debug HighResTimer::Consult()
 
  Delay(499)
  Debug HighResTimer::Consult()
 
  Delay(500)
  Debug HighResTimer::Consult()
 
  Delay(1499)
  Debug HighResTimer::Consult()
 
  Delay(1501)
  Debug HighResTimer::Consult()
 
  HighResTimer::Stop()
  HighResTimer::Reset()
 
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<

Best regards.
StarBootics

Page 2 of 2 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/