Converting jiffies to milli seconds

前端 未结 4 1812
生来不讨喜
生来不讨喜 2020-12-04 11:42

How do I manually convert jiffies to milliseconds and vice versa in Linux? I know kernel 2.6 has a function for this, but I\'m working on 2.4 (homework) and though I looked

相关标签:
4条回答
  • 2020-12-04 11:49

    As a previous answer said, the rate at which jiffies increments is fixed.

    The standard way of specifying time for a function that accepts jiffies is using the constant HZ.

    That's the abbreviation for Hertz, or the number of ticks per second. On a system with a timer tick set to 1ms, HZ=1000. Some distributions or architectures may use another number (100 used to be common).

    The standard way of specifying a jiffies count for a function is using HZ, like this:

    schedule_timeout(HZ / 10);  /* Timeout after 1/10 second */
    

    In most simple cases, this works fine.

    2*HZ     /* 2 seconds in jiffies */
    HZ       /* 1 second in jiffies */
    foo * HZ /* foo seconds in jiffies */
    HZ/10    /* 100 milliseconds in jiffies */
    HZ/100   /* 10 milliseconds in jiffies */
    bar*HZ/1000 /* bar milliseconds in jiffies */
    

    Those last two have a bit of a problem, however, as on a system with a 10 ms timer tick, HZ/100 is 1, and the precision starts to suffer. You may get a delay anywhere between 0.0001 and 1.999 timer ticks (0-2 ms, essentially). If you tried to use HZ/200 on a 10ms tick system, the integer division gives you 0 jiffies!

    So the rule of thumb is, be very careful using HZ for tiny values (those approaching 1 jiffie).

    To convert the other way, you would use:

    jiffies / HZ          /* jiffies to seconds */
    jiffies * 1000 / HZ   /* jiffies to milliseconds */
    

    You shouldn't expect anything better than millisecond precision.

    0 讨论(0)
  • 2020-12-04 11:52

    To obtain the USER_HZ value (see the comments under the accepted answer) using CLI:

    getconf CLK_TCK
    
    0 讨论(0)
  • 2020-12-04 12:02

    Jiffies are hard-coded in Linux 2.4. Check the definition of HZ, which is defined in the architecture-specific param.h. It's often 100 Hz, which is one tick every (1 sec/100 ticks * 1000 ms/sec) 10 ms.

    This holds true for i386, and HZ is defined in include/asm-i386/param.h.

    There are functions in include/linux/time.h called timespec_to_jiffies and jiffies_to_timespec where you can convert back and forth between a struct timespec and jiffies:

        #define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
    
        static __inline__ unsigned long
        timespec_to_jiffies(struct timespec *value)
        {
                unsigned long sec = value->tv_sec;
                long nsec = value->tv_nsec;
    
                if (sec >= (MAX_JIFFY_OFFSET / HZ))
                        return MAX_JIFFY_OFFSET;
                nsec += 1000000000L / HZ - 1;
                nsec /= 1000000000L / HZ;
                return HZ * sec + nsec;
        }
    
        static __inline__ void
        jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
        {
                value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ);
                value->tv_sec = jiffies / HZ;
        }
    

    Note: I checked this info in version 2.4.22.

    0 讨论(0)
  • 2020-12-04 12:03

    I found this sample code on kernelnewbies. Make sure you link with -lrt

    #include <unistd.h>
    #include <time.h>
    #include <stdio.h>
    
    int main()
    {
        struct timespec res;
        double resolution;
    
        printf("UserHZ   %ld\n", sysconf(_SC_CLK_TCK));
    
        clock_getres(CLOCK_REALTIME, &res);
        resolution = res.tv_sec + (((double)res.tv_nsec)/1.0e9);
    
        printf("SystemHZ %ld\n", (unsigned long)(1/resolution + 0.5));
        return 0;
     }
    
    0 讨论(0)
提交回复
热议问题