patch-2.4.0-test3 linux/kernel/timer.c
Next file: linux/lib/Makefile
Previous file: linux/kernel/sysctl.c
Back to the patch index
Back to the overall index
- Lines: 172
- Date:
Mon Jul 10 14:35:19 2000
- Orig file:
v2.4.0-test2/linux/kernel/timer.c
- Orig date:
Fri May 12 14:18:56 2000
diff -u --recursive --new-file v2.4.0-test2/linux/kernel/timer.c linux/kernel/timer.c
@@ -160,7 +160,9 @@
list_add(&timer->list, vec->prev);
}
+/* Initialize both explicitly - let's try to have them in the same cache line */
spinlock_t timerlist_lock = SPIN_LOCK_UNLOCKED;
+volatile struct timer_list *running_timer = NULL;
void add_timer(struct timer_list *timer)
{
@@ -233,11 +235,12 @@
spin_lock_irqsave(&timerlist_lock, flags);
ret += detach_timer(timer);
timer->list.next = timer->list.prev = 0;
- running = timer->running;
+ running = timer_is_running(timer);
spin_unlock_irqrestore(&timerlist_lock, flags);
if (!running)
- return ret;
+ break;
+
timer_synchronize(timer);
}
@@ -295,10 +298,11 @@
detach_timer(timer);
timer->list.next = timer->list.prev = NULL;
- timer_set_running(timer);
+ timer_enter(timer);
spin_unlock_irq(&timerlist_lock);
fn(data);
spin_lock_irq(&timerlist_lock);
+ timer_exit();
goto repeat;
}
++timer_jiffies;
@@ -307,25 +311,6 @@
spin_unlock_irq(&timerlist_lock);
}
-
-static inline void run_old_timers(void)
-{
- struct timer_struct *tp;
- unsigned long mask;
-
- for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) {
- if (mask > timer_active)
- break;
- if (!(mask & timer_active))
- continue;
- if (time_after(tp->expires, jiffies))
- continue;
- timer_active &= ~mask;
- tp->fn();
- sti();
- }
-}
-
spinlock_t tqueue_lock = SPIN_LOCK_UNLOCKED;
void tqueue_bh(void)
@@ -338,9 +323,6 @@
run_task_queue(&tq_immediate);
}
-unsigned long timer_active;
-struct timer_struct timer_table[32];
-
/*
* this routine handles the overflow of the microsecond field
*
@@ -577,27 +559,32 @@
do_it_prof(p, ticks);
}
-static void update_process_times(unsigned long ticks, unsigned long system)
+/*
+ * Called from the timer interrupt handler to charge one tick to the current
+ * process. user_tick is 1 if the tick is user time, 0 for system.
+ */
+static void update_process_times(int user_tick)
{
/*
* SMP does this on a per-CPU basis elsewhere
*/
#ifndef CONFIG_SMP
- struct task_struct * p = current;
- unsigned long user = ticks - system;
+ struct task_struct *p = current;
+ int system = !user_tick;
+
if (p->pid) {
- p->counter -= ticks;
- if (p->counter <= 0) {
+ if (--p->counter <= 0) {
p->counter = 0;
p->need_resched = 1;
}
if (p->priority < DEF_PRIORITY)
- kstat.cpu_nice += user;
+ kstat.cpu_nice += user_tick;
else
- kstat.cpu_user += user;
+ kstat.cpu_user += user_tick;
kstat.cpu_system += system;
- }
- update_one_process(p, ticks, user, system, 0);
+ } else if (local_bh_count(0) || local_irq_count(0) > 1)
+ kstat.cpu_system += system;
+ update_one_process(p, 1, user_tick, system, 0);
#endif
}
@@ -642,8 +629,8 @@
}
}
-volatile unsigned long lost_ticks;
-static unsigned long lost_ticks_system;
+/* jiffies at the most recent update of wall time */
+unsigned long wall_jiffies;
/*
* This spinlock protect us from races in SMP while playing with xtime. -arca
@@ -661,37 +648,26 @@
*/
write_lock_irq(&xtime_lock);
- ticks = lost_ticks;
- lost_ticks = 0;
-
+ ticks = jiffies - wall_jiffies;
if (ticks) {
- unsigned long system;
- system = xchg(&lost_ticks_system, 0);
-
- calc_load(ticks);
+ wall_jiffies += ticks;
update_wall_time(ticks);
- write_unlock_irq(&xtime_lock);
-
- update_process_times(ticks, system);
-
- } else
- write_unlock_irq(&xtime_lock);
+ }
+ write_unlock_irq(&xtime_lock);
+ calc_load(ticks);
}
void timer_bh(void)
{
update_times();
- run_old_timers();
run_timer_list();
}
-void do_timer(struct pt_regs * regs)
+void do_timer(struct pt_regs *regs)
{
(*(unsigned long *)&jiffies)++;
- lost_ticks++;
+ update_process_times(user_mode(regs));
mark_bh(TIMER_BH);
- if (!user_mode(regs))
- lost_ticks_system++;
if (tq_timer)
mark_bh(TQUEUE_BH);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)