What is jiffies:
- The original kernel timer system (called the "timer wheel) was based on incrementing a kernel-internal value (jiffies) every timer interrupt.
- The timer interrupt rate (and jiffy increment rate) is defined by a compile-time constant called HZ.
- Different platforms use different values for HZ.
- The kernel used 100 as the value for HZ, yielding a jiffy interval of 10 ms.
- With 2.4, the HZ value for i386 was changed to 1000, yeilding a jiffy interval of 1 ms.
- Process:
- When jiffy count is incremented then a process gets time to run.
- The jiffies are incremented by the timer interrupt that tells the scheduler to reschedule
- If the process calls yield() or sleep(), for example, then rescheduling takes place immediately.
- Thus the context switch to a next available running process not necessarily occurs at the jiffy boundary.
- It lists /proc/timer_list and /proc/timer_stats.
- Tick generation:
- It is updated every tick
- tick is triggered by timer/clock interrupt.
- The interrupt is generated by Intel 8253 or HPET hardware
- So it won't update until the hardware was property initialized.
- Difference:
- There is a better solution to ensure correct jiffy wrap handling in *ALL* kernel code: make jiffy wrap in first five minutes of uptime.
- #define INITIAL_JIFFIES (0xffffffffUL & (unsigned long)(-300*HZ))
- Hence jiffies is using the full 32 bit, after that overflow happen.
- So jiffies.h file comment as maximum jiffie value is (MAX_INT >> 1) is a false comment.
- Don't use MAX_JIFFY_OFFSET as max value since this is wrong.
- https://lwn.net/Articles/22874/
Program:
Wrong program:
- This below code is wrong, because jiffies is using the full 32 bit confirmed by after bootup jiffies overflow in 5 min,
- So after bootup just checked the jiffies value, it is using full 32 bit before overflow.
- Hence below code is wrong, this is wrongly used in some of kernel code.
inline unsigned long jiffies_time_diff(unsigned long start, unsigned long end)
{
if (end >= start)
return end - start;
{
if (end >= start)
return end - start;
return end + (MAX_JIFFY_OFFSET - start);
}
}
Correct program:
inline unsigned long jiffies_time_diff(unsigned long start, unsigned long end)
{
{
unsigned long diff = 0;
/* This code is handle the overflow also, by converting to long.
if jiffies start time is 13 and after overflowed end time is 5 then, coverting to sign
difference value is -8, the 1st complement +1 value of -8 is stored as big value in unsiged diff.
This is the correct difference */
diff = (long)end - (long) start;
return diff;
}
}
No comments:
Post a Comment