Loading...
--- xnu/xnu-12377.121.6/tools/lockstat/lockstat.c
+++ /dev/null
@@ -1,442 +0,0 @@
-#include <mach/mach.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <time.h>
-#include <mach/error.h>
-#include <mach/mach_error.h>
-#include <mach/mig_errors.h>
-#include <mach/machine.h>
-#include <mach/processor_info.h>
-#include <assert.h>
-#include <nlist.h>
-#include <fcntl.h>
-#include <string.h>
-#include <mach/mach.h>
-#include <mach/host_info.h>
-
-/*
- * lockstat.c
- *
- * Utility to display kernel lock contention statistics.
- * Usage:
- * lockstat [all, spin, mutex, rw, <lock group name>] {<repeat interval>} {abs}
- *
- * Argument 1 specifies the type of lock to display contention statistics
- * for; alternatively, a lock group (a logically grouped set of locks,
- * which can encompass multiple types of locks) can be specified by name.
- * When argument 1 is "all", statistics are displayed for all lock groups
- * which have statistics enabled.
- * Lock types include mutexes, reader-writer locks and spin locks.
- * Note that support for gathering contention statistics may not be present
- * for all types of locks on all platforms.
- *
- * Argument 2 specifies a periodic interval. The program will display an
- * updated list of statistics every <repeat interval> seconds. This
- * argument is optional. The updates display the deltas from the previous
- * set of statistics, unless "abs" is specified as argument 3.
- *
- * Argument 3, if "abs", causes the periodically refreshed lock statistics
- * to be displayed as absolute values rather than deltas from the previous
- * display.
- *
- * Types of statistics:
- * Acquisitions: These can include both normal acquisitions, as well
- * as acquisition attempts. These are listed in the first column.
- * Examples include calls to lck_mtx_lock and lck_mtx_try_lock
- * Misses: Incremented if a lock acquisition attempt failed, due to
- * contention.
- * Waits (Meaningful only for lock types that can block): Incremented
- * if a lock acquisition attempt proceeded to block.
- *
- * Direct Waits (currently implemented only on i386/x86_64): For adaptive
- * locks, such as mutexes, incremented if the owner of the mutex
- * wasn't active on another processor at the time of the lock
- * attempt. This indicates that no adaptive spin occurred.
- */
-
-/*
- * HISTORY
- * 2005: Bernard Semeria
- * Created.
- * 2006: Derek Kumar
- * Display i386 specific stats, fix incremental display, add
- * explanatory block comment.
- */
-void usage(void);
-void print_spin_hdr(void);
-void print_spin(int requested, lockgroup_info_t *lockgroup);
-void print_all_spin(lockgroup_info_t *lockgroup);
-void print_mutex_hdr(void);
-void print_mutex(int requested, lockgroup_info_t *lockgroup);
-void print_all_mutex(lockgroup_info_t *lockgroup);
-void print_rw_hdr(void);
-void print_rw(int requested, lockgroup_info_t *lockgroup);
-void print_all_rw(lockgroup_info_t *lockgroup);
-void prime_lockgroup_deltas(void);
-void get_lockgroup_deltas(void);
-
-char *pgmname;
-mach_port_t host_control;
-
-lockgroup_info_t *lockgroup_info, *lockgroup_start, *lockgroup_deltas;
-unsigned int count;
-
-unsigned int gDebug = 1;
-
-int
-main(int argc, char **argv)
-{
- kern_return_t kr;
- int arg2;
- unsigned int i;
- int found;
-
- setlinebuf(stdout);
-
- pgmname = argv[0];
- gDebug = (NULL != strstr(argv[0], "debug"));
-
- host_control = mach_host_self();
-
- kr = host_lockgroup_info(host_control, &lockgroup_info, &count);
-
- if (kr != KERN_SUCCESS) {
- mach_error("host_statistics", kr);
- exit(EXIT_FAILURE);
- }
- if (gDebug) {
- printf("count = %d\n", count);
- for (i = 0; i < count; i++) {
- printf("%s\n", lockgroup_info[i].lockgroup_name);
- }
- }
-
- switch (argc) {
- case 2:
- if (strcmp(argv[1], "all") == 0) {
- print_spin_hdr();
- print_all_spin(lockgroup_info);
- print_mutex_hdr();
- print_all_mutex(lockgroup_info);
- print_rw_hdr();
- print_all_rw(lockgroup_info);
- } else if (strcmp(argv[1], "spin") == 0) {
- print_spin_hdr();
- print_all_spin(lockgroup_info);
- } else if (strcmp(argv[1], "mutex") == 0) {
- print_mutex_hdr();
- print_all_mutex(lockgroup_info);
- } else if (strcmp(argv[1], "rw") == 0) {
- print_rw_hdr();
- print_all_rw(lockgroup_info);
- } else {
- found = 0;
- for (i = 0; i < count; i++) {
- if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
- found = 1;
- print_spin_hdr();
- print_spin(i, lockgroup_info);
- print_mutex_hdr();
- print_mutex(i, lockgroup_info);
- print_rw_hdr();
- print_rw(i, lockgroup_info);
- break;
- }
- }
- if (found == 0) {
- usage();
- }
- }
- break;
- case 3:
- if (sscanf(argv[2], "%d", &arg2) != 1) {
- usage();
- }
- if (arg2 < 0) {
- usage();
- }
- prime_lockgroup_deltas();
- if (strcmp(argv[1], "all") == 0) {
- while (1) {
- sleep(arg2);
- get_lockgroup_deltas();
- print_spin_hdr();
- print_all_spin(lockgroup_deltas);
- print_mutex_hdr();
- print_all_mutex(lockgroup_deltas);
- print_rw_hdr();
- print_all_rw(lockgroup_deltas);
- }
- } else if (strcmp(argv[1], "spin") == 0) {
- while (1) {
- sleep(arg2);
- get_lockgroup_deltas();
- print_spin_hdr();
- print_all_spin(lockgroup_deltas);
- }
- } else if (strcmp(argv[1], "mutex") == 0) {
- while (1) {
- sleep(arg2);
- get_lockgroup_deltas();
- print_mutex_hdr();
- print_all_mutex(lockgroup_deltas);
- }
- } else if (strcmp(argv[1], "rw") == 0) {
- while (1) {
- sleep(arg2);
- get_lockgroup_deltas();
- print_rw_hdr();
- print_all_rw(lockgroup_deltas);
- }
- } else {
- found = 0;
- for (i = 0; i < count; i++) {
- if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
- found = 1;
- while (1) {
- sleep(arg2);
- get_lockgroup_deltas();
- print_spin_hdr();
- print_spin(i, lockgroup_deltas);
- print_mutex_hdr();
- print_mutex(i, lockgroup_deltas);
- print_rw_hdr();
- print_rw(i, lockgroup_deltas);
- }
- }
- }
- if (found == 0) {
- usage();
- }
- }
- break;
- case 4:
- if (strcmp(argv[3], "abs") != 0) {
- usage();
- }
- if (sscanf(argv[2], "%d", &arg2) != 1) {
- usage();
- }
- if (strcmp(argv[1], "all") == 0) {
- while (1) {
- print_spin_hdr();
- print_all_spin(lockgroup_info);
- print_mutex_hdr();
- print_all_mutex(lockgroup_info);
- print_rw_hdr();
- print_all_rw(lockgroup_info);
- sleep(arg2);
- }
- } else if (strcmp(argv[1], "spin") == 0) {
- while (1) {
- print_all_spin(lockgroup_info);
- sleep(arg2);
- }
- } else if (strcmp(argv[1], "mutex") == 0) {
- print_mutex_hdr();
- while (1) {
- print_all_mutex(lockgroup_info);
- sleep(arg2);
- }
- } else if (strcmp(argv[1], "rw") == 0) {
- print_rw_hdr();
- while (1) {
- print_all_rw(lockgroup_info);
- sleep(arg2);
- }
- } else {
- found = 0;
- for (i = 0; i < count; i++) {
- if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
- found = 1;
- while (1) {
- print_spin_hdr();
- print_spin(i, lockgroup_info);
- print_mutex_hdr();
- print_mutex(i, lockgroup_info);
- print_rw_hdr();
- print_rw(i, lockgroup_info);
- sleep(arg2);
- }
- }
- }
- if (found == 0) {
- usage();
- }
- }
- break;
- default:
- usage();
- break;
- }
-
- exit(0);
-}
-
-void
-usage()
-{
- fprintf(stderr, "Usage: %s [all, spin, mutex, rw, <lock group name>] {<repeat interval>} {abs}\n", pgmname);
- exit(EXIT_FAILURE);
-}
-
-void
-print_spin_hdr(void)
-{
- printf(" Spinlock acquires misses Name\n");
-}
-
-void
-print_spin(int requested, lockgroup_info_t *lockgroup)
-{
- lockgroup_info_t *curptr = &lockgroup[requested];
-
- if (curptr->lock_spin_cnt != 0 && curptr->lock_spin_util_cnt != 0) {
- printf("%16lld ", curptr->lock_spin_util_cnt);
- printf("%16lld ", curptr->lock_spin_miss_cnt);
- printf("%-14s\n", curptr->lockgroup_name);
- }
-}
-
-void
-print_all_spin(lockgroup_info_t *lockgroup)
-{
- unsigned int i;
-
- for (i = 0; i < count; i++) {
- print_spin(i, lockgroup);
- }
- printf("\n");
-}
-
-void
-print_mutex_hdr(void)
-{
-#if defined(__i386__) || defined(__x86_64__)
- printf("Mutex lock attempts Misses Waits Direct Waits Name\n");
-#else
- printf(" mutex locks misses waits name\n");
-#endif
-}
-
-void
-print_mutex(int requested, lockgroup_info_t *lockgroup)
-{
- lockgroup_info_t *curptr = &lockgroup[requested];
-
- if (curptr->lock_mtx_cnt != 0 && curptr->lock_mtx_util_cnt != 0) {
- printf("%16lld ", curptr->lock_mtx_util_cnt);
-#if defined(__i386__) || defined(__x86_64__)
- printf("%10lld %10lld %10lld ", curptr->lock_mtx_miss_cnt, curptr->lock_mtx_wait_cnt, curptr->lock_mtx_held_cnt);
-#else
- printf("%16lld %16lld ", curptr->lock_mtx_miss_cnt, curptr->lock_mtx_wait_cnt);
-#endif
- printf("%-14s\n", curptr->lockgroup_name);
- }
-}
-
-void
-print_all_mutex(lockgroup_info_t *lockgroup)
-{
- unsigned int i;
-
- for (i = 0; i < count; i++) {
- print_mutex(i, lockgroup);
- }
- printf("\n");
-}
-
-void
-print_rw_hdr(void)
-{
- printf(" RW locks Misses Waits Name\n");
-}
-
-void
-print_rw(int requested, lockgroup_info_t *lockgroup)
-{
- lockgroup_info_t *curptr = &lockgroup[requested];
-
- if (curptr->lock_rw_cnt != 0 && curptr->lock_rw_util_cnt != 0) {
- printf("%16lld ", curptr->lock_rw_util_cnt);
- printf("%16lld %16lld ", curptr->lock_rw_miss_cnt, curptr->lock_rw_wait_cnt);
- printf("%-14s\n", curptr->lockgroup_name);
- }
-}
-
-void
-print_all_rw(lockgroup_info_t *lockgroup)
-{
- unsigned int i;
-
- for (i = 0; i < count; i++) {
- print_rw(i, lockgroup);
- }
- printf("\n");
-}
-
-void
-prime_lockgroup_deltas(void)
-{
- lockgroup_start = calloc(count, sizeof(lockgroup_info_t));
- if (lockgroup_start == NULL) {
- fprintf(stderr, "Can't allocate memory for lockgroup info\n");
- exit(EXIT_FAILURE);
- }
- memcpy(lockgroup_start, lockgroup_info, count * sizeof(lockgroup_info_t));
-
- lockgroup_deltas = calloc(count, sizeof(lockgroup_info_t));
- if (lockgroup_deltas == NULL) {
- fprintf(stderr, "Can't allocate memory for lockgroup info\n");
- exit(EXIT_FAILURE);
- }
-}
-
-void
-get_lockgroup_deltas(void)
-{
- kern_return_t kr;
- unsigned int i;
-
- kr = host_lockgroup_info(host_control, &lockgroup_info, &count);
-
- if (kr != KERN_SUCCESS) {
- mach_error("host_statistics", kr);
- exit(EXIT_FAILURE);
- }
-
- memcpy(lockgroup_deltas, lockgroup_info, count * sizeof(lockgroup_info_t));
- for (i = 0; i < count; i++) {
- lockgroup_deltas[i].lock_spin_util_cnt =
- lockgroup_info[i].lock_spin_util_cnt -
- lockgroup_start[i].lock_spin_util_cnt;
- lockgroup_deltas[i].lock_spin_miss_cnt =
- lockgroup_info[i].lock_spin_miss_cnt -
- lockgroup_start[i].lock_spin_miss_cnt;
- lockgroup_deltas[i].lock_mtx_util_cnt =
- lockgroup_info[i].lock_mtx_util_cnt -
- lockgroup_start[i].lock_mtx_util_cnt;
- lockgroup_deltas[i].lock_mtx_miss_cnt =
- lockgroup_info[i].lock_mtx_miss_cnt -
- lockgroup_start[i].lock_mtx_miss_cnt;
- lockgroup_deltas[i].lock_mtx_wait_cnt =
- lockgroup_info[i].lock_mtx_wait_cnt -
- lockgroup_start[i].lock_mtx_wait_cnt;
- lockgroup_deltas[i].lock_mtx_held_cnt =
- lockgroup_info[i].lock_mtx_held_cnt -
- lockgroup_start[i].lock_mtx_held_cnt;
- lockgroup_deltas[i].lock_rw_util_cnt =
- lockgroup_info[i].lock_rw_util_cnt -
- lockgroup_start[i].lock_rw_util_cnt;
- lockgroup_deltas[i].lock_rw_miss_cnt =
- lockgroup_info[i].lock_rw_miss_cnt -
- lockgroup_start[i].lock_rw_miss_cnt;
- lockgroup_deltas[i].lock_rw_wait_cnt =
- lockgroup_info[i].lock_rw_wait_cnt -
- lockgroup_start[i].lock_rw_wait_cnt;
- }
- memcpy(lockgroup_start, lockgroup_info, count * sizeof(lockgroup_info_t));
-}