Microsecond timer and printf issues in C++

Hi guys,

First post here - hope it's in the right place.

I'm writing a timer for a client. It can send data every 100ms and receive every 150. It's an AI project so I *don't* want to fork() and pipe or go multi threaded, use interupts etc.

Using linux, gcc 4.3.2

The code I have:

initUsecs=usecs();
for ( ; ; ) {
    curUsecs=usecs();
    elapsed = curUsecs-initUsecs;
    printf("curUsecs: %d elapsed: %d\n", curUsecs, elapsed);
    
    if (elapsed > 20000) {
        printf("2 seconds, resetting\n");
        initUsecs=curUsecs;
    }
}
int Agent::usecs() 
{
    struct timeval tv;
         struct timezone tz;
    struct tm *tm;
    int ms;

    gettimeofday(&tv, &tz);
    ms = tv.tv_sec -1263300000;
    ms *= 1000;
    ms += tv.tv_usec;
    return(ms);
}

It's fairly ugly I know, but when I run it normally, the output is fairly unexpected. 'elapsed' turns to negative numbers after about 2 seconds and if I take out the first printf ('printf("curUsecs: %d....') then it dumps 7 or 8 lines, then nothing for a while and dumps some more or occasionally doesn't dump anything if I've mess arround a bit more. If I pipe it out to less or redirect output to a file insead of stdout then the results seem to be fine but I can't test it to make sure it is actually kicking in about every two seconds.

Is this a printf thing? Have I done something stupid? Is there an easier way to time things? (I was using clock() orriginally but I can't simulate more than one agent per cpu that way). How do I know it won't do this in the middle of execution?

Many thanks
Sam

This is probably why - don't use %d, use %ld at least. check your sytem's definition of the timeval datatypes.

Does sys/types.h have usec_t typedef? Then don't return int, return usec_t from usecs(). sys/time.h usually has something like this:

typedef long    suseconds_t;    /* signed # of microseconds */

struct timeval {
        time_t          tv_sec;         /* seconds */
        suseconds_t     tv_usec;        /* and microseconds */

edit: one other note - usually struct timezone tz is passed as a NULL. Read your system's manpage for gettimeofday

IMO you have inadvertantly hashed up the datatypes.

---------- Post updated at 09:44 ---------- Previous update was at 09:23 ----------

tv_usec is one-millionth of a second, microseconds not one-thousandth, milliseconds.

Fantastic - good call. All fixed - cheers :smiley: