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

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

Diff for /src/sys/kern/kern_clock.c between version 1.74 and 1.74.2.4

version 1.74, 2001/01/17 18:21:41 version 1.74.2.4, 2001/11/14 19:16:33
Line 77 
Line 77 
  *      @(#)kern_clock.c        8.5 (Berkeley) 1/21/94   *      @(#)kern_clock.c        8.5 (Berkeley) 1/21/94
  */   */
   
   #include <sys/cdefs.h>
   __KERNEL_RCSID(0, "$NetBSD$");
   
   #include "opt_callout.h"
 #include "opt_ntp.h"  #include "opt_ntp.h"
   
 #include <sys/param.h>  #include <sys/param.h>
Line 84 
Line 88 
 #include <sys/dkstat.h>  #include <sys/dkstat.h>
 #include <sys/callout.h>  #include <sys/callout.h>
 #include <sys/kernel.h>  #include <sys/kernel.h>
   #include <sys/lwp.h>
 #include <sys/proc.h>  #include <sys/proc.h>
 #include <sys/resourcevar.h>  #include <sys/resourcevar.h>
 #include <sys/signalvar.h>  #include <sys/signalvar.h>
Line 91 
Line 96 
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
 #include <sys/timex.h>  #include <sys/timex.h>
 #include <sys/sched.h>  #include <sys/sched.h>
   #ifdef CALLWHEEL_STATS
   #include <sys/device.h>
   #endif
   
 #include <machine/cpu.h>  #include <machine/cpu.h>
 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS  #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
Line 314  long clock_cpu = 0;  /* CPU clock adjust
Line 322  long clock_cpu = 0;  /* CPU clock adjust
   
 int     stathz;  int     stathz;
 int     profhz;  int     profhz;
   int     schedhz;
 int     profprocs;  int     profprocs;
 int     softclock_running;              /* 1 => softclock() is running */  int     softclock_running;              /* 1 => softclock() is running */
 static int psdiv;                       /* prof => stat divider */  static int psdiv;                       /* prof => stat divider */
Line 353  int callwheelsize, callwheelbits, callwh
Line 362  int callwheelsize, callwheelbits, callwh
 static struct callout *nextsoftcheck;   /* next callout to be checked */  static struct callout *nextsoftcheck;   /* next callout to be checked */
   
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
 int     callwheel_collisions;           /* number of hash collisions */  int          *callwheel_sizes;          /* per-bucket length count */
 int     callwheel_maxlength;            /* length of the longest hash chain */  struct evcnt callwheel_collisions;      /* number of hash collisions */
 int     *callwheel_sizes;               /* per-bucket length count */  struct evcnt callwheel_maxlength;       /* length of the longest hash chain */
 u_int64_t callwheel_count;              /* # callouts currently */  struct evcnt callwheel_count;           /* # callouts currently */
 u_int64_t callwheel_established;        /* # callouts established */  struct evcnt callwheel_established;     /* # callouts established */
 u_int64_t callwheel_fired;              /* # callouts that fired */  struct evcnt callwheel_fired;           /* # callouts that fired */
 u_int64_t callwheel_disestablished;     /* # callouts disestablished */  struct evcnt callwheel_disestablished;  /* # callouts disestablished */
 u_int64_t callwheel_changed;            /* # callouts changed */  struct evcnt callwheel_changed;         /* # callouts changed */
 u_int64_t callwheel_softclocks;         /* # times softclock() called */  struct evcnt callwheel_softclocks;      /* # times softclock() called */
 u_int64_t callwheel_softchecks;         /* # checks per softclock() */  struct evcnt callwheel_softchecks;      /* # checks per softclock() */
 u_int64_t callwheel_softempty;          /* # empty buckets seen */  struct evcnt callwheel_softempty;       /* # empty buckets seen */
   struct evcnt callwheel_hintworked;      /* # times hint saved scan */
 #endif /* CALLWHEEL_STATS */  #endif /* CALLWHEEL_STATS */
   
 /*  /*
Line 509  initclocks(void)
Line 519  initclocks(void)
 void  void
 hardclock(struct clockframe *frame)  hardclock(struct clockframe *frame)
 {  {
           struct lwp *l;
         struct proc *p;          struct proc *p;
         int delta;          int delta;
         extern int tickdelta;          extern int tickdelta;
Line 519  hardclock(struct clockframe *frame)
Line 530  hardclock(struct clockframe *frame)
         int ltemp;          int ltemp;
 #endif  #endif
   
         p = curproc;          l = curproc;
         if (p) {          if (l) {
                 struct pstats *pstats;                  struct pstats *pstats;
                   p = l->l_proc;
                 /*                  /*
                  * Run current process's virtual and profile time, as needed.                   * Run current process's virtual and profile time, as needed.
                  */                   */
Line 880  hardclock(struct clockframe *frame)
Line 891  hardclock(struct clockframe *frame)
          */           */
         simple_lock(&callwheel_slock);  /* already at splclock() */          simple_lock(&callwheel_slock);  /* already at splclock() */
         hardclock_ticks++;          hardclock_ticks++;
         if (TAILQ_FIRST(&callwheel[hardclock_ticks & callwheelmask]) != NULL) {          if (! TAILQ_EMPTY(&callwheel[hardclock_ticks & callwheelmask].cq_q)) {
                 simple_unlock(&callwheel_slock);                  simple_unlock(&callwheel_slock);
                 if (CLKF_BASEPRI(frame)) {                  if (CLKF_BASEPRI(frame)) {
                         /*                          /*
Line 930  softclock(void *v)
Line 941  softclock(void *v)
         softclock_running = 1;          softclock_running = 1;
   
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
         callwheel_softclocks++;          callwheel_softclocks.ev_count++;
 #endif  #endif
   
         while (softclock_ticks != hardclock_ticks) {          while (softclock_ticks != hardclock_ticks) {
                 softclock_ticks++;                  softclock_ticks++;
                 idx = (int)(softclock_ticks & callwheelmask);                  idx = (int)(softclock_ticks & callwheelmask);
                 bucket = &callwheel[idx];                  bucket = &callwheel[idx];
                 c = TAILQ_FIRST(bucket);                  c = TAILQ_FIRST(&bucket->cq_q);
                   if (c == NULL) {
   #ifdef CALLWHEEL_STATS
                           callwheel_softempty.ev_count++;
   #endif
                           continue;
                   }
                   if (softclock_ticks < bucket->cq_hint) {
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
                 if (c == NULL)                          callwheel_hintworked.ev_count++;
                         callwheel_softempty++;  
 #endif  #endif
                           continue;
                   }
                   bucket->cq_hint = UQUAD_MAX;
                 while (c != NULL) {                  while (c != NULL) {
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
                         callwheel_softchecks++;                          callwheel_softchecks.ev_count++;
 #endif  #endif
                         if (c->c_time != softclock_ticks) {                          if (c->c_time != softclock_ticks) {
                                   if (c->c_time < bucket->cq_hint)
                                           bucket->cq_hint = c->c_time;
                                 c = TAILQ_NEXT(c, c_link);                                  c = TAILQ_NEXT(c, c_link);
                                 if (++steps >= MAX_SOFTCLOCK_STEPS) {                                  if (++steps >= MAX_SOFTCLOCK_STEPS) {
                                         nextsoftcheck = c;                                          nextsoftcheck = c;
Line 958  softclock(void *v)
Line 980  softclock(void *v)
                                 }                                  }
                         } else {                          } else {
                                 nextsoftcheck = TAILQ_NEXT(c, c_link);                                  nextsoftcheck = TAILQ_NEXT(c, c_link);
                                 TAILQ_REMOVE(bucket, c, c_link);                                  TAILQ_REMOVE(&bucket->cq_q, c, c_link);
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
                                 callwheel_sizes[idx]--;                                  callwheel_sizes[idx]--;
                                 callwheel_fired++;                                  callwheel_fired.ev_count++;
                                 callwheel_count--;                                  callwheel_count.ev_count--;
 #endif  #endif
                                 func = c->c_func;                                  func = c->c_func;
                                 arg = c->c_arg;                                  arg = c->c_arg;
Line 975  softclock(void *v)
Line 997  softclock(void *v)
                                 c = nextsoftcheck;                                  c = nextsoftcheck;
                         }                          }
                 }                  }
                   if (TAILQ_EMPTY(&bucket->cq_q))
                           bucket->cq_hint = UQUAD_MAX;
         }          }
         nextsoftcheck = NULL;          nextsoftcheck = NULL;
         softclock_running = 0;          softclock_running = 0;
Line 1006  callout_startup(void)
Line 1030  callout_startup(void)
 {  {
         int i;          int i;
   
         for (i = 0; i < callwheelsize; i++)          for (i = 0; i < callwheelsize; i++) {
                 TAILQ_INIT(&callwheel[i]);                  callwheel[i].cq_hint = UQUAD_MAX;
                   TAILQ_INIT(&callwheel[i].cq_q);
           }
   
         simple_lock_init(&callwheel_slock);          simple_lock_init(&callwheel_slock);
   
   #ifdef CALLWHEEL_STATS
           evcnt_attach_dynamic(&callwheel_collisions, EVCNT_TYPE_MISC,
               NULL, "callwheel", "collisions");
           evcnt_attach_dynamic(&callwheel_maxlength, EVCNT_TYPE_MISC,
               NULL, "callwheel", "maxlength");
           evcnt_attach_dynamic(&callwheel_count, EVCNT_TYPE_MISC,
               NULL, "callwheel", "count");
           evcnt_attach_dynamic(&callwheel_established, EVCNT_TYPE_MISC,
               NULL, "callwheel", "established");
           evcnt_attach_dynamic(&callwheel_fired, EVCNT_TYPE_MISC,
               NULL, "callwheel", "fired");
           evcnt_attach_dynamic(&callwheel_disestablished, EVCNT_TYPE_MISC,
               NULL, "callwheel", "disestablished");
           evcnt_attach_dynamic(&callwheel_changed, EVCNT_TYPE_MISC,
               NULL, "callwheel", "changed");
           evcnt_attach_dynamic(&callwheel_softclocks, EVCNT_TYPE_MISC,
               NULL, "callwheel", "softclocks");
           evcnt_attach_dynamic(&callwheel_softempty, EVCNT_TYPE_MISC,
               NULL, "callwheel", "softempty");
           evcnt_attach_dynamic(&callwheel_hintworked, EVCNT_TYPE_MISC,
               NULL, "callwheel", "hintworked");
   #endif /* CALLWHEEL_STATS */
 }  }
   
 /*  /*
Line 1048  callout_reset(struct callout *c, int tic
Line 1097  callout_reset(struct callout *c, int tic
         if (c->c_flags & CALLOUT_PENDING) {          if (c->c_flags & CALLOUT_PENDING) {
                 callout_stop_locked(c); /* Already locked */                  callout_stop_locked(c); /* Already locked */
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
                 callwheel_changed++;                  callwheel_changed.ev_count++;
 #endif  #endif
         }          }
   
Line 1060  callout_reset(struct callout *c, int tic
Line 1109  callout_reset(struct callout *c, int tic
         bucket = &callwheel[c->c_time & callwheelmask];          bucket = &callwheel[c->c_time & callwheelmask];
   
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
         if (TAILQ_FIRST(bucket) != NULL)          if (! TAILQ_EMPTY(&bucket->cq_q))
                 callwheel_collisions++;                  callwheel_collisions.ev_count++;
 #endif  #endif
   
         TAILQ_INSERT_TAIL(bucket, c, c_link);          TAILQ_INSERT_TAIL(&bucket->cq_q, c, c_link);
           if (c->c_time < bucket->cq_hint)
                   bucket->cq_hint = c->c_time;
   
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
         callwheel_count++;          callwheel_count.ev_count++;
         callwheel_established++;          callwheel_established.ev_count++;
         if (++callwheel_sizes[c->c_time & callwheelmask] > callwheel_maxlength)          if (++callwheel_sizes[c->c_time & callwheelmask] >
                 callwheel_maxlength =              callwheel_maxlength.ev_count)
                   callwheel_maxlength.ev_count =
                     callwheel_sizes[c->c_time & callwheelmask];                      callwheel_sizes[c->c_time & callwheelmask];
 #endif  #endif
   
Line 1085  callout_reset(struct callout *c, int tic
Line 1137  callout_reset(struct callout *c, int tic
 static void  static void
 callout_stop_locked(struct callout *c)  callout_stop_locked(struct callout *c)
 {  {
           struct callout_queue *bucket;
   
         /*          /*
          * Don't attempt to delete a callout that's not on the queue.           * Don't attempt to delete a callout that's not on the queue.
Line 1099  callout_stop_locked(struct callout *c)
Line 1152  callout_stop_locked(struct callout *c)
         if (nextsoftcheck == c)          if (nextsoftcheck == c)
                 nextsoftcheck = TAILQ_NEXT(c, c_link);                  nextsoftcheck = TAILQ_NEXT(c, c_link);
   
         TAILQ_REMOVE(&callwheel[c->c_time & callwheelmask], c, c_link);          bucket = &callwheel[c->c_time & callwheelmask];
           TAILQ_REMOVE(&bucket->cq_q, c, c_link);
           if (TAILQ_EMPTY(&bucket->cq_q))
                   bucket->cq_hint = UQUAD_MAX;
 #ifdef CALLWHEEL_STATS  #ifdef CALLWHEEL_STATS
         callwheel_count--;          callwheel_count.ev_count--;
         callwheel_disestablished++;          callwheel_disestablished.ev_count++;
         callwheel_sizes[c->c_time & callwheelmask]--;          callwheel_sizes[c->c_time & callwheelmask]--;
 #endif  #endif
   
Line 1142  callout_showstats(void)
Line 1198  callout_showstats(void)
         splx(s);          splx(s);
   
         printf("Callwheel statistics:\n");          printf("Callwheel statistics:\n");
         printf("\tCallouts currently queued: %llu\n", callwheel_count);          printf("\tCallouts currently queued: %llu\n",
         printf("\tCallouts established: %llu\n", callwheel_established);              (long long) callwheel_count.ev_count);
         printf("\tCallouts disestablished: %llu\n", callwheel_disestablished);          printf("\tCallouts established: %llu\n",
         if (callwheel_changed != 0)              (long long) callwheel_established.ev_count);
                 printf("\t\tOf those, %llu were changes\n", callwheel_changed);          printf("\tCallouts disestablished: %llu\n",
         printf("\tCallouts that fired: %llu\n", callwheel_fired);              (long long) callwheel_disestablished.ev_count);
           if (callwheel_changed.ev_count != 0)
                   printf("\t\tOf those, %llu were changes\n",
                       (long long) callwheel_changed.ev_count);
           printf("\tCallouts that fired: %llu\n",
               (long long) callwheel_fired.ev_count);
         printf("\tNumber of buckets: %d\n", callwheelsize);          printf("\tNumber of buckets: %d\n", callwheelsize);
         printf("\tNumber of hash collisions: %d\n", callwheel_collisions);          printf("\tNumber of hash collisions: %llu\n",
         printf("\tMaximum hash chain length: %d\n", callwheel_maxlength);              (long long) callwheel_collisions.ev_count);
           printf("\tMaximum hash chain length: %llu\n",
               (long long) callwheel_maxlength.ev_count);
         printf("\tSoftclocks: %llu, Softchecks: %llu\n",          printf("\tSoftclocks: %llu, Softchecks: %llu\n",
             callwheel_softclocks, callwheel_softchecks);              (long long) callwheel_softclocks.ev_count,
         printf("\t\tEmpty buckets seen: %llu\n", callwheel_softempty);              (long long) callwheel_softchecks.ev_count);
           printf("\t\tEmpty buckets seen: %llu\n",
               (long long) callwheel_softempty.ev_count);
           printf("\t\tTimes hint saved scan: %llu\n",
               (long long) callwheel_hintworked.ev_count);
 }  }
 #endif  #endif
   
Line 1264  statclock(struct clockframe *frame)
Line 1331  statclock(struct clockframe *frame)
 #endif  #endif
         struct cpu_info *ci = curcpu();          struct cpu_info *ci = curcpu();
         struct schedstate_percpu *spc = &ci->ci_schedstate;          struct schedstate_percpu *spc = &ci->ci_schedstate;
           struct lwp *l;
         struct proc *p;          struct proc *p;
   
         /*          /*
Line 1279  statclock(struct clockframe *frame)
Line 1347  statclock(struct clockframe *frame)
                         setstatclockrate(profhz);                          setstatclockrate(profhz);
                 }                  }
         }          }
         p = curproc;          l = curproc;
           p = (l ? l->l_proc : 0);
         if (CLKF_USERMODE(frame)) {          if (CLKF_USERMODE(frame)) {
                 if (p->p_flag & P_PROFIL)                  if (p->p_flag & P_PROFIL)
                         addupc_intr(p, CLKF_PC(frame));                          addupc_intr(p, CLKF_PC(frame));
Line 1308  statclock(struct clockframe *frame)
Line 1377  statclock(struct clockframe *frame)
                         }                          }
                 }                  }
 #endif  #endif
 #ifdef PROC_PC  #ifdef LWP_PC
                 if (p && p->p_flag & P_PROFIL)                  if (p && p->p_flag & P_PROFIL)
                         addupc_intr(p, PROC_PC(p));                          addupc_intr(p, LWP_PC(l));
 #endif  #endif
                 if (--spc->spc_pscnt > 0)                  if (--spc->spc_pscnt > 0)
                         return;                          return;
Line 1338  statclock(struct clockframe *frame)
Line 1407  statclock(struct clockframe *frame)
         }          }
         spc->spc_pscnt = psdiv;          spc->spc_pscnt = psdiv;
   
         if (p != NULL) {          if (l != NULL) {
                 ++p->p_cpticks;                  ++p->p_cpticks;
                 /*                  /*
                  * If no separate schedclock is provided, call it here                   * If no separate schedclock is provided, call it here
Line 1346  statclock(struct clockframe *frame)
Line 1415  statclock(struct clockframe *frame)
                  */                   */
                 if (schedhz == 0)                  if (schedhz == 0)
                         if ((++ci->ci_schedstate.spc_schedticks & 3) == 0)                          if ((++ci->ci_schedstate.spc_schedticks & 3) == 0)
                                 schedclock(p);                                  schedclock(l);
         }          }
 }  }
   

Legend:
Removed from v.1.74  
changed lines
  Added in v.1.74.2.4

CVSweb <webmaster@jp.NetBSD.org>