Blame view

kernel/time/jiffies.c 3.87 KB
734efb467   John Stultz   [PATCH] Time: Clo...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  /***********************************************************************
  * linux/kernel/time/jiffies.c
  *
  * This file contains the jiffies based clocksource.
  *
  * Copyright (C) 2004, 2005 IBM, John Stultz (johnstul@us.ibm.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  ************************************************************************/
  #include <linux/clocksource.h>
  #include <linux/jiffies.h>
fbad1ea94   Torben Hohn   time: Move get_ji...
25
  #include <linux/module.h>
734efb467   John Stultz   [PATCH] Time: Clo...
26
  #include <linux/init.h>
bfb83b275   Thomas Gleixner   tick: Move clocks...
27
  #include "timekeeping.h"
e2830b5c1   Torben Hohn   time: Make do_tim...
28

734efb467   John Stultz   [PATCH] Time: Clo...
29
30
31
32
33
34
35
  /* The Jiffies based clocksource is the lowest common
   * denominator clock source which should function on
   * all systems. It has the same coarse resolution as
   * the timer interrupt frequency HZ and it suffers
   * inaccuracies caused by missed or lost timer
   * interrupts and the inability for the timer
   * interrupt hardware to accuratly tick at the
25985edce   Lucas De Marchi   Fix common misspe...
36
   * requested HZ value. It is also not recommended
734efb467   John Stultz   [PATCH] Time: Clo...
37
38
   * for "tick-less" systems.
   */
b3c869d35   John Stultz   jiffies: Remove c...
39
  #define NSEC_PER_JIFFY	((NSEC_PER_SEC+HZ/2)/HZ)
734efb467   John Stultz   [PATCH] Time: Clo...
40
41
42
43
44
45
46
47
48
49
  
  /* Since jiffies uses a simple NSEC_PER_JIFFY multiplier
   * conversion, the .shift value could be zero. However
   * this would make NTP adjustments impossible as they are
   * in units of 1/2^.shift. Thus we use JIFFIES_SHIFT to
   * shift both the nominator and denominator the same
   * amount, and give ntp adjustments in units of 1/2^8
   *
   * The value 8 is somewhat carefully chosen, as anything
   * larger can result in overflows. NSEC_PER_JIFFY grows as
025dfdafe   Frederik Schwarzer   trivial: fix then...
50
   * HZ shrinks, so values greater than 8 overflow 32bits when
734efb467   John Stultz   [PATCH] Time: Clo...
51
52
   * HZ=100.
   */
80d767d77   Mikulas Patocka   time: Fix overflo...
53
54
55
56
57
  #if HZ < 34
  #define JIFFIES_SHIFT	6
  #elif HZ < 67
  #define JIFFIES_SHIFT	7
  #else
734efb467   John Stultz   [PATCH] Time: Clo...
58
  #define JIFFIES_SHIFT	8
80d767d77   Mikulas Patocka   time: Fix overflo...
59
  #endif
734efb467   John Stultz   [PATCH] Time: Clo...
60

8e19608e8   Magnus Damm   clocksource: pass...
61
  static cycle_t jiffies_read(struct clocksource *cs)
734efb467   John Stultz   [PATCH] Time: Clo...
62
63
64
  {
  	return (cycle_t) jiffies;
  }
f95a98578   Lars-Peter Clausen   time/jiffies: Mak...
65
  static struct clocksource clocksource_jiffies = {
734efb467   John Stultz   [PATCH] Time: Clo...
66
  	.name		= "jiffies",
3f4a0b917   John Stultz   [PATCH] i386 Time...
67
  	.rating		= 1, /* lowest valid rating*/
734efb467   John Stultz   [PATCH] Time: Clo...
68
69
70
71
  	.read		= jiffies_read,
  	.mask		= 0xffffffff, /*32bits*/
  	.mult		= NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
  	.shift		= JIFFIES_SHIFT,
3c17ad19f   John Stultz   timekeeping: Add ...
72
  	.max_cycles	= 10,
734efb467   John Stultz   [PATCH] Time: Clo...
73
  };
d6ad41876   John Stultz   time: Kill xtime_...
74
  __cacheline_aligned_in_smp DEFINE_SEQLOCK(jiffies_lock);
fbad1ea94   Torben Hohn   time: Move get_ji...
75
76
77
78
79
80
81
  #if (BITS_PER_LONG < 64)
  u64 get_jiffies_64(void)
  {
  	unsigned long seq;
  	u64 ret;
  
  	do {
d6ad41876   John Stultz   time: Kill xtime_...
82
  		seq = read_seqbegin(&jiffies_lock);
fbad1ea94   Torben Hohn   time: Move get_ji...
83
  		ret = jiffies_64;
d6ad41876   John Stultz   time: Kill xtime_...
84
  	} while (read_seqretry(&jiffies_lock, seq));
fbad1ea94   Torben Hohn   time: Move get_ji...
85
86
87
88
89
90
  	return ret;
  }
  EXPORT_SYMBOL(get_jiffies_64);
  #endif
  
  EXPORT_SYMBOL(jiffies);
734efb467   John Stultz   [PATCH] Time: Clo...
91
92
  static int __init init_jiffies_clocksource(void)
  {
f8935983f   John Stultz   clocksource: Most...
93
  	return __clocksource_register(&clocksource_jiffies);
734efb467   John Stultz   [PATCH] Time: Clo...
94
  }
98de9e3ba   John Stultz   [PATCH] fix jiffi...
95
  core_initcall(init_jiffies_clocksource);
f1b82746c   Martin Schwidefsky   clocksource: Clea...
96
97
98
99
100
  
  struct clocksource * __init __weak clocksource_default_clock(void)
  {
  	return &clocksource_jiffies;
  }
b3c869d35   John Stultz   jiffies: Remove c...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  
  struct clocksource refined_jiffies;
  
  int register_refined_jiffies(long cycles_per_second)
  {
  	u64 nsec_per_tick, shift_hz;
  	long cycles_per_tick;
  
  
  
  	refined_jiffies = clocksource_jiffies;
  	refined_jiffies.name = "refined-jiffies";
  	refined_jiffies.rating++;
  
  	/* Calc cycles per tick */
  	cycles_per_tick = (cycles_per_second + HZ/2)/HZ;
  	/* shift_hz stores hz<<8 for extra accuracy */
  	shift_hz = (u64)cycles_per_second << 8;
  	shift_hz += cycles_per_tick/2;
  	do_div(shift_hz, cycles_per_tick);
  	/* Calculate nsec_per_tick using shift_hz */
  	nsec_per_tick = (u64)NSEC_PER_SEC << 8;
  	nsec_per_tick += (u32)shift_hz/2;
  	do_div(nsec_per_tick, (u32)shift_hz);
  
  	refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT;
f8935983f   John Stultz   clocksource: Most...
127
  	__clocksource_register(&refined_jiffies);
b3c869d35   John Stultz   jiffies: Remove c...
128
129
  	return 0;
  }