]> Zhao Yanbai Git Server - minix.git/commitdiff
Internal 64M buffer for profiling
authorTomas Hruby <tom@minix3.org>
Thu, 23 Sep 2010 10:49:48 +0000 (10:49 +0000)
committerTomas Hruby <tom@minix3.org>
Thu, 23 Sep 2010 10:49:48 +0000 (10:49 +0000)
- when profiling is compiled in kernel includes a 64M buffer for
  sample

- 64M is the default used by profile tool as its buffer

- when using nmi profiling it is not possible to always copy sample
  stright to userland as the nmi may (and does) happen in bad moments

- reduces sampling overhead as samples are copied out only when
  profiling stops

kernel/profile.c
kernel/profile.h
kernel/system/do_sprofile.c

index 626202338784cdbe0f91eb559c77b79cc566dbb9..4319eccd5ada1e0deb75f4e992315c5c34e9fcd7 100644 (file)
@@ -63,32 +63,26 @@ PUBLIC void stop_profile_clock()
 
 PRIVATE sprof_save_sample(struct proc * p)
 {
-       struct sprof_sample s;
+       struct sprof_sample *s;
 
-       s.proc = p->p_endpoint;
-       s.pc = (void *) p->p_reg.pc;
+       s = (struct sprof_sample *) (sprof_sample_buffer + sprof_info.mem_used);
 
-       /* Store sample (process name and program counter). */
-       data_copy(KERNEL, (vir_bytes) &s,
-                       sprof_ep, sprof_data_addr_vir + sprof_info.mem_used,
-                       sizeof(s));
+       s->proc = p->p_endpoint;
+       s->pc = (void *) p->p_reg.pc;
 
-       sprof_info.mem_used += sizeof(s);
+       sprof_info.mem_used += sizeof(struct sprof_sample);
 }
 
 PRIVATE sprof_save_proc(struct proc * p)
 {
-       struct sprof_proc s;
+       struct sprof_proc s;
 
-       s.proc = p->p_endpoint;
-       memcpy(s.name, p->p_name, P_NAME_LEN);
+       s = (struct sprof_proc *) (sprof_sample_buffer + sprof_info.mem_used);
 
-       /* Store sample (process name and program counter). */
-       data_copy(KERNEL, (vir_bytes) &s,
-                       sprof_ep, sprof_data_addr_vir + sprof_info.mem_used,
-                       sizeof(s));
+       s->proc = p->p_endpoint;
+       memcpy(&s->name, p->p_name, P_NAME_LEN);
 
-       sprof_info.mem_used += sizeof(s);
+       sprof_info.mem_used += sizeof(struct sprof_proc);
 }
 
 PRIVATE void profile_sample(struct proc * p)
@@ -100,7 +94,9 @@ PRIVATE void profile_sample(struct proc * p)
          return;
 
   /* Check if enough memory available before writing sample. */
-  if (sprof_info.mem_used + sizeof(sprof_info) > sprof_mem_size) {
+  if (sprof_info.mem_used + sizeof(sprof_info) +
+                 2*sizeof(struct sprof_sample) +
+                 2*sizeof(struct sprof_sample) > sprof_mem_size) {
        sprof_info.mem_used = -1;
        return;
   }
index 275ec87117bfd5d1ca2d700f875f3a44f6ebc6b9..5580bf544792ec1f251015a61d28c9995b6875bb 100644 (file)
@@ -7,6 +7,9 @@
 
 #include "arch_watchdog.h"
 
+#define SAMPLE_BUFFER_SIZE     (64 << 20)
+EXTERN char sprof_sample_buffer[SAMPLE_BUFFER_SIZE];
+
 EXTERN int sprofiling;                 /* whether profiling is running */
 EXTERN int sprofiling_type;                    /* whether profiling is running */
 EXTERN int sprof_mem_size;             /* available user memory for data */
index d4f4b404df78bd1a48fafdeb68005e77344edfef..e5aebc8215121f8dc7faf0ce63bbd7e153dc934e 100644 (file)
@@ -65,7 +65,8 @@ PUBLIC int do_sprofile(struct proc * caller, message * m_ptr)
        sprof_info.system_samples = 0;
        sprof_info.user_samples = 0;
 
-       sprof_mem_size = m_ptr->PROF_MEM_SIZE;
+       sprof_mem_size = m_ptr->PROF_MEM_SIZE < SAMPLE_BUFFER_SIZE ?
+                               m_ptr->PROF_MEM_SIZE : SAMPLE_BUFFER_SIZE;
 
        switch (sprofiling_type = m_ptr->PROF_INTR_TYPE) {
                case PROF_RTC:
@@ -111,6 +112,8 @@ PUBLIC int do_sprofile(struct proc * caller, message * m_ptr)
 
        data_copy(KERNEL, (vir_bytes) &sprof_info,
                sprof_ep, sprof_info_addr_vir, sizeof(sprof_info));
+       data_copy(KERNEL, (vir_bytes) sprof_sample_buffer,
+               sprof_ep, sprof_data_addr_vir, sprof_info.mem_used);
 
        clean_seen_flag();