1. High-Res time and related functions

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 message » categorize

2. Re: High-Res time and related functions

jmduro said...
ifdef WINDOWS then 
 
procedure error_message(sequence msg, atom quit) 
 
elsifdef LINUX then 
 
    error_message("Your hardware does not support hi-res timers.", 1) 
 
end ifdef 
 

Does that work??

new topic     » goto parent     » topic index » view message » categorize

3. Re: High-Res time and related functions

petelomax said...
jmduro said...
ifdef WINDOWS then 
 
procedure error_message(sequence msg, atom quit) 
 
elsifdef LINUX then 
 
    error_message("Your hardware does not support hi-res timers.", 1) 
 
end ifdef 
 

Does that work??

You're right.error_message is a procedure I define normally in another file.

Here I inserted it at the wrong place. It should be above ifdef WINDOWS.

--------------------------------------------------------------------------------  
  
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  
  
--*------------------------------------------------------*  
-- 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  
  

Sorry for the bug.

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

4. Re: High-Res time and related functions

When did peek8u() get added? I'm running v 4.0.5 and I get an error that peek8u is not defined. Is this 64 bit only? It's not in the online manual but it is in the Wiki.

Lonny

new topic     » goto parent     » topic index » view message » categorize

5. Re: High-Res time and related functions

Lnettnay said...

When did peek8u() get added? I'm running v 4.0.5 and I get an error that peek8u is not defined. Is this 64 bit only? It's not in the online manual but it is in the Wiki.

Lonny

peek8u() was probably added in Euphoria Beta 4.1.0 Beta 2. Also, everyone should be using the beta as its pretty stable for the most part and has the extra functions are very useful. Whenever the full release happens, it should have struct support too.

new topic     » goto parent     » topic index » view message » categorize

6. Re: High-Res time and related functions

Icy_Viking said...
Lnettnay said...

When did peek8u() get added? I'm running v 4.0.5 and I get an error that peek8u is not defined. Is this 64 bit only? It's not in the online manual but it is in the Wiki.

Lonny

peek8u() was probably added in Euphoria Beta 4.1.0 Beta 2. Also, everyone should be using the beta as its pretty stable for the most part and has the extra functions are very useful. Whenever the full release happens, it should have struct support too.

Yes, peek8u is and EU4.1 function. It can be replaced by following code in EU4.0 (source CChris):

constant p232=power(2,32) 
 
function peek8u(atom addr) 
  return peek4u(addr)+p232*peek4u(addr+4) 
end function 
 

Jean-Marc

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu