4

The following refers to SuSE 11.4 Linux.

When my multi-process software starts on a server, the returned value of the C times() function is saved as an integer in shared memory.  (This is OK, because we’re pre-C11.)  Later, calls to times() are made to get the starting and ending times for tasks.  For example, a start time is computed as the amount of time since the original call to times(), and an end time is computed the same way.  Later, the difference can be taken between the starting and ending time, to compute a task’s duration.

Previously, we only used 32-bit processes.  For the next release, we’re planning on having both 32- and 64-bit processes running on the same server.  However, there seems to be clashing results from times().

According to the documentation, times() returns the duration since an arbitrary point in the past.  What I’m finding is that the initial point in the past differs depending on if the process was built as a 32- or 64-bit executable.

Consider the following code:

#include <time.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <unistd.h>

clock_t getTimes()
{
    clock_t c = times(0);
    int64_t c_int64_t = (int64_t)c & 0x00000000FFFFFFFF;
    printf("c_int64_t is [%" PRId64 "]\n", c_int64_t);
    return c;
}

int main(void)
{
    printf("sizeof(clock_t) is [%d]\n", sizeof(clock_t));

    clock_t c1 = getTimes();
    printf("sleeping for 2 seconds...\n");
    sleep(2);
    clock_t c2 = getTimes();

    double elapsedTime = ((double) (c2 - c1)) / (double)sysconf(_SC_CLK_TCK);
    printf("elapsedTime is [%f]\n", elapsedTime);
    return 0;
}

I compile it as follows:

$ gcc -m32 -oa.32.out clock.c
$ gcc –m64 -oa.64.out clock.c

Note what happens when I run it 4 times:

$ for i in a.32.out a.64.out a.32.out a.64.out
> do
> echo " "
> ./${i}
> done

sizeof(clock_t) is [4]
c_int64_t is [2286152112]
sleeping for 2 seconds...
c_int64_t is [2286152312]
elapsedTime is [2.000000]

sizeof(clock_t) is [8]
c_int64_t is [2286295196]
sleeping for 2 seconds...
c_int64_t is [2286295396]
elapsedTime is [2.000000]

sizeof(clock_t) is [4]
c_int64_t is [2286152512]
sleeping for 2 seconds...
c_int64_t is [2286152712]
elapsedTime is [2.000000]

sizeof(clock_t) is [8]
c_int64_t is [2286295597]
sleeping for 2 seconds...
c_int64_t is [2286295797]
elapsedTime is [2.000000]

As I hope is clear from the results, the 32-bit and 64-bit processes are each consistent amongst themselves.  But they differ between each other by about 142,885 units (or 1429 seconds).  The result of this is that my software can’t share a “base time” between 64- and 32-bit processes.

Is this behaviour of times() normal and expected?

First Last
  • 49
  • 5
  • 2
    Any reason you're not using `clock_gettime`? – dbush Apr 03 '19 at 19:30
  • I suppose mainly because the code has been this way for years, if not decades. But I will take a close look at `clock_gettime` as a possible fix. Thanks. – First Last Apr 03 '19 at 19:40
  • 1
    I can't reproduce this problem, but I don't have SuSE handy and I don't even know which version of SuSE you're using. With Ubuntu 18.04, and having fixed the warnings produced by your code (for example, by adding `#include `, which might make a difference), I get consistent results but they're quite different from either of the values you show. – rici Apr 03 '19 at 20:42
  • It's SuSE 11.4. I updated the question to reflect that. – First Last Apr 04 '19 at 12:32

0 Answers0