aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/timer.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-06-11 11:55:42 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-11 11:55:42 -0400
commit940010c5a314a7bd9b498593bc6ba1718ac5aec5 (patch)
treed141e08ced08c40c6a8e3ab2cdecde5ff14e560f /kernel/timer.c
parent8dc8e5e8bc0ce00b0f656bf972f67cd8a72759e5 (diff)
parent991ec02cdca33b03a132a0cacfe6f0aa0be9aa8d (diff)
Merge branch 'linus' into perfcounters/core
Conflicts: arch/x86/kernel/irqinit.c arch/x86/kernel/irqinit_64.c arch/x86/kernel/traps.c arch/x86/mm/fault.c include/linux/sched.h kernel/exit.c
Diffstat (limited to 'kernel/timer.c')
-rw-r--r--kernel/timer.c86
1 files changed, 8 insertions, 78 deletions
diff --git a/kernel/timer.c b/kernel/timer.c
index fed53be44fd9..c01e568935ea 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1124,47 +1124,6 @@ void update_process_times(int user_tick)
1124} 1124}
1125 1125
1126/* 1126/*
1127 * Nr of active tasks - counted in fixed-point numbers
1128 */
1129static unsigned long count_active_tasks(void)
1130{
1131 return nr_active() * FIXED_1;
1132}
1133
1134/*
1135 * Hmm.. Changed this, as the GNU make sources (load.c) seems to
1136 * imply that avenrun[] is the standard name for this kind of thing.
1137 * Nothing else seems to be standardized: the fractional size etc
1138 * all seem to differ on different machines.
1139 *
1140 * Requires xtime_lock to access.
1141 */
1142unsigned long avenrun[3];
1143
1144EXPORT_SYMBOL(avenrun);
1145
1146/*
1147 * calc_load - given tick count, update the avenrun load estimates.
1148 * This is called while holding a write_lock on xtime_lock.
1149 */
1150static inline void calc_load(unsigned long ticks)
1151{
1152 unsigned long active_tasks; /* fixed-point */
1153 static int count = LOAD_FREQ;
1154
1155 count -= ticks;
1156 if (unlikely(count < 0)) {
1157 active_tasks = count_active_tasks();
1158 do {
1159 CALC_LOAD(avenrun[0], EXP_1, active_tasks);
1160 CALC_LOAD(avenrun[1], EXP_5, active_tasks);
1161 CALC_LOAD(avenrun[2], EXP_15, active_tasks);
1162 count += LOAD_FREQ;
1163 } while (count < 0);
1164 }
1165}
1166
1167/*
1168 * This function runs timers and the timer-tq in bottom half context. 1127 * This function runs timers and the timer-tq in bottom half context.
1169 */ 1128 */
1170static void run_timer_softirq(struct softirq_action *h) 1129static void run_timer_softirq(struct softirq_action *h)
@@ -1190,16 +1149,6 @@ void run_local_timers(void)
1190} 1149}
1191 1150
1192/* 1151/*
1193 * Called by the timer interrupt. xtime_lock must already be taken
1194 * by the timer IRQ!
1195 */
1196static inline void update_times(unsigned long ticks)
1197{
1198 update_wall_time();
1199 calc_load(ticks);
1200}
1201
1202/*
1203 * The 64-bit jiffies value is not atomic - you MUST NOT read it 1152 * The 64-bit jiffies value is not atomic - you MUST NOT read it
1204 * without sampling the sequence number in xtime_lock. 1153 * without sampling the sequence number in xtime_lock.
1205 * jiffies is defined in the linker script... 1154 * jiffies is defined in the linker script...
@@ -1208,7 +1157,8 @@ static inline void update_times(unsigned long ticks)
1208void do_timer(unsigned long ticks) 1157void do_timer(unsigned long ticks)
1209{ 1158{
1210 jiffies_64 += ticks; 1159 jiffies_64 += ticks;
1211 update_times(ticks); 1160 update_wall_time();
1161 calc_global_load();
1212} 1162}
1213 1163
1214#ifdef __ARCH_WANT_SYS_ALARM 1164#ifdef __ARCH_WANT_SYS_ALARM
@@ -1409,37 +1359,17 @@ int do_sysinfo(struct sysinfo *info)
1409{ 1359{
1410 unsigned long mem_total, sav_total; 1360 unsigned long mem_total, sav_total;
1411 unsigned int mem_unit, bitcount; 1361 unsigned int mem_unit, bitcount;
1412 unsigned long seq; 1362 struct timespec tp;
1413 1363
1414 memset(info, 0, sizeof(struct sysinfo)); 1364 memset(info, 0, sizeof(struct sysinfo));
1415 1365
1416 do { 1366 ktime_get_ts(&tp);
1417 struct timespec tp; 1367 monotonic_to_bootbased(&tp);
1418 seq = read_seqbegin(&xtime_lock); 1368 info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
1419
1420 /*
1421 * This is annoying. The below is the same thing
1422 * posix_get_clock_monotonic() does, but it wants to
1423 * take the lock which we want to cover the loads stuff
1424 * too.
1425 */
1426
1427 getnstimeofday(&tp);
1428 tp.tv_sec += wall_to_monotonic.tv_sec;
1429 tp.tv_nsec += wall_to_monotonic.tv_nsec;
1430 monotonic_to_bootbased(&tp);
1431 if (tp.tv_nsec - NSEC_PER_SEC >= 0) {
1432 tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC;
1433 tp.tv_sec++;
1434 }
1435 info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
1436 1369
1437 info->loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); 1370 get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT);
1438 info->loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT);
1439 info->loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT);
1440 1371
1441 info->procs = nr_threads; 1372 info->procs = nr_threads;
1442 } while (read_seqretry(&xtime_lock, seq));
1443 1373
1444 si_meminfo(info); 1374 si_meminfo(info);
1445 si_swapinfo(info); 1375 si_swapinfo(info);