views:

978

answers:

6

I need a way to get the elapsed time (wall-clock time) since a program started, in a way that is resilient to users meddling with the system clock.

On windows, the non standard clock() implementation doesn't do the trick, as it appears to work just by calculating the difference with the time sampled at start up, so that I get negative values if I "move the clock hands back".

On UNIX, clock/getrusage refer to system time, whereas using function such as gettimeofday to sample timestamps has the same problem as using clock on windows.

I'm not really interested in precision, and I've hacked a solution by having a half a second resolution timer spinning in the background countering the clock skews when they happen (if the difference between the sampled time and the expected exceeds 1 second i use the expected timer for the new baseline) but I think there must be a better way.

A: 

If you have a network connection, you can always acquire the time from an NTP server. This will obviously not be affected in any the local clock.

Steve Moyer
+1  A: 

I don't think you'll find a cross-platform way of doing that.

On Windows what you need is GetTickCount (or maybe QueryPerformanceCounter and QueryPerformanceFrequency for a high resolution timer). I don't have experience with that on Linux, but a search on Google gave me clock_gettime.

Romulo A. Ceccon
A: 

Wall clock time can bit calculated with the time() call.

EvilTeach
A: 

/proc/uptime on linux maintains the number of seconds that the system has been up (and the number of seconds it has been idle), which should be unaffected by changes to the clock as it's maintained by the system interrupt (jiffies / HZ). Perhaps windows has something similar?

Steve Baker
+1  A: 

I guess you can always start some kind of timer. For example under Linux a thread that would have a loop like this :

static void timer_thread(void * arg)
{
        struct timespec delay;
        unsigned int msecond_delay = ((app_state_t*)arg)->msecond_delay;

        delay.tv_sec = 0;
        delay.tv_nsec = msecond_delay * 1000000;

        while(1) {
                some_global_counter_increment();
                nanosleep(&delay, NULL);
        }
}

Where app_state_t is an application structure of your choice were you store variables. If you want to prevent tampering, you need to be sure no one killed your thread

shodanex
A: 

For POSIX, use clock_gettime() with CLOCK_MONOTONIC.

Kristopher Johnson