ofGetElapsedTimef() wrap

I’ve been fighting with my program locking up (in Windows, of_v0073_vs2010_release) at various times and I pinned it down to

unsigned long long ofGetSystemTimeMicros( ) {
return ((unsigned long long)timeGetTime()) * 1000;

after which I found out that it was fixed 24 days ago when I went to report it - https://github.com/openframeworks/openFrameworks/issues/1768


But in the process I read that timeGetTime rolls over after 49.71 days - http://msdn.microsoft.com/en-us/library/windows/desktop/dd757629(v=vs.85.aspx

So question is…
am I understanding correctly that on Windows ofGetElapsedTimef() will rollover to zero after 49.71 days?

This is something I may have otherwise not realized until after installing my exhibit for a 2 month show over overseas, so it could be a blessing in (a very convincing) disguise.


Also, related question…
Does anyone know if ofGetElapsedTimef() rolls over at some point on Mac?

I could be mistaken here, but inside of ofUtils.cpp, would it be better to have

static unsigned long startTime = ofGetSystemTime();  
unsigned long ofGetElapsedTimeMillis(){  
	return ofGetSystemTime() - startTime;  
unsigned long ofGetSystemTime( )  

instead of

static unsigned long long startTime = ofGetSystemTime();  
unsigned long long ofGetElapsedTimeMillis(){  
	return ofGetSystemTime() - startTime;  
unsigned long long ofGetSystemTime( )  


My thinking is that at the moment timeGetTime() rolls over after 43.7 days, the subtraction (ofGetSystemTime() - startTime) is going to give you a very large number (~2^32) when those values are both unsigned long long, but if they were just unsigned long the same subtraction would give you a small number (~1). Obviously neither is correct, but I think the latter behaves more nicely.

For starters, I think unsigned long long is susceptible to a discontinuity at the timeGetTime()==2^32 to zero transition, which could happen at any point in time after program start (and then repeat every 43 days), whereas unsigned long is only susceptible when (ofGetSystemTime() - startTime) == 2^32, which happens the first time at 43 days (and then repeats every 43 days).

Further, if do:

myTimerStart = ofGetElapsedTimeMillis();  
myTotalTime = ofGetElapsedTimeMillis() - myTimerStart;  

If everything above is unsigned long, my timer works over any myTotalTime less than 43.7 days (at which point it goes back to zero), but if we’re using unsigned long long I think we can end up in the funky ~2^32 scenario at whatever lucky moment timeGetTime() rolls and it can make your delay timers wait a really long time.

All of this is speaking only from the PC side. I can’t say I know what happens with now.tv_usec.

I think the unsigned long long acts a bit stranger than I thought. Here is a thought experiment analogous to

unsigned long long ofGetElapsedTimeMillis(){    
    return ofGetSystemTime() - startTime;    

when everything is either unsigned long or unsigned long long. For mental simplicity I’m imagining that unsigned long rolls at 10 and unsigned long long rolls at 20. The below are of the form:
ofGetSystemTime() - startTime = [unsigned long result], [unsigned long long result]
Experiment 2:
6-5 = 1, 1
7-5 = 2, 2
8-5 = 3, 3
9-5 = 4, 4
0-5 = 5, 15
1-5 = 6, 16
2-5 = 7, 17
3-5 = 8, 18
4-5 = 9, 19
5-5 = 0, 0
6-5 = 1, 1

Experiment 1:
0-9 = 1, 11
1-9 = 2, 12

8-9 = 9, 19
9-9 = 0, 0
0-9 = 1, 11

Note how when the unsigned long long form rolls, the result acts crazy and how it acts depends where timeGetTime() was when the program was started.

Is this analysis correct??

I’ve been working waay too hard for an upcoming show… hard drives crashing… oy va voy… but this program has to run correctly with good timing for over 2 months an ocean away…

OK, I think an easy interim solution (for pc anyway) is to cast the output of ofGetElapsedTimeMillis() as an unsigned long

unsigned long myElapsed = ofGetElapsedTimeMillis();  

which then wraps our funky numbers back around (last post)

ofGetElapsedTimef() will still behave strangely as above and I’m not sure I can predict the behavior of ofGetElapsedTimeMicros() without some more thought.