The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/tools/lockstat/lockstat.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include <mach/mach.h>
    2 #include <stdlib.h>
    3 #include <stdio.h>
    4 #include <signal.h>
    5 #include <unistd.h>
    6 #include <sys/time.h>
    7 #include <time.h>
    8 #include <mach/error.h>
    9 #include <mach/mach_error.h>
   10 #include <mach/mig_errors.h>
   11 #include <mach/machine.h>
   12 #include <mach/processor_info.h>
   13 #include <assert.h>
   14 #include <nlist.h>
   15 #include <fcntl.h>
   16 #include <string.h>
   17 #include <mach/mach.h>
   18 #include <mach/host_info.h>
   19 
   20 /*
   21  *      lockstat.c
   22  *
   23  *      Utility to display kernel lock contention statistics.
   24  *      Usage:
   25  *      lockstat [all, spin, mutex, rw, <lock group name>] {<repeat interval>} {abs}
   26  *
   27  *      Argument 1 specifies the type of lock to display contention statistics
   28  *      for; alternatively, a lock group (a logically grouped set of locks,
   29  *      which can encompass multiple types of locks) can be specified by name.
   30  *      When argument 1 is "all", statistics are displayed for all lock groups
   31  *      which have statistics enabled.
   32  *      Lock types include mutexes, reader-writer locks and spin locks.
   33  *      Note that support for gathering contention statistics may not be present
   34  *      for all types of locks on all platforms.
   35  *
   36  *      Argument 2 specifies a periodic interval. The program will display an
   37  *      updated list of statistics every <repeat interval> seconds. This
   38  *      argument is optional. The updates display the deltas from the previous
   39  *      set of statistics, unless "abs" is specified as argument 3.
   40  *
   41  *      Argument 3, if "abs", causes the periodically refreshed lock statistics
   42  *      to be displayed as absolute values rather than deltas from the previous
   43  *      display.
   44  *
   45  *      Types of statistics:
   46  *      Acquisitions: These can include both normal acquisitions, as well
   47  *      as acquisition attempts. These are listed in the first column.
   48  *      Examples include calls to lck_mtx_lock and lck_mtx_try_lock
   49  *      Misses: Incremented if  a lock acquisition attempt failed, due to
   50  *      contention.
   51  *      Waits (Meaningful only for lock types that can block): Incremented
   52  *      if a lock acquisition attempt proceeded to block.
   53  *
   54  *      Direct Waits (currently implemented only on i386): For adaptive
   55  *      locks, such as mutexes, incremented if the owner of the mutex
   56  *      wasn't active on another processor at the time of the lock
   57  *      attempt. This indicates that no adaptive spin occurred.
   58  */
   59 
   60 /*
   61  * HISTORY
   62  * 2005: Bernard Semeria
   63  *              Created.
   64  * 2006: Derek Kumar
   65  *              Display i386 specific stats, fix incremental display, add
   66  *              explanatory block comment.
   67  */
   68 void usage(void);
   69 void print_spin_hdr(void);
   70 void print_spin(int requested, lockgroup_info_t *lockgroup);
   71 void print_all_spin(lockgroup_info_t *lockgroup);
   72 void print_mutex_hdr(void);
   73 void print_mutex(int requested, lockgroup_info_t *lockgroup);
   74 void print_all_mutex(lockgroup_info_t *lockgroup);
   75 void print_rw_hdr(void);
   76 void print_rw(int requested, lockgroup_info_t *lockgroup);
   77 void print_all_rw(lockgroup_info_t *lockgroup);
   78 void prime_lockgroup_deltas(void);
   79 void get_lockgroup_deltas(void);
   80 
   81 char *pgmname;
   82 mach_port_t host_control;
   83 
   84 lockgroup_info_t        *lockgroup_info, *lockgroup_start, *lockgroup_deltas;
   85 unsigned int            count;
   86 
   87 unsigned int            gDebug = 1;
   88 
   89 int
   90 main(int argc, char **argv)
   91 {
   92         kern_return_t           kr;
   93         int                     arg2;
   94         unsigned int            i;
   95         int                     found;
   96 
   97         setlinebuf(stdout);
   98 
   99         pgmname = argv[0];
  100         gDebug = (NULL != strstr(argv[0], "debug"));
  101 
  102         host_control = mach_host_self();  
  103 
  104         kr = host_lockgroup_info(host_control, &lockgroup_info, &count);
  105 
  106         if (kr != KERN_SUCCESS)
  107         {
  108                 mach_error("host_statistics", kr);
  109                 exit (EXIT_FAILURE);
  110         }
  111         if (gDebug) {
  112                 printf("count = %d\n", count);
  113                 for (i = 0; i < count; i++) {
  114                         printf("%s\n",lockgroup_info[i].lockgroup_name);
  115                 }
  116         }
  117 
  118         switch (argc) {
  119         case 2:
  120                 if (strcmp(argv[1], "all") == 0) {
  121                         print_spin_hdr();
  122                         print_all_spin(lockgroup_info);
  123                         print_mutex_hdr();
  124                         print_all_mutex(lockgroup_info);
  125                         print_rw_hdr();
  126                         print_all_rw(lockgroup_info);
  127                 }
  128                 else if (strcmp(argv[1], "spin") == 0) {
  129                         print_spin_hdr();
  130                         print_all_spin(lockgroup_info);
  131                 }
  132                 else if (strcmp(argv[1], "mutex") == 0) {
  133                         print_mutex_hdr();
  134                         print_all_mutex(lockgroup_info);
  135                 }
  136                 else if (strcmp(argv[1], "rw") == 0) {
  137                         print_rw_hdr();
  138                         print_all_rw(lockgroup_info);
  139                 }
  140                 else {
  141                         found = 0;
  142                         for (i = 0;i < count;i++) {
  143                                 if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
  144                                         found = 1;
  145                                         print_spin_hdr();
  146                                         print_spin(i, lockgroup_info);
  147                                         print_mutex_hdr();
  148                                         print_mutex(i, lockgroup_info);
  149                                         print_rw_hdr();
  150                                         print_rw(i, lockgroup_info);
  151                                         break;
  152                                 }
  153                         }
  154                         if (found == 0) 
  155                         { usage(); }
  156                 }
  157                 break;  
  158         case 3:
  159                 if (sscanf(argv[2], "%d", &arg2) != 1) {
  160                         usage();
  161                 }
  162                 if (arg2 < 0) {
  163                         usage();
  164                 }
  165                 prime_lockgroup_deltas();
  166                 if (strcmp(argv[1], "all") == 0) {
  167 
  168                         while (1) {
  169                                 sleep(arg2);
  170                                 get_lockgroup_deltas();
  171                                 print_spin_hdr();
  172                                 print_all_spin(lockgroup_deltas);
  173                                 print_mutex_hdr();
  174                                 print_all_mutex(lockgroup_deltas);
  175                                 print_rw_hdr();
  176                                 print_all_rw(lockgroup_deltas);
  177                         }
  178                 }
  179                 else if (strcmp(argv[1], "spin") == 0) {
  180 
  181                         while (1) {
  182                                 sleep(arg2);
  183                                 get_lockgroup_deltas();
  184                                 print_spin_hdr();
  185                                 print_all_spin(lockgroup_deltas);
  186                         }
  187                 }
  188                 else if (strcmp(argv[1], "mutex") == 0) {
  189 
  190                         while (1) {
  191                                 sleep(arg2);
  192                                 get_lockgroup_deltas();
  193                                 print_mutex_hdr();
  194                                 print_all_mutex(lockgroup_deltas);
  195                         }
  196                 }
  197                 else if (strcmp(argv[1], "rw") == 0) {
  198 
  199                         while (1) {
  200                                 sleep(arg2);
  201                                 get_lockgroup_deltas();
  202                                 print_rw_hdr();
  203                                 print_all_rw(lockgroup_deltas);
  204                         }
  205                 }
  206                 else {
  207 
  208                         found = 0;
  209                         for (i = 0;i < count;i++) {
  210                                 if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
  211                                         found = 1;
  212                                         while (1) {
  213                                                 sleep(arg2);
  214                                                 get_lockgroup_deltas();
  215                                                 print_spin_hdr();
  216                                                 print_spin(i, lockgroup_deltas);
  217                                                 print_mutex_hdr();
  218                                                 print_mutex(i, lockgroup_deltas);
  219                                                 print_rw_hdr();
  220                                                 print_rw(i, lockgroup_deltas);
  221                                         }
  222                                 }
  223                         }
  224                         if (found == 0)
  225                         { usage(); }
  226                 }
  227                 break;
  228         case 4:
  229                 if (strcmp(argv[3], "abs") != 0)
  230                 { usage(); }
  231                 if (sscanf(argv[2], "%d", &arg2) != 1)
  232                 { usage(); }
  233                 if (strcmp(argv[1], "all") == 0) {
  234                         while (1)
  235                         {
  236                                 print_spin_hdr();
  237                                 print_all_spin(lockgroup_info);
  238                                 print_mutex_hdr();
  239                                 print_all_mutex(lockgroup_info);
  240                                 print_rw_hdr();
  241                                 print_all_rw(lockgroup_info);
  242                                 sleep(arg2);
  243                         }
  244                 }
  245                 else if (strcmp(argv[1], "spin") == 0) {
  246                         while (1)
  247                         {print_all_spin(lockgroup_info);
  248                                 sleep(arg2);
  249                         }
  250                 }
  251                 else if (strcmp(argv[1], "mutex") == 0) {
  252                         print_mutex_hdr();
  253                         while (1)
  254                         {print_all_mutex(lockgroup_info);
  255                                 sleep(arg2);
  256                         }
  257                 }
  258                 else if (strcmp(argv[1], "rw") == 0) {
  259                         print_rw_hdr();
  260                         while (1)
  261                         {print_all_rw(lockgroup_info);
  262                                 sleep(arg2);
  263                         }
  264                 }
  265                 else {
  266                         found = 0;
  267                         for (i = 0;i < count;i++) {
  268                                 if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
  269                                         found = 1;
  270                                         while (1)
  271                                         {
  272                                                 print_spin_hdr();
  273                                                 print_spin(i, lockgroup_info);
  274                                                 print_mutex_hdr();
  275                                                 print_mutex(i, lockgroup_info);
  276                                                 print_rw_hdr();
  277                                                 print_rw(i, lockgroup_info);
  278                                                 sleep(arg2);
  279                                         }
  280                                 }
  281                         }
  282                         if (found == 0)
  283                         { usage(); }
  284                 }
  285                 break;
  286         default:
  287                 usage();
  288                 break;
  289         }       
  290 
  291         exit(0);
  292 }
  293  
  294 void 
  295 usage()
  296 {
  297         fprintf(stderr, "Usage: %s [all, spin, mutex, rw, <lock group name>] {<repeat interval>} {abs}\n", pgmname);
  298         exit(EXIT_FAILURE);
  299 }
  300 
  301 void
  302 print_spin_hdr(void)
  303 {
  304         printf("    Spinlock acquires           misses   Name\n");
  305 }
  306 
  307 void
  308 print_spin(int requested, lockgroup_info_t *lockgroup)
  309 {
  310         lockgroup_info_t        *curptr = &lockgroup[requested];
  311 
  312         if (curptr->lock_spin_cnt != 0 && curptr->lock_spin_util_cnt != 0) {
  313                 printf("%16lld ", curptr->lock_spin_util_cnt);
  314                 printf("%16lld   ", curptr->lock_spin_miss_cnt);
  315                 printf("%-14s\n", curptr->lockgroup_name);
  316         }
  317 }
  318 
  319 void
  320 print_all_spin(lockgroup_info_t *lockgroup)
  321 {
  322         unsigned int            i;
  323 
  324         for (i = 0;i < count;i++)
  325                 print_spin(i, lockgroup);
  326         printf("\n");
  327 }
  328 
  329 void
  330 print_mutex_hdr(void)
  331 {
  332 #if defined(__i386__)
  333         printf("Mutex lock attempts  Misses      Waits Direct Waits Name\n");
  334 #else
  335         printf("     mutex locks           misses            waits   name\n");
  336 #endif
  337 }
  338 
  339 void
  340 print_mutex(int requested, lockgroup_info_t *lockgroup)
  341 {
  342         lockgroup_info_t        *curptr = &lockgroup[requested];
  343 
  344         if (curptr->lock_mtx_cnt != 0 && curptr->lock_mtx_util_cnt != 0) {
  345                 printf("%16lld ", curptr->lock_mtx_util_cnt);
  346 #if defined(__i386__)
  347                 printf("%10lld %10lld %10lld   ", curptr->lock_mtx_miss_cnt,  curptr->lock_mtx_wait_cnt, curptr->lock_mtx_held_cnt);
  348 #else
  349                 printf("%16lld %16lld   ", curptr->lock_mtx_miss_cnt,  curptr->lock_mtx_wait_cnt);
  350 #endif
  351                 printf("%-14s\n", curptr->lockgroup_name);
  352         }
  353 }
  354 
  355 void
  356 print_all_mutex(lockgroup_info_t *lockgroup)
  357 {
  358         unsigned int            i;
  359 
  360         for (i = 0;i < count;i++)
  361                 print_mutex(i, lockgroup);
  362         printf("\n");
  363 
  364 }
  365 
  366 void
  367 print_rw_hdr(void)
  368 {
  369         printf("        RW locks           Misses            Waits   Name\n");
  370 }
  371 
  372 void
  373 print_rw(int requested, lockgroup_info_t *lockgroup)
  374 {
  375         lockgroup_info_t        *curptr = &lockgroup[requested];
  376 
  377         if (curptr->lock_rw_cnt != 0 && curptr->lock_rw_util_cnt != 0) {
  378                 printf("%16lld ", curptr->lock_rw_util_cnt);
  379                 printf("%16lld %16lld   ", curptr->lock_rw_miss_cnt,  curptr->lock_rw_wait_cnt);
  380                 printf("%-14s\n", curptr->lockgroup_name);
  381         }
  382 }
  383 
  384 void
  385 print_all_rw(lockgroup_info_t *lockgroup)
  386 {
  387         unsigned int            i;
  388 
  389         for (i = 0;i < count;i++)
  390                 print_rw(i, lockgroup);
  391         printf("\n");
  392 
  393 }
  394 
  395 void
  396 prime_lockgroup_deltas(void)
  397 {
  398         lockgroup_start = calloc(count, sizeof(lockgroup_info_t));
  399         if (lockgroup_start == NULL) {
  400                 fprintf(stderr, "Can't allocate memory for lockgroup info\n");
  401                 exit (EXIT_FAILURE);
  402         }
  403         memcpy(lockgroup_start, lockgroup_info, count * sizeof(lockgroup_info_t));
  404 
  405         lockgroup_deltas = calloc(count,  sizeof(lockgroup_info_t));
  406         if (lockgroup_deltas == NULL) {
  407                 fprintf(stderr, "Can't allocate memory for lockgroup info\n");
  408                 exit (EXIT_FAILURE);
  409         }
  410 }
  411 
  412 void
  413 get_lockgroup_deltas(void)
  414 {
  415         kern_return_t                   kr;
  416         unsigned int                    i;
  417 
  418         kr = host_lockgroup_info(host_control, &lockgroup_info, &count);
  419 
  420         if (kr != KERN_SUCCESS)
  421         {
  422                 mach_error("host_statistics", kr);
  423                 exit (EXIT_FAILURE);
  424         }
  425 
  426         memcpy(lockgroup_deltas, lockgroup_info, count * sizeof(lockgroup_info_t));
  427         for (i = 0; i < count; i++) {
  428                 lockgroup_deltas[i].lock_spin_util_cnt =
  429                     lockgroup_info[i].lock_spin_util_cnt -
  430                     lockgroup_start[i].lock_spin_util_cnt;
  431                 lockgroup_deltas[i].lock_spin_miss_cnt =
  432                     lockgroup_info[i].lock_spin_miss_cnt -
  433                     lockgroup_start[i].lock_spin_miss_cnt;
  434                 lockgroup_deltas[i].lock_mtx_util_cnt =
  435                     lockgroup_info[i].lock_mtx_util_cnt -
  436                     lockgroup_start[i].lock_mtx_util_cnt;
  437                 lockgroup_deltas[i].lock_mtx_miss_cnt =
  438                     lockgroup_info[i].lock_mtx_miss_cnt -
  439                     lockgroup_start[i].lock_mtx_miss_cnt;
  440                 lockgroup_deltas[i].lock_mtx_wait_cnt =
  441                     lockgroup_info[i].lock_mtx_wait_cnt -
  442                     lockgroup_start[i].lock_mtx_wait_cnt;
  443                 lockgroup_deltas[i].lock_mtx_held_cnt =
  444                     lockgroup_info[i].lock_mtx_held_cnt -
  445                     lockgroup_start[i].lock_mtx_held_cnt;
  446                 lockgroup_deltas[i].lock_rw_util_cnt =
  447                     lockgroup_info[i].lock_rw_util_cnt -
  448                     lockgroup_start[i].lock_rw_util_cnt;
  449                 lockgroup_deltas[i].lock_rw_miss_cnt =
  450                     lockgroup_info[i].lock_rw_miss_cnt -
  451                     lockgroup_start[i].lock_rw_miss_cnt;
  452                 lockgroup_deltas[i].lock_rw_wait_cnt =
  453                     lockgroup_info[i].lock_rw_wait_cnt -
  454                     lockgroup_start[i].lock_rw_wait_cnt;
  455         }
  456         memcpy(lockgroup_start, lockgroup_info, count * sizeof(lockgroup_info_t));
  457 }

Cache object: db82f83f6ea13708e264df8b3be870c1


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.