bug : millisecs() returns a negative decreasing value on Windows 10 (fixed)

Started by RemiD, March 27, 2018, 09:38:21

Previous topic - Next topic

RemiD

Hello,

One of my procedure is working well on different computers with Windows XP and Windows 7, but not on a computer with Windows 10, and apparently this is caused by millisecs() which returns a negative decreasing value on Windows 10...

Here is an example :

Graphics3D(854,480,32,2)

Global MilliValue% = MilliSecs()

Global MainLoopTimer = CreateTimer(30)

Main()

End()

Function Main()

Repeat

  If( KeyHit(28)=1 )
   MilliValue = MilliSecs()
  EndIf

  SetBuffer(BackBuffer())
  ClsColor(000,000,000) : Cls()

  Color(255,255,255)
  TStr$ = MilliValue : CText(TStr,GraphicsWidth()/2-StringWidth(TStr)/2,0)

  ;Flip(1)
  WaitTimer(MainLoopTimer)
  VWait():Flip(False)

Until( KeyDown(1)=1 )

End Function

Function CText(TextStr$,PX%,PY%)

Text(PX,PY,TextStr,False,False)

End Function


This is bad, so i guess that i will have to find a dll with a function to return the correct millisecond value on all Windows OS (XP, Vista, 7, 8, 10)

If you have one, please share it. (.dll and .decls)

Thanks,

therevills

Works okay on my Windows 10 machine, it outputted 1048160687... how long has the PC been on for or running your app?

Derron

Uptime > 28 days and it will wrap around the integer-limits.


bye
Ron

RemiD

@therevills>>The computer has just been started a few minutes ago, and it was not in sleep mode...


@Derron>>the problem is not what you mention, because the value is negative and decreasing...


I have found a dll + decls with a function to get the millisecond value, i will test it. wait...

RemiD

The dll + decls i have used was made by Bobysait, so probably functional...

Same result than with the Blitz3d millisecs() function :
On 2 computers with Windows 7, it returns the correct value (the 2 milliseconds values of the 2 functions are the same)
But on the computer with Windows 10, it returns a negative decreasing value (around -508100000) (the computer has just been started... and it was not in sleep mode)

weird ???

Steve Elliott

Quote
Works okay on my Windows 10 machine

Same here, works fine.
Win11 64Gb 12th Gen Intel i9 12900K 3.2Ghz Nvidia RTX 3070Ti 8Gb
Win11 16Gb 12th Gen Intel i5 12450H 2Ghz Nvidia RTX 2050 8Gb
Win11  Pro 8Gb Celeron Intel UHD Graphics 600
Win10/Linux Mint 16Gb 4th Gen Intel i5 4570 3.2GHz, Nvidia GeForce GTX 1050 2Gb
macOS 32Gb Apple M2Max
pi5 8Gb
Spectrum Next 2Mb

RemiD

So how is this possible ? And what can i do about it ? is there a way to reset the milliseconds value to 0 and to set the "timer" to increase instead of decrease ?

The easy approach would be to disregard buggy computers :P

Naughty Alien


TomToad

Find other development tools, such as BlitzMax, AGK, C++, etc... See if the problem exists in any of those.  Could be you have a defective timer.  Try
Graphics3D(854,480,32,2)

Global MilliValue% = (MilliSecs() And $7FFFFFFF) / 1000

Global MainLoopTimer = CreateTimer(30)

Main()

End()

Function Main()

Repeat

  If( KeyHit(28)=1 )
   MilliValue = (MilliSecs() And $7FFFFFFF) / 1000
  EndIf

  SetBuffer(BackBuffer())
  ClsColor(000,000,000) : Cls()

  Color(255,255,255)
  TStr$ = MilliValue : CText(TStr,GraphicsWidth()/2-StringWidth(TStr)/2,0)

  ;Flip(1)
  WaitTimer(MainLoopTimer)
  VWait():Flip(False)

Until( KeyDown(1)=1 )

End Function

Function CText(TextStr$,PX%,PY%)

Text(PX,PY,TextStr,False,False)

End Function

This should count up by 1 second intervals.  Let it run for about 10 seconds, then press enter to see if the timer has advanced 10 seconds or not.  Try 30 or a minute.  Is it keeping correct time?
------------------------------------------------
8 rabbits equals 1 rabbyte.

Henri

My first impression was overflow issue.

In NG you could resolve it by using unsigned variables like:
Code (blitzmax) Select
While Not KeyHit(KEY_ESCAPE)

Print GetTickCount() + " | " + GetTickCount64()

Delay 1000
PollSystem()
Wend

Print "END"

Extern "Win32"
' https://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx
Function GetTickCount:UInt()="UInt GetTickCount() !" ' Unsigned 32bit
Function GetTickCount64:ULong()="ULong GetTickCount() !" ' Unsigned 64bit
EndExternn


Doing the same in Blitz3d requires some jiggery-pokery :-)

-Henri
- Got 01100011 problems, but the bit ain't 00000001

Derron

@ Henri
I thought that too but RemiD ruled that out.


bye
Ron

RemiD

What is strange is that each time, the computer has just been started, and was not in sleep mode, so in theory the milliseconds value should start at 0 and increase (until it reaches 2147483647 (in Blitz3d) which would be after 24.85 days...)

I will output a text file with milliseconds values during a few seconds and post it here, maybe it will give you some ideas...

RemiD

here the milliseconds values during 5seconds :
http://rd-stuff.fr/milliseconds-values-during-5seconds.txt

apparently the value increases, unlike what i said previously, because a smaller negative value is nearer to 0 ???

but what i am supposed to do with that ? i don't want to have to rewrite all my procedures just for this weird computer...

Derron

if the value increases this is that "rollover thing".

It reaches its maximum and continues then at the integer minimum. You will need to replace your Millisecs-calls with something different - see the code by tomtoad:
Global MilliValue% = (MilliSecs() And $7FFFFFFF) / 1000

to get an idea...


In my Dig-Framework I use this:
Code (BlitzMax) Select

'returns the time gone since the computer was started
Function MilliSecsLong:Long()
'code from:
'http://www.blitzbasic.com/Community/post.php?topic=84114&post=950107

'Convert to 32-bit unsigned
Local Milli:Long = Long(Millisecs()) + 2147483648:Long
'Accumulate 2^32
If Milli < LastMilliSeconds Then MilliSeconds :+ 4294967296:long

LastMilliSeconds = Milli
Return MilliSeconds + Milli
End Function



As you recognized already: the value does increase, so "new value" minus "old value" will result in the "time gone". An "if new - old > 1000 then OneSecondIsGone()" should work regardless of the rollover issue.


bye
Ron

RemiD

ok but what does (MilliSecs() And $7FFFFFFF) does ? compared to only MilliSecs()


btw my problem is not to keep track of milliseconds time, but rather to give a milliseconds value to an entity after it has been updated, and to use these milliseconds values to order the entities from lowest value to highest value, so that the entity which was updated the more time ago, is updated next. but these negative milliseconds values somehow makes my procedure bug...