rm_irq_handler(&profile_clock_hook);
}
-PRIVATE sprof_save_sample(struct proc * p)
+PRIVATE sprof_save_sample(struct proc * p, void * pc)
{
struct sprof_sample *s;
s = (struct sprof_sample *) (sprof_sample_buffer + sprof_info.mem_used);
s->proc = p->p_endpoint;
- s->pc = (void *) p->p_reg.pc;
+ s->pc = pc;
sprof_info.mem_used += sizeof(struct sprof_sample);
}
sprof_info.mem_used += sizeof(struct sprof_proc);
}
-PRIVATE void profile_sample(struct proc * p)
+PRIVATE void profile_sample(struct proc * p, void * pc)
{
/* This executes on every tick of the CMOS timer. */
/* Runnable system process? */
if (p->p_endpoint == IDLE)
sprof_info.idle_samples++;
- else if (priv(p)->s_flags & SYS_PROC && proc_is_runnable(p)) {
- sprof_save_sample(p);
+ else if (p->p_endpoint == KERNEL ||
+ (priv(p)->s_flags & SYS_PROC && proc_is_runnable(p))) {
+ sprof_save_sample(p, pc);
sprof_info.system_samples++;
} else {
/* User process. */
struct proc * p;
p = get_cpulocal_var(proc_ptr);
- profile_sample(p);
+ profile_sample(p, (void *) p->p_reg.pc);
/* Acknowledge interrupt if necessary. */
arch_ack_profile_clock();
PUBLIC void nmi_sprofile_handler(struct nmi_frame * frame)
{
+ struct proc * p = get_cpulocal_var(proc_ptr);
/*
* test if the kernel was interrupted. If so, save first a sample fo
* kernel and than for the current process, otherwise save just the
if (nmi_in_kernel(frame)) {
struct proc *kern;
+ /*
+ * if we sample kernel, check if IDLE is scheduled. If so,
+ * account for idle time rather than taking kernel sample
+ */
+ if (p->p_endpoint == IDLE) {
+ sprof_info.idle_samples++;
+ sprof_info.total_samples++;
+ return;
+ }
+
kern = proc_addr(KERNEL);
- kern->p_reg.pc = frame->pc;
- profile_sample(kern);
+ profile_sample(kern, (void *) frame->pc);
}
-
- profile_sample(get_cpulocal_var(proc_ptr));
+ else
+ profile_sample(p, (void *) frame->pc);
}
#endif /* SPROFILE */