sprofile exports kernel sample entries

- in case of kernel hit while proc_ptr is IDLE, account for idle time
  instead of taking kernel sample
This commit is contained in:
Tomas Hruby 2010-09-23 10:49:50 +00:00
parent 87c576584d
commit d2b56f60da

View file

@ -61,14 +61,14 @@ PUBLIC void stop_profile_clock()
rm_irq_handler(&profile_clock_hook); 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; struct sprof_sample *s;
s = (struct sprof_sample *) (sprof_sample_buffer + sprof_info.mem_used); s = (struct sprof_sample *) (sprof_sample_buffer + sprof_info.mem_used);
s->proc = p->p_endpoint; 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_sample);
} }
@ -85,7 +85,7 @@ PRIVATE sprof_save_proc(struct proc * p)
sprof_info.mem_used += sizeof(struct sprof_proc); 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. */ /* This executes on every tick of the CMOS timer. */
@ -109,8 +109,9 @@ PRIVATE void profile_sample(struct proc * p)
/* Runnable system process? */ /* Runnable system process? */
if (p->p_endpoint == IDLE) if (p->p_endpoint == IDLE)
sprof_info.idle_samples++; sprof_info.idle_samples++;
else if (priv(p)->s_flags & SYS_PROC && proc_is_runnable(p)) { else if (p->p_endpoint == KERNEL ||
sprof_save_sample(p); (priv(p)->s_flags & SYS_PROC && proc_is_runnable(p))) {
sprof_save_sample(p, pc);
sprof_info.system_samples++; sprof_info.system_samples++;
} else { } else {
/* User process. */ /* User process. */
@ -128,7 +129,7 @@ PRIVATE int profile_clock_handler(irq_hook_t *hook)
struct proc * p; struct proc * p;
p = get_cpulocal_var(proc_ptr); p = get_cpulocal_var(proc_ptr);
profile_sample(p); profile_sample(p, (void *) p->p_reg.pc);
/* Acknowledge interrupt if necessary. */ /* Acknowledge interrupt if necessary. */
arch_ack_profile_clock(); arch_ack_profile_clock();
@ -138,6 +139,7 @@ PRIVATE int profile_clock_handler(irq_hook_t *hook)
PUBLIC void nmi_sprofile_handler(struct nmi_frame * frame) 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 * test if the kernel was interrupted. If so, save first a sample fo
* kernel and than for the current process, otherwise save just the * kernel and than for the current process, otherwise save just the
@ -146,13 +148,22 @@ PUBLIC void nmi_sprofile_handler(struct nmi_frame * frame)
if (nmi_in_kernel(frame)) { if (nmi_in_kernel(frame)) {
struct proc *kern; struct proc *kern;
kern = proc_addr(KERNEL); /*
kern->p_reg.pc = frame->pc; * 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;
}
profile_sample(kern); kern = proc_addr(KERNEL);
profile_sample(kern, (void *) frame->pc);
} }
else
profile_sample(get_cpulocal_var(proc_ptr)); profile_sample(p, (void *) frame->pc);
} }
#endif /* SPROFILE */ #endif /* SPROFILE */