Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » get_milliseconds function

This thread is locked; no one can reply to it. rss feed Print
get_milliseconds function
CGamesPlay
Member #2,559
July 2002
avatar

This post is in reply to this one, and also is related to an AD post with the same subject.

My method adds a get_milliseconds function to Allegro, and puts the call in the TIMER_DRIVER vtable. That means that it does require a call to install_timer.

Quote:

I'd also suggest adding something like al_get_time_delta() on top of it, which would return zero on first call and time delta in milliseconds on all next calls.

I thought about it, but it's just too trivial to merit its own function. Besides, it encourages use of global variables and isn't thread-safe.

Quote:

These points were made for QPC/QPF, but probably apply to timeGetTime() too

Seeing as how QPC and timeGetTime use completely separate metrics for measuring time, I'd like a little more proof that they "probably" apply, especially since the docs don't make that conclusion.

MSDN on timeGetTime

The patch I've created is attached.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Matt Smith
Member #783
November 2000

There is already an al_current_time() in the 4.3 event code which returns milliseconds. Have a look at that to see if it's the same thing.

I agree about the QPC being a special case of thread-unsafety, because it's a register in the cpu core, whereas there's always only one system clock.

X-G
Member #856
December 2000
avatar

Note if you're using QPC: Make sure to restrict CPU affinity to just one core to avoid timing fuckups.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Krzysztof Kluczek
Member #4,191
January 2004
avatar

Quote:

I agree about the QPC being a special case of thread-unsafety, because it's a register in the cpu core, whereas there's always only one system clock.

QPC/timeGetTime doesn't directly return contents of CPU tick count register and makes proper corrections taking CPU speed changes into accout (namely CPU clock changes when idle). The problem is when there are two separate CPUs/cores in the system that change speed independently and time chcecks are called from various processors.

System clock (eg. GetTickCount) shouldn't have such problems, but it has lower resolution (IIRC 5ms), which isn't enough for smooth animation and will produce quite big time aliasing on standard refresh ratios (eg. for 80Hz you'll randomly get 10ms and 15ms deltas between frames). :)

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

QPC/timeGetTime doesn't directly return contents of CPU tick count register and makes proper corrections taking CPU speed changes into accout (namely CPU clock changes when idle).

timeGetTime doesn't return the CPU tick count at all. It returns the number of milliseconds since the system was started.

Quote:

System clock (eg. GetTickCount) shouldn't have such problems, but it has lower resolution (IIRC 5ms), which isn't enough for smooth animation and will produce quite big time aliasing on standard refresh ratios (eg. for 80Hz you'll randomly get 10ms and 15ms deltas between frames). :)

Read the MSDN link from my first post, please.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Krzysztof Kluczek
Member #4,191
January 2004
avatar

OK, so timeGetTime() should be safe to use. Now only somebody with knowledge about Allegro timer system should add emulation of this function. :)

And here are my points from Minorhack thread:
- al_get_milliseconds could require install_timer() call on all platforms to encourage portable coding.

- I'd also suggest adding something like al_get_time_delta() on top of it, which would return zero on first call and time delta in milliseconds on all next calls (which would effectively make coding delta-based logic with Allegro a breeze). :)

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

- al_get_milliseconds could require install_timer() call on all platforms to encourage portable coding.

- I'd also suggest adding something like al_get_time_delta() on top of it, which would return zero on first call and time delta in milliseconds on all next calls (which would effectively make coding delta-based logic with Allegro a breeze). :)

Both of those are already addressed in my first post, if you have anything further to comment on...

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Elias
Member #358
May 2000

Anything wrong with al_get_time (from 4.9)? Someone might want to compare to the implementation there, then send a complete patch to the mailing list if this one is better.

--
"Either help out or stop whining" - Evert

Krzysztof Kluczek
Member #4,191
January 2004
avatar

Quote:

Quote:
I'd also suggest adding something like al_get_time_delta() on top of it, which would return zero on first call and time delta in milliseconds on all next calls.

I thought about it, but it's just too trivial to merit its own function. Besides, it encourages use of global variables and isn't thread-safe.

We already have get_mouse_mickeys, so getting time delta won't be much different. :)

CGamesPlay
Member #2,559
July 2002
avatar

The mouse's movement delta is fundamentally different from the mouse's position. You can't simply subtract mouse_x from mouse_old_x to find the difference.

[append]

In other words, get_mouse_mickeys adds functionality that couldn't be added without a specialized function. Adding a function to return a time delta is an exact replicate of al_get_milliseconds, which returns a time delta as well, just from a different reference point.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

GullRaDriel
Member #3,861
September 2003
avatar

I finally got it working, please some other Windows owner, test it ! attached are the good versions in a 7z archive )

I tried your version, compiled fine (attached are the modified dll and extimer).

But looks like it does not work.
http://www.allegro.cc/files/attachment/592240

I am searching why get_milliseconds always return 0

EDIT: I see that the new get_milliseconds rely on timeGetTime:

So I think that the problem is near that. I am testing timeGetTime lonely in a sample code to see if it is my system who's buggy.

EDIT: It is working when using directly timeGetTime. So the implementation should be messed up.

1#include <allegro.h>
2#include <winalleg.h>
3 
4int main( int argc , char *argv[] )
5{
6 
7unsigned int start = 0 , end = 0 ;
8 
9allegro_init();
10install_timer();
11 
12start = timeGetTime();
13 
14rest( 1000 );
15 
16end = timeGetTime();
17 
18printf( "Time: %u\n" , (end - start) );
19 
20allegro_exit();
21 
22}END_OF_MAIN()

This code returns 1000, and as told in msdn, testing show me that the default granularity is 5 ms on WinXp.

EDIT: Modified test to set granularity to 1 ms

1#include <allegro.h>
2#include <winalleg.h>
3 
4int main( int argc , char *argv[] )
5{
6 
7unsigned int start = 0 , end = 0 ;
8 
9allegro_init();
10install_timer();
11 
12if( timeBeginPeriod( 1 ) == TIMERR_NOCANDO ) /* set the granularity to 1 ms */
13 printf( "Can not set timeBeginPeriod to 1 ms\n" );
14
15start = timeGetTime();
16 
17rest( 1 );
18 
19end = timeGetTime();
20 
21if( timeEndPeriod( 1 ) == TIMERR_NOCANDO )
22 printf( "Can not end TimeEndPeriod correclty\n" );
23
24printf( "Time: %u\n" , (end - start) );
25
26allegro_exit();
27 
28}END_OF_MAIN()

This code works fine, it returns me 1 or 2 ms ( a for loop with a rest(1) inside gave me these results )

EDIT: More investigation

if ((timer_driver) && (timer_driver->get_milliseconds)) {
      return timer_driver->get_milliseconds();
   }
   else
      return 0;

The problem is here. It always return 0

EDIT: Some more test around, I added the following to extimer.c

if( timer_driver )
  printf( "timer_driver: %p\n" , timer_driver );
else
  printf( "No timer_driver pointer\n" );

if( timer_driver -> get_milliseconds)
  printf( "timer_driver -> get_milliseconds = %p\n" , timer_driver -> get_milliseconds );
else
  printf( "No timer_driver -> get_milliseconds pointer\n" );

Result:
timer_driver: 67A68780
No timer_driver -> get_milliseconds pointer

EDIT: After searching a little, it looks like tim_win32_get_milliseconds is not implemented in the driver list, which cause the get_milliseconds function to always return 0

testing with tim_win32_get_milliseconds implemented:

1static TIMER_DRIVER timer_win32_high_perf =
2{
3 TIMER_WIN32_HIGH_PERF,
4 empty_string,
5 empty_string,
6 "Win32 high performance timer",
7 tim_win32_high_perf_init,
8 tim_win32_exit,
9 NULL, NULL, NULL, NULL, NULL, NULL,
10 tim_win32_rest,
11 tim_win32_get_milliseconds
12};
13 
14 
15static TIMER_DRIVER timer_win32_low_perf =
16{
17 TIMER_WIN32_LOW_PERF,
18 empty_string,
19 empty_string,
20 "Win32 low performance timer",
21 tim_win32_low_perf_init,
22 tim_win32_exit,
23 NULL, NULL, NULL, NULL, NULL, NULL,
24 tim_win32_rest,
25 tim_win32_get_milliseconds
26};

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

BAF
Member #2,981
December 2002
avatar

There isn't a gettimeofday on Mac that you can use to provide Mac compatibility?

GullRaDriel
Member #3,861
September 2003
avatar

http://www.hmug.org/man/2/gettimeofday.php says yes.

unix.c says ALLEGRO_MACOSX sometimes. So I guess it already uses gettimeofday

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Go to: