problem with currentTimeMillis()

After reading that a lot of people had problems with java5.0 I decided to redo my 2d engine so that it worked with java 1.4.x.
I had a game loop that used nanoTime() for time synchro and it worked like a charm.
I rewrote my loop, this time using currentTimeMillis() and I just noticed a problem:
the value of currentTimeMillis is not updated regularly.The value isn’t changed during 3 iterations and suddenly at the fourth it is increased of 50 units (50 milliseconds).
That makes it practically impossible to achieve a smooth animation in my engine.
Anybody else have encountered this problem? and do you have solutions?

“currentTimeMillis()” is dependent on the operating system clock.

The time it returns is dependent on the OS, it’s better on Linux than Windows and it’s even worse on Mac.

I suggest you use a C timer through JNI, like the GAGE timer or force your users to upgrade Java. :slight_smile:

I know it was tongue in cheek, but… forcing everyone else to move to java 5 just because Sun’s Windows 1.4 JVM has a bug isn’t really fair. It’s also likely to turn away most people with java (most people don’t have java 5 yet, by the looks of things).

GAGE timer has been used by nearly everyone; it’s small, it works. Just use it :).

GAGE is all you need, no more, no less.

It will even fall back on the sun.misc.perf Timer if its present (Suns VM 1.4.x)

How does this GAGE timer work? Do you have to download something to get it or is it built in as default?

GAGE Timer is at:

http://java.dnsalias.com

Its a native library for windows that works using a different clock to the System.currentTimeMillis(). It wraps up the nasty work of deciding what you need to do and where.

GAGE Timer is brought to you by the letters A and D, the number 10 and our good friend jbanes.

Kev

[quote]GAGE Timer is at:

http://java.dnsalias.com

Its a native library for windows (…)
[/quote]
Yeah that’s what I noticed unfortunately, so it doesn’t really solve the problems I have and it’s not really better than using java1.5 if it’s only for Windows.

There’s also a hires timer in (Sun’s) Java 1.4 hidden in sun.misc.Perf. However, it’s in an “evil” Sun package…
I’ve written myself a TimeProvider interface with one method (currentTimeMillis()) and different implementations for misc.Perf, System.currentTimeMillis() and the LWJGL timer. I’m accessing these via a factory class that returns the appropriate timer depending on my needs and on what’s available on the current machine. It’s not a problem to add two more implementations for GAGE and Java5’s nanoTime…
That way, you’ll get high precision where available and still have some fallback options.

[quote]There’s also a hires timer in (Sun’s) Java 1.4 hidden in sun.misc.Perf. However, it’s in an “evil” Sun package…
I’ve written myself a TimeProvider interface with one method (currentTimeMillis()) and different implementations for misc.Perf, System.currentTimeMillis() and the LWJGL timer. I’m accessing these via a factory class that returns the appropriate timer depending on my needs and on what’s available on the current machine. It’s not a problem to add two more implementations for GAGE and Java5’s nanoTime…
That way, you’ll get high precision where available and still have some fallback options.
[/quote]
GAGE already does all of that :slight_smile:

Hey EgonOlsen, I like your implementation, could u post the source code or send it by email?

I was wondering some time ago how good is the LWJGL timer compared to GAGE? I guess the point is if you’re already using LWJGL then why would you use another timing API if it works well with LWJGL?

[quote]I was wondering some time ago how good is the LWJGL timer compared to GAGE? I guess the point is if you’re already using LWJGL then why would you use another timing API if it works well with LWJGL?
[/quote]
They all used to use the same timer. LWJGL pre 0.96, Gage native dll, nanoTime and sun.misc.Perf all uses the Performance Counter api. It’s problem is that it don’t work properly on speed-step computers. The speed of the game will fluctuate as the processor frequency is changed.

LWJGL 0.96 uses timeGetTime wich can have 1 ms resolution. But it requires you to use Thread.sleep(1) in your game loop for maximum reliability. And sleep is not accurate in java. Sometimes it will degrade to 10-15ms accurace, making it no better than currentTimeMillis.

So there is no timer that works on all systems on windows :’( There is always a catch. The next step is to detect wich timer works best.

Its not a bug.

It works as designed.

It just is not the right design for game needs.

Your choices for game needs are:

(1) The nanosecond timer in Java5 (IMHo the best choice)
(2) The old Sleep hack (depends on undocumented behavior of
Sleep and as such is not reliable.)
(3) The Java3D utils timer. (Depedns on a native DLL so only works
on thsoe platforms j3D has been proted to.)
(4) A third party native DLL (same problem as 3).

The nano timer in 1.5, and in fact in every other bit of code in the rest of the universe that seems to rely on the same underlying code, is now unreliable and broken :frowning: Not a single game on my new laptop runs correctly - except the ones I’ve written :frowning:

Cas :slight_smile:

[quote]The nano timer in 1.5, and in fact in every other bit of code in the rest of the universe that seems to rely on the same underlying code, is now unreliable and broken :frowning: Not a single game on my new laptop runs correctly - except the ones I’ve written :frowning:

Cas :slight_smile:
[/quote]
Well in theory, every bit of timing code in the universe will always be faulty at one time or another anyway :smiley:
I changed my 2.6ghz athlon for a 3200+ XP64 and I didn’t notice difference on my game that uses nanoTime().
And now that macintoshes have java 5, I think i’ll stick with it, well maybe I’ll write some redudant code to use misc.perf if the 1.4jvm is detected, that is if I manage to keep the motivation for that :slight_smile:

[quote]The nano timer in 1.5, and in fact in every other bit of code in the rest of the universe that seems to rely on the same underlying code, is now unreliable and broken :frowning: Not a single game on my new laptop runs correctly - except the ones I’ve written :frowning:

Cas :slight_smile:
[/quote]
Ouch. What platform is on that? I assume Windows since you are saying every game is broken.

Is this maybe a result of MSFt not handling this “speedstep” stuff right?

:frowning: I wish they’d fix it but really it’s rather too late now, the cat is out of the bag. TBH I don’t even know if they can fix it easily. Might be some strange hardware shenanigans.

Cas :slight_smile:

Just hit this problem on jdk1.5.0, and I’m extremely disappointed.

Thread.sleep( 20 ) now consistently sleeps for 31ms on my Sempron machine. I remember seeing similar behaviour on much earlier JVM versions.

In my opinion this is quite unacceptable for a bug of this magnitude to be present in any JVM release. I fail to see how Java can provide serious competition to .NET as a desktop platform with performance like this.

I very much doubt the IO and networking classes use the exposed interfaces, as it would likely ruin their performance.

EDIT:

Ok, rant over. I’ve come up with a nice robust work-around. I long for the days when you could hook your app to the vertical blank …

I suppose it’s an operating-system issue, possibly related to sleeping across schedule-points. I’d guess that other platforms like .NET have the same problems.

Cheers,
Martin

[quote]Just hit this problem on jdk1.5.0, and I’m extremely disappointed.

Thread.sleep( 20 ) now consistently sleeps for 31ms on my Sempron machine. I remember seeing similar behaviour on much earlier JVM versions.

In my opinion this is quite unacceptable for a bug of this magnitude to be present in any JVM release. I fail to see how Java can provide serious competition to .NET as a desktop platform with performance like this.
[/quote]
Is this Windows? Because Windows does not provide very granular sleep, try the same application under Linux and you should see 20ms sleep times.

Why is it that C++ game developers never complain about this problem on windows but it hurts all java developers? Surely this points to it being a problem with java? And wasn’t sun.misc.perf considerably better (I’ve never tried it, so I wouldn’t know for sure)?