[BACK]Return to tprof.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / tprof

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/tprof/tprof.c between version 1.7 and 1.7.2.1

version 1.7, 2010/08/11 11:36:02 version 1.7.2.1, 2011/06/06 09:08:40
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*-  /*-
  * Copyright (c)2008,2009 YAMAMOTO Takashi,   * Copyright (c)2008,2009,2010 YAMAMOTO Takashi,
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 38  __KERNEL_RCSID(0, "$NetBSD$");
Line 38  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/callout.h>  #include <sys/callout.h>
 #include <sys/kmem.h>  #include <sys/kmem.h>
 #include <sys/module.h>  #include <sys/module.h>
   #include <sys/proc.h>
 #include <sys/workqueue.h>  #include <sys/workqueue.h>
 #include <sys/queue.h>  #include <sys/queue.h>
   
Line 55  __KERNEL_RCSID(0, "$NetBSD$");
Line 56  __KERNEL_RCSID(0, "$NetBSD$");
  *      L: tprof_lock   *      L: tprof_lock
  *      R: tprof_reader_lock   *      R: tprof_reader_lock
  *      S: tprof_startstop_lock   *      S: tprof_startstop_lock
    *      s: writer should hold tprof_startstop_lock and tprof_lock
    *         reader should hold tprof_startstop_lock or tprof_lock
  */   */
   
 typedef struct {  
         uintptr_t s_pc; /* program counter */  
 } tprof_sample_t;  
   
 typedef struct tprof_buf {  typedef struct tprof_buf {
         u_int b_used;          u_int b_used;
         u_int b_size;          u_int b_size;
Line 77  typedef struct tprof_buf {
Line 76  typedef struct tprof_buf {
   
 typedef struct {  typedef struct {
         tprof_buf_t *c_buf;          tprof_buf_t *c_buf;
           uint32_t c_cpuid;
         struct work c_work;          struct work c_work;
         callout_t c_callout;          callout_t c_callout;
 } __aligned(CACHE_LINE_SIZE) tprof_cpu_t;  } __aligned(CACHE_LINE_SIZE) tprof_cpu_t;
Line 89  typedef struct tprof_backend {
Line 89  typedef struct tprof_backend {
 } tprof_backend_t;  } tprof_backend_t;
   
 static kmutex_t tprof_lock;  static kmutex_t tprof_lock;
 static bool tprof_running;  static bool tprof_running;              /* s: */
 static u_int tprof_nworker;             /* L: # of running worker LWPs */  static u_int tprof_nworker;             /* L: # of running worker LWPs */
 static lwp_t *tprof_owner;  static lwp_t *tprof_owner;
 static STAILQ_HEAD(, tprof_buf) tprof_list; /* L: global buffer list */  static STAILQ_HEAD(, tprof_buf) tprof_list; /* L: global buffer list */
Line 296  tprof_start(const struct tprof_param *pa
Line 296  tprof_start(const struct tprof_param *pa
   
         error = tb->tb_ops->tbo_start(NULL);          error = tb->tb_ops->tbo_start(NULL);
         if (error != 0) {          if (error != 0) {
                   KASSERT(tb->tb_usecount > 0);
                   tb->tb_usecount--;
                 tprof_stop1();                  tprof_stop1();
                 goto done;                  goto done;
         }          }
Line 318  done:
Line 320  done:
 static void  static void
 tprof_stop(void)  tprof_stop(void)
 {  {
         CPU_INFO_ITERATOR cii;  
         struct cpu_info *ci;  
         tprof_backend_t *tb;          tprof_backend_t *tb;
   
         KASSERT(mutex_owned(&tprof_startstop_lock));          KASSERT(mutex_owned(&tprof_startstop_lock));
Line 335  tprof_stop(void)
Line 335  tprof_stop(void)
         mutex_enter(&tprof_lock);          mutex_enter(&tprof_lock);
         tprof_running = false;          tprof_running = false;
         cv_broadcast(&tprof_reader_cv);          cv_broadcast(&tprof_reader_cv);
         mutex_exit(&tprof_lock);          while (tprof_nworker > 0) {
                   cv_wait(&tprof_cv, &tprof_lock);
         for (CPU_INFO_FOREACH(cii, ci)) {  
                 mutex_enter(&tprof_lock);  
                 while (tprof_nworker > 0) {  
                         cv_wait(&tprof_cv, &tprof_lock);  
                 }  
                 mutex_exit(&tprof_lock);  
         }          }
           mutex_exit(&tprof_lock);
   
         tprof_stop1();          tprof_stop1();
 done:  done:
Line 400  tprof_backend_lookup(const char *name)
Line 395  tprof_backend_lookup(const char *name)
  * tprof_sample: record a sample on the per-cpu buffer.   * tprof_sample: record a sample on the per-cpu buffer.
  *   *
  * be careful; can be called in NMI context.   * be careful; can be called in NMI context.
  * we are assuming that curcpu() is safe.   * we are bluntly assuming the followings are safe.
    *      curcpu()
    *      curlwp->l_lid
    *      curlwp->l_proc->p_pid
  */   */
   
 void  void
Line 408  tprof_sample(tprof_backend_cookie_t *coo
Line 406  tprof_sample(tprof_backend_cookie_t *coo
 {  {
         tprof_cpu_t * const c = tprof_curcpu();          tprof_cpu_t * const c = tprof_curcpu();
         tprof_buf_t * const buf = c->c_buf;          tprof_buf_t * const buf = c->c_buf;
           tprof_sample_t *sp;
         const uintptr_t pc = tfi->tfi_pc;          const uintptr_t pc = tfi->tfi_pc;
           const lwp_t * const l = curlwp;
         u_int idx;          u_int idx;
   
         idx = buf->b_used;          idx = buf->b_used;
Line 416  tprof_sample(tprof_backend_cookie_t *coo
Line 416  tprof_sample(tprof_backend_cookie_t *coo
                 buf->b_overflow++;                  buf->b_overflow++;
                 return;                  return;
         }          }
         buf->b_data[idx].s_pc = pc;          sp = &buf->b_data[idx];
           sp->s_pid = l->l_proc->p_pid;
           sp->s_lwpid = l->l_lid;
           sp->s_cpuid = c->c_cpuid;
           sp->s_flags = (tfi->tfi_inkernel) ? TPROF_SAMPLE_INKERNEL : 0;
           sp->s_pc = pc;
         buf->b_used = idx + 1;          buf->b_used = idx + 1;
 }  }
   
Line 662  MODULE(MODULE_CLASS_DRIVER, tprof, NULL)
Line 667  MODULE(MODULE_CLASS_DRIVER, tprof, NULL)
 static void  static void
 tprof_driver_init(void)  tprof_driver_init(void)
 {  {
           unsigned int i;
   
         mutex_init(&tprof_lock, MUTEX_DEFAULT, IPL_NONE);          mutex_init(&tprof_lock, MUTEX_DEFAULT, IPL_NONE);
         mutex_init(&tprof_reader_lock, MUTEX_DEFAULT, IPL_NONE);          mutex_init(&tprof_reader_lock, MUTEX_DEFAULT, IPL_NONE);
Line 669  tprof_driver_init(void)
Line 675  tprof_driver_init(void)
         cv_init(&tprof_cv, "tprof");          cv_init(&tprof_cv, "tprof");
         cv_init(&tprof_reader_cv, "tprof_rd");          cv_init(&tprof_reader_cv, "tprof_rd");
         STAILQ_INIT(&tprof_list);          STAILQ_INIT(&tprof_list);
           for (i = 0; i < __arraycount(tprof_cpus); i++) {
                   tprof_cpu_t * const c = &tprof_cpus[i];
   
                   c->c_buf = NULL;
                   c->c_cpuid = i;
           }
 }  }
   
 static void  static void

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.7.2.1

CVSweb <webmaster@jp.NetBSD.org>