aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86/timer.h
diff options
context:
space:
mode:
authorGuillaume Chazarain <guichaz@yahoo.fr>2008-01-30 07:30:06 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:30:06 -0500
commit53d517cdbaac704352b3d0c10fecb99e0b54572e (patch)
tree4056bc99a4e6077d7d968d30ea21895e425a83ef /include/asm-x86/timer.h
parent83bd01024b1fdfc41d9b758e5669e80fca72df66 (diff)
x86: scale cyc_2_nsec according to CPU frequency
scale the sched_clock() cyc_2_nsec scaling factor according to CPU frequency changes. [ mingo@elte.hu: simplified it and fixed it for SMP. ] Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/asm-x86/timer.h')
-rw-r--r--include/asm-x86/timer.h23
1 files changed, 18 insertions, 5 deletions
diff --git a/include/asm-x86/timer.h b/include/asm-x86/timer.h
index 0db7e994fb8b..4f6fcb050c11 100644
--- a/include/asm-x86/timer.h
+++ b/include/asm-x86/timer.h
@@ -2,6 +2,7 @@
2#define _ASMi386_TIMER_H 2#define _ASMi386_TIMER_H
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/pm.h> 4#include <linux/pm.h>
5#include <linux/percpu.h>
5 6
6#define TICK_SIZE (tick_nsec / 1000) 7#define TICK_SIZE (tick_nsec / 1000)
7 8
@@ -16,7 +17,7 @@ extern int recalibrate_cpu_khz(void);
16#define calculate_cpu_khz() native_calculate_cpu_khz() 17#define calculate_cpu_khz() native_calculate_cpu_khz()
17#endif 18#endif
18 19
19/* Accellerators for sched_clock() 20/* Accelerators for sched_clock()
20 * convert from cycles(64bits) => nanoseconds (64bits) 21 * convert from cycles(64bits) => nanoseconds (64bits)
21 * basic equation: 22 * basic equation:
22 * ns = cycles / (freq / ns_per_sec) 23 * ns = cycles / (freq / ns_per_sec)
@@ -31,20 +32,32 @@ extern int recalibrate_cpu_khz(void);
31 * And since SC is a constant power of two, we can convert the div 32 * And since SC is a constant power of two, we can convert the div
32 * into a shift. 33 * into a shift.
33 * 34 *
34 * We can use khz divisor instead of mhz to keep a better percision, since 35 * We can use khz divisor instead of mhz to keep a better precision, since
35 * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. 36 * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
36 * (mathieu.desnoyers@polymtl.ca) 37 * (mathieu.desnoyers@polymtl.ca)
37 * 38 *
38 * -johnstul@us.ibm.com "math is hard, lets go shopping!" 39 * -johnstul@us.ibm.com "math is hard, lets go shopping!"
39 */ 40 */
40extern unsigned long cyc2ns_scale __read_mostly; 41
42DECLARE_PER_CPU(unsigned long, cyc2ns);
41 43
42#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ 44#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
43 45
44static inline unsigned long long cycles_2_ns(unsigned long long cyc) 46static inline unsigned long long __cycles_2_ns(unsigned long long cyc)
45{ 47{
46 return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; 48 return cyc * per_cpu(cyc2ns, smp_processor_id()) >> CYC2NS_SCALE_FACTOR;
47} 49}
48 50
51static inline unsigned long long cycles_2_ns(unsigned long long cyc)
52{
53 unsigned long long ns;
54 unsigned long flags;
55
56 local_irq_save(flags);
57 ns = __cycles_2_ns(cyc);
58 local_irq_restore(flags);
59
60 return ns;
61}
49 62
50#endif 63#endif