patch-2.1.36 linux/arch/i386/kernel/smp.c
Next file: linux/arch/i386/kernel/time.c
Previous file: linux/arch/i386/kernel/signal.c
Back to the patch index
Back to the overall index
- Lines: 156
- Date:
Wed Apr 16 16:52:23 1997
- Orig file:
v2.1.35/linux/arch/i386/kernel/smp.c
- Orig date:
Wed Apr 16 14:14:59 1997
diff -u --recursive --new-file v2.1.35/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
@@ -49,6 +49,9 @@
#include "irq.h"
extern unsigned long start_kernel, _etext;
+extern void update_one_process( struct task_struct *p,
+ unsigned long ticks, unsigned long user,
+ unsigned long system);
void setup_APIC_clock (void);
/*
@@ -1307,37 +1310,6 @@
}
/*
- * Platform specific profiling function.
- * it builds a 'prof_shift' resolution EIP distribution histogram
- *
- * it's SMP safe.
- */
-
-static inline void x86_do_profile (unsigned long eip)
-{
- if (prof_buffer && current->pid) {
- extern int _stext;
- eip -= (unsigned long) &_stext;
- eip >>= prof_shift;
- if (eip < prof_len)
- atomic_inc(&prof_buffer[eip]);
- else
- /*
- * Dont ignore out-of-bounds EIP values silently,
- * put them into the last histogram slot, so if
- * present, they will show up as a sharp peak.
- */
- atomic_inc(&prof_buffer[prof_len-1]);
- }
-}
-
-unsigned int prof_multiplier[NR_CPUS];
-unsigned int prof_counter[NR_CPUS];
-
-extern void update_one_process( struct task_struct *p,
- unsigned long ticks, unsigned long user,
- unsigned long system);
-/*
* Local timer interrupt handler. It does both profiling and
* process statistics/rescheduling.
*
@@ -1346,14 +1318,19 @@
* multiplier is 1 and it can be changed by writing a 4 bytes multiplier
* value into /proc/profile.
*/
+
+unsigned int prof_multiplier[NR_CPUS];
+unsigned int prof_counter[NR_CPUS];
+
static inline void smp_local_timer_interrupt(struct pt_regs * regs)
{
int cpu = smp_processor_id();
+
/*
- * Both the profiling function and the statistics
- * counters are SMP safe. We leave the APIC irq
- * unacked while updating the profiling info, thus
- * we cannot be interrupted by the same APIC interrupt.
+ * The profiling function is SMP safe. (nothing can mess
+ * around with "current", and the profiling counters are
+ * updated with atomic operations). This is especially
+ * useful with a profiling multiplier != 1
*/
if (!user_mode(regs))
x86_do_profile (regs->eip);
@@ -1363,13 +1340,10 @@
struct task_struct * p = current;
/*
- * We mess around with thread statistics, but
- * since we are the CPU running it, we dont
- * have to lock it. We assume that switch_to()
- * protects 'current' against local irqs via __cli.
- *
- * kernel statistics counters are updated via atomic
- * operations.
+ * After doing the above, we need to make like
+ * a normal interrupt - otherwise timer interrupts
+ * ignore the global interrupt lock, which is the
+ * WrongThing (tm) to do.
*/
if (user_mode(regs))
@@ -1377,7 +1351,9 @@
else
system=1;
+ irq_enter(cpu, 0);
if (p->pid) {
+
update_one_process(p, 1, user, system);
p->counter -= 1;
@@ -1386,25 +1362,21 @@
need_resched = 1;
}
if (p->priority < DEF_PRIORITY)
- atomic_add (user, &kstat.cpu_nice);
+ kstat.cpu_nice += user;
else
- atomic_add (user, &kstat.cpu_user);
+ kstat.cpu_user += user;
- atomic_add (system, &kstat.cpu_system);
+ kstat.cpu_system += system;
} else {
#ifdef __SMP_PROF__
if (test_bit(cpu,&smp_idle_map))
smp_idle_count[cpu]++;
#endif
- /*
- * This is a hack until we have need_resched[]
- */
- if (read_smp_counter(&smp_process_available))
- need_resched=1;
}
-
prof_counter[cpu]=prof_multiplier[cpu];
+
+ irq_exit(cpu, 0);
}
#ifdef __SMP_PROF__
@@ -1432,8 +1404,6 @@
*/
void smp_apic_timer_interrupt(struct pt_regs * regs)
{
- int cpu = smp_processor_id();
-
/*
* NOTE! We'd better ACK the irq immediately,
* because timer handling can be slow, and we
@@ -1442,15 +1412,7 @@
*/
ack_APIC_irq ();
- /*
- * After doing the above, we need to make like
- * a normal interrupt - otherwise timer interrupts
- * ignore the global interrupt lock, which is the
- * WrongThing (tm) to do.
- */
- irq_enter(cpu, 0);
smp_local_timer_interrupt(regs);
- irq_exit(cpu, 0);
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov