gethrtime() is returning negative value on LINUX - Linux

This is a discussion on gethrtime() is returning negative value on LINUX - Linux ; hi we had implemented gethrtime on LINUX machine using the following code: long long gethrtime(void) { // Try to get the cpu frequency by reading // /proc/cpuinfo. Look for field "cpu Mhz". FILE *cpuInfo = fopen ("/proc/cpuinfo", "r"); if (cpuInfo ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: gethrtime() is returning negative value on LINUX

  1. gethrtime() is returning negative value on LINUX

    hi
    we had implemented gethrtime on LINUX machine using the following
    code:
    long long gethrtime(void)
    {

    // Try to get the cpu frequency by reading
    // /proc/cpuinfo. Look for field "cpu Mhz".
    FILE *cpuInfo = fopen ("/proc/cpuinfo", "r");
    if (cpuInfo != NULL)
    {
    char buf[256];
    double mhertz = 0;
    while (fgets(buf, sizeof(buf), cpuInfo))
    {
    if (sscanf(buf, "cpu MHz : %lf\n", &mhertz) ==
    1)
    {
    scaleFactor = (int)(mhertz + 0.5);
    printf("mhertz = %lf, scaleFactor = %d
    \n", mhertz, scaleFactor);
    long long now;
    asm volatile ("rdtsc" : "=A" (now) : :
    "memory");
    now = (now*1000)/scaleFactor;
    return now;
    }
    }
    }
    }
    Now on our customer setup this function starts returning negative
    value after sometime i.e after couple of days.
    from the logs we can find the scale factor to be 3060 and the returned
    value -2940642805558051. What could be the reason of this negative
    value? Though the system was up only for 40 days.
    regards,
    rishabh


  2. Re: gethrtime() is returning negative value on LINUX

    In article <1174112370.366020.64530@l77g2000hsb.googlegroups.c om>, "linux_bp" writes:
    > hi
    > we had implemented gethrtime on LINUX machine using the following
    > code:
    > long long gethrtime(void)
    > {
    >
    > [ ... ]


    > long long now;
    > asm volatile ("rdtsc" : "=A" (now) : : "memory");
    > now = (now*1000)/scaleFactor;
    > return now;
    > [ ... ]


    > Now on our customer setup this function starts returning negative
    > value after sometime i.e after couple of days.
    > from the logs we can find the scale factor to be 3060 and the returned
    > value -2940642805558051. What could be the reason of this negative
    > value? Though the system was up only for 40 days.
    > regards,
    > rishabh


    So do the math manually:
    1) What would be the value of the TSC after the system has been
    up for 40 days.
    2) Now multiply that by a thousand.
    3) What's wrong with this value relative to your algorithm and
    your choice of a 64-bit signed int to hold it?

    Is this really code from your deployed system? If so:
    1) I suggest that you do your calculations in floating point.
    You will avoid problems like this and you won't lose any
    precision given that you're getting CPU speed from /proc.
    2) You fall off the end of your code with no explicitly returned
    value if anything goes wrong with your parsing.
    3) You're leaking file handles like a sieve.
    4) The rdtsc instruction shouldn't need a "memory" directive
    to asm. One might possibly want serialization, but this
    routine will operate so slowly that it won't matter in this
    case.
    5) Given that you're using (relatively) slow functions like
    open and reading from /proc, why do you need a high precision
    value such as the TSC? Why not just use the current time
    (e.g., gettimeofday or clock_gettime)? (Plus current time
    doesn't have the problem of potentially unsynchronized TSCs
    on a multi-processor system.)

    - dmw

    --
    .. Douglas Wells . Connection Technologies .
    .. Internet: -sp9804- -at - contek.com- .

  3. Re: gethrtime() is returning negative value on LINUX

    On Mar 16, 11:19 pm, "linux_bp" wrote:
    > hi
    > we had implemented gethrtime on LINUX machine using the following
    > code:


    Here's a much better implementation (untested):

    #include
    long long gethrtime(void)
    {
    struct timespec sp;
    int ret;
    long long v;
    #ifdef CLOCK_MONOTONIC_HR
    ret=clock_gettime(CLOCK_MONOTONIC_HR, &sp);
    #else
    ret=clock_gettime(CLOCK_MONOTONIC, &sp);
    #endif
    if(ret!=0) return 0;
    v=1000000000LL; /* seconds->nanonseconds */
    v*=sp.tv_sec;
    v+=sp.tv_nsec;
    return v;
    }

    DS

    --
    If you know anyone who has an invite to the ICQ 6 Preview, I'd
    appreciate
    one. Email me for details. Thanks in advance.


+ Reply to Thread