1. High-Res time and related functions
- Posted by jmduro Aug 07, 2021
- 1090 views
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
2. Re: High-Res time and related functions
- Posted by petelomax Aug 07, 2021
- 1071 views
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??
3. Re: High-Res time and related functions
- Posted by jmduro Aug 07, 2021
- 1068 views
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
4. Re: High-Res time and related functions
- Posted by Lnettnay Aug 09, 2021
- 1003 views
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
5. Re: High-Res time and related functions
- Posted by Icy_Viking Aug 09, 2021
- 990 views
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.
6. Re: High-Res time and related functions
- Posted by jmduro Aug 10, 2021
- 980 views
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