]> Zhao Yanbai Git Server - minix.git/commitdiff
sprofile exports kernel sample entries
authorTomas Hruby <tom@minix3.org>
Thu, 23 Sep 2010 10:49:50 +0000 (10:49 +0000)
committerTomas Hruby <tom@minix3.org>
Thu, 23 Sep 2010 10:49:50 +0000 (10:49 +0000)
- in case of kernel hit while proc_ptr is IDLE, account for idle time
  instead of taking kernel sample

kernel/profile.c

index 4319eccd5ada1e0deb75f4e992315c5c34e9fcd7..73f79bd46eee5b5cf85c61a7fc20b6c20154078f 100644 (file)
@@ -61,14 +61,14 @@ PUBLIC void stop_profile_clock()
   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);
 }
@@ -85,7 +85,7 @@ PRIVATE sprof_save_proc(struct proc * p)
        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. */
 
@@ -109,8 +109,9 @@ PRIVATE void profile_sample(struct proc * p)
   /* 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. */
@@ -128,7 +129,7 @@ PRIVATE int profile_clock_handler(irq_hook_t *hook)
   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();
@@ -138,6 +139,7 @@ PRIVATE int profile_clock_handler(irq_hook_t *hook)
 
 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
@@ -146,13 +148,22 @@ PUBLIC void nmi_sprofile_handler(struct nmi_frame * frame)
        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 */