High-Res time and related functions

new topic     » topic index » view thread      » older message » newer message

Here is another high-resolution time library which differs from previous ones by following points:

  • usable in windows and linux
  • improved set_rand (called randomize(): does not give the same behaviour if called twice in less than a second)
  • cant generate UUIDs
include std/dll.e 
include std/machine.e 
include std/os.e 
include std/rand.e 
ifdef WINDOWS then 
  include std/win32/msgbox.e 
end ifdef  
 
--*------------------------------------------------------* 
-- reference high resolution timer libraries 
--*------------------------------------------------------* 
ifdef WINDOWS then 
 
atom k32 = open_dll("kernel32") 
if k32 = -1 then 
  error_message("kernel32.dll can\'t be opened.", 1) 
end if 
atom perf_frq_ = define_c_func(k32, "QueryPerformanceFrequency", {C_UINT}, C_UINT) 
atom perf_cnt_ = define_c_proc(k32, "QueryPerformanceCounter", {C_UINT}) 
if (perf_cnt_=-1) or (perf_frq_=-1) then 
  error_message("The current Windows version does not support hi-res timers.", 1) 
end if 
 
-------------------------------------------------------------------------------- 
 
procedure error_message(sequence msg, atom quit) 
ifdef WINDOWS then 
  object void = message_box(msg, "Error", MB_ICONERROR+MB_OK+MB_APPLMODAL+MB_SETFOREGROUND) 
elsifdef LINUX then 
  puts(2, "Error: " & msg & "\n") 
end ifdef 
  if quit then abort(1) end if 
end procedure 
 
-------------------------------------------------------------------------------- 
 
-- retrieves the frequency of the performance counter, in ticks per second 
public function QueryPerformanceFrequency() 
  atom lpFrequency = allocate(8) 
  if not c_func(perf_frq_, {lpFrequency}) then 
    error_message("Your hardware does not support hi-res timers.", 1) 
  end if 
  atom ticks_per_sec = peek8u(lpFrequency) 
  free(lpFrequency) 
  return ticks_per_sec 
end function 
 
-------------------------------------------------------------------------------- 
 
-- retrieves the current value of the performance counter, in ticks, which is 
-- a high resolution (<1us) time stamp 
public function QueryPerformanceCounter() 
  atom lpTicks = allocate(8) 
  c_proc(perf_cnt_, {lpTicks}) 
  atom ticks = peek8u(lpTicks) 
  free(lpTicks) 
  return ticks 
end function 
 
-------------------------------------------------------------------------------- 
 
-- returns an atom: number of seconds since PC has started, accurate up to 1us 
-- hires_time()*1000 = number of milliseconds since PC has started 
public function hires_time() 
  atom ticks_per_sec = QueryPerformanceFrequency() 
  atom ticks = QueryPerformanceCounter() 
  return ticks/ticks_per_sec 
end function 
 
elsifdef LINUX then 
 
constant 
  CLOCK_REALTIME  =  0, 
  CLOCK_MONOTONIC =  1 
 
atom clock_gettime_ = define_c_func(open_dll(""), "clock_gettime", {C_POINTER, C_POINTER}, C_INT) 
 
public function get_time() 
  atom timep = allocate( sizeof( C_POINTER ) ) 
  sequence time = {0, 0} 
  if c_func(clock_gettime_, {CLOCK_MONOTONIC, timep}) then 
    error_message("Your hardware does not support hi-res timers.", 1) 
  end if 
  time = peek_longu({timep, 2}) 
  free(timep) 
  return time 
end function 
 
-- returns an atom: number of seconds since PC has started, accurate up to 1ns 
-- hires_time()*1000 = number of milliseconds since PC has started 
public function hires_time() 
  atom secs, nsecs 
  {secs, nsecs} = get_time() 
  return secs + nsecs/1e9 
end function 
 
end ifdef 
 
-------------------------------------------------------------------------------- 
 
-- better randomization than set_rand(time()) because it gives different results 
-- even if called twice in less than a second 
public procedure randomize() 
  set_rand(hires_time()*1000) 
end procedure 
 
-------------------------------------------------------------------------------- 
 
public function gen_uuid() 
  -- following line converted from PHP: https://www.ts-services.com/generation-uuid-php/ 
  return sprintf( 
    "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", 
    { 
      rand_range(0, #FFFF), 
      rand_range(0, #FFFF), 
      rand_range(0, #FFFF), 
      or_bits(rand_range(0, #0FFF), #4000), 
      or_bits(rand_range(0, #3FFF), #8000), 
      rand_range(0, #FFFF), 
      rand_range(0, #FFFF), 
      rand_range(0, #FFFF) 
    } 
 ) 
end function 

Jean-Marc

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu