1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <stdio.h> 30*0Sstevel@tonic-gate #include <stdlib.h> 31*0Sstevel@tonic-gate #include <string.h> 32*0Sstevel@tonic-gate #include <fcntl.h> 33*0Sstevel@tonic-gate #include <errno.h> 34*0Sstevel@tonic-gate #include <unistd.h> 35*0Sstevel@tonic-gate #include <signal.h> 36*0Sstevel@tonic-gate #include <strings.h> 37*0Sstevel@tonic-gate #include <limits.h> 38*0Sstevel@tonic-gate #include <sys/mman.h> 39*0Sstevel@tonic-gate #include <sys/pset.h> 40*0Sstevel@tonic-gate #include <sys/varargs.h> 41*0Sstevel@tonic-gate #include <sys/trapstat.h> 42*0Sstevel@tonic-gate #include <sys/wait.h> 43*0Sstevel@tonic-gate #include <stddef.h> 44*0Sstevel@tonic-gate #include <termio.h> 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate #define TSTAT_DEVICE "/dev/trapstat" 47*0Sstevel@tonic-gate #define TSTAT_COMMAND "trapstat" 48*0Sstevel@tonic-gate #define TSTAT_DELTA(data, old, member) g_absolute ? (data)->member : \ 49*0Sstevel@tonic-gate (uint64_t)(0.5 + (g_interval / (double)((data)->tdata_snapts - \ 50*0Sstevel@tonic-gate (old)->tdata_snapts)) * (double)((data)->member - (old)->member)) 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate #define TSTAT_PRINT_MISSDATA(diff, time) \ 53*0Sstevel@tonic-gate (void) printf(" %9lld %4.1f", (diff), (time)); 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate #define TSTAT_PAGESIZE_MODIFIERS " kmgtp" 56*0Sstevel@tonic-gate #define TSTAT_PAGESIZE_STRLEN 10 57*0Sstevel@tonic-gate #define TSTAT_MAX_RATE 5000 58*0Sstevel@tonic-gate #define TSTAT_COLUMN_OFFS 26 59*0Sstevel@tonic-gate #define TSTAT_COLUMNS_PER_CPU 9 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate static tstat_data_t *g_data[2]; 62*0Sstevel@tonic-gate static tstat_data_t *g_ndata, *g_odata; 63*0Sstevel@tonic-gate static processorid_t g_max_cpus; 64*0Sstevel@tonic-gate static int8_t *g_selected; 65*0Sstevel@tonic-gate static timer_t g_tid; 66*0Sstevel@tonic-gate static int g_interval = NANOSEC; 67*0Sstevel@tonic-gate static int g_peffect = 1; 68*0Sstevel@tonic-gate static int g_absolute = 0; 69*0Sstevel@tonic-gate static sigset_t g_oset; 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate static psetid_t g_pset = PS_NONE; 72*0Sstevel@tonic-gate static processorid_t *g_pset_cpus; 73*0Sstevel@tonic-gate static uint_t g_pset_ncpus; 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate static int g_cpus_per_line = (80 - TSTAT_COLUMN_OFFS) / TSTAT_COLUMNS_PER_CPU; 76*0Sstevel@tonic-gate static int g_winch; 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate static int g_pgsizes; 79*0Sstevel@tonic-gate static size_t *g_pgsize; 80*0Sstevel@tonic-gate static char **g_pgnames; 81*0Sstevel@tonic-gate static size_t g_datasize; 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate static int g_gen; 84*0Sstevel@tonic-gate static int g_fd; 85*0Sstevel@tonic-gate static uint8_t g_active[TSTAT_NENT]; 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate static hrtime_t g_start; 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate static int g_exec_errno; 90*0Sstevel@tonic-gate static int g_child_exited; 91*0Sstevel@tonic-gate static int g_child_status; 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate static void (*g_process)(void *, uint64_t, double); 94*0Sstevel@tonic-gate static void *g_arg; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate typedef struct tstat_sum { 97*0Sstevel@tonic-gate uint64_t tsum_diff; 98*0Sstevel@tonic-gate double tsum_time; 99*0Sstevel@tonic-gate } tstat_sum_t; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate #define TSTAT_ENT_USED 0 102*0Sstevel@tonic-gate #define TSTAT_ENT_RESERVED 1 103*0Sstevel@tonic-gate #define TSTAT_ENT_UNUSED 2 104*0Sstevel@tonic-gate #define TSTAT_ENT_CONTINUED 3 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate typedef struct tstat_ent { 107*0Sstevel@tonic-gate char *tent_name; 108*0Sstevel@tonic-gate char *tent_descr; 109*0Sstevel@tonic-gate int tent_type; 110*0Sstevel@tonic-gate } tstat_ent_t; 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate static tstat_ent_t g_traps[] = { 113*0Sstevel@tonic-gate #ifndef sun4v 114*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 115*0Sstevel@tonic-gate { "power-on", "power on reset" }, 116*0Sstevel@tonic-gate { "watchdog", "watchdog reset" }, 117*0Sstevel@tonic-gate { "xir", "externally initiated reset" }, 118*0Sstevel@tonic-gate { "sir", "software initiated reset" }, 119*0Sstevel@tonic-gate { "red", "RED state exception" }, 120*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 121*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 122*0Sstevel@tonic-gate { "immu-xcp", "instruction access exception" }, 123*0Sstevel@tonic-gate { "immu-miss", "instruction access MMU miss" }, 124*0Sstevel@tonic-gate { "immu-err", "instruction access error" }, 125*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 126*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 127*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 128*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 129*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 130*0Sstevel@tonic-gate { "ill-inst", "illegal instruction" }, 131*0Sstevel@tonic-gate { "priv-inst", "privileged opcode" }, 132*0Sstevel@tonic-gate { "unimp-ldd", "unimplemented LDD" }, 133*0Sstevel@tonic-gate { "unimp-std", "unimplemented STD" }, 134*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 135*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 136*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 137*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 138*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 139*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 140*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 141*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 142*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 143*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 144*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 145*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 146*0Sstevel@tonic-gate { "fp-disabled", "fp disabled" }, 147*0Sstevel@tonic-gate { "fp-ieee754", "fp exception ieee754" }, 148*0Sstevel@tonic-gate { "fp-xcp-other", "fp exception other" }, 149*0Sstevel@tonic-gate { "tag-oflow", "tag overflow" }, 150*0Sstevel@tonic-gate { "cleanwin", "clean window" }, 151*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 152*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 153*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 154*0Sstevel@tonic-gate { "div-zero", "division by zero" }, 155*0Sstevel@tonic-gate { "internal-err", "internal processor error" }, 156*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 157*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 158*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 159*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 160*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 161*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 162*0Sstevel@tonic-gate { "dmmu-xcp", "data access exception" }, 163*0Sstevel@tonic-gate { "dmmu-miss", "data access MMU miss" }, 164*0Sstevel@tonic-gate { "dmmu-err", "data access error" }, 165*0Sstevel@tonic-gate { "dmmu-prot", "data access protection" }, 166*0Sstevel@tonic-gate { "unalign", "mem address not aligned" }, 167*0Sstevel@tonic-gate { "lddf-unalign", "LDDF mem address not aligned" }, 168*0Sstevel@tonic-gate { "stdf-unalign", "STDF mem address not aligned" }, 169*0Sstevel@tonic-gate { "priv-act", "privileged action" }, 170*0Sstevel@tonic-gate { "ldqf-unalign", "LDQF mem address not aligned" }, 171*0Sstevel@tonic-gate { "stqf-unalign", "STQF mem address not aligned" }, 172*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 173*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 174*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 175*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 176*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 177*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 178*0Sstevel@tonic-gate { "async-d-err", "async data error" }, 179*0Sstevel@tonic-gate { "level-1", "interrupt level 1" }, 180*0Sstevel@tonic-gate { "level-2", "interrupt level 2" }, 181*0Sstevel@tonic-gate { "level-3", "interrupt level 3" }, 182*0Sstevel@tonic-gate { "level-4", "interrupt level 4" }, 183*0Sstevel@tonic-gate { "level-5", "interrupt level 5" }, 184*0Sstevel@tonic-gate { "level-6", "interrupt level 6" }, 185*0Sstevel@tonic-gate { "level-7", "interrupt level 7" }, 186*0Sstevel@tonic-gate { "level-8", "interrupt level 8" }, 187*0Sstevel@tonic-gate { "level-9", "interrupt level 9" }, 188*0Sstevel@tonic-gate { "level-10", "interrupt level 10" }, 189*0Sstevel@tonic-gate { "level-11", "interrupt level 11" }, 190*0Sstevel@tonic-gate { "level-12", "interrupt level 12" }, 191*0Sstevel@tonic-gate { "level-13", "interrupt level 13" }, 192*0Sstevel@tonic-gate { "level-14", "interrupt level 14" }, 193*0Sstevel@tonic-gate { "level-15", "interrupt level 15" }, 194*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 195*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 196*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 197*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 198*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 199*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 200*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 201*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 202*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 203*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 204*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 205*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 206*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 207*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 208*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 209*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 210*0Sstevel@tonic-gate { "int-vec", "interrupt vector" }, 211*0Sstevel@tonic-gate { "pa-watch", "PA watchpoint" }, 212*0Sstevel@tonic-gate { "va-watch", "VA watchpoint" }, 213*0Sstevel@tonic-gate { "ecc-err", "corrected ECC error" }, 214*0Sstevel@tonic-gate { "itlb-miss", "instruction access MMU miss" }, 215*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 216*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 217*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 218*0Sstevel@tonic-gate { "dtlb-miss", "data access MMU miss" }, 219*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 220*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 221*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 222*0Sstevel@tonic-gate { "dtlb-prot", "data access protection" }, 223*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 224*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 225*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 226*0Sstevel@tonic-gate { "fast-ecc", "fast ECC error" }, 227*0Sstevel@tonic-gate { "dcache-parity", "D-cache parity error" }, 228*0Sstevel@tonic-gate { "icache-parity", "I-cache parity error" }, 229*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 230*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 231*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 232*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 233*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 234*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 235*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 236*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 237*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 238*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 239*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 240*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 241*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 242*0Sstevel@tonic-gate #else /* sun4v */ 243*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 244*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 245*0Sstevel@tonic-gate { "watchdog", "watchdog reset" }, 246*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 247*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 248*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 249*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 250*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 251*0Sstevel@tonic-gate { "immu-xcp", "instruction access exception" }, 252*0Sstevel@tonic-gate { "immu-miss", "instruction access MMU miss" }, 253*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 254*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 255*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 256*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 257*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 258*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 259*0Sstevel@tonic-gate { "ill-inst", "illegal instruction" }, 260*0Sstevel@tonic-gate { "priv-inst", "privileged opcode" }, 261*0Sstevel@tonic-gate { "unimp-ldd", "unimplemented LDD" }, 262*0Sstevel@tonic-gate { "unimp-std", "unimplemented STD" }, 263*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 264*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 265*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 266*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 267*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 268*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 269*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 270*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 271*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 272*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 273*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 274*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 275*0Sstevel@tonic-gate { "fp-disabled", "fp disabled" }, 276*0Sstevel@tonic-gate { "fp-ieee754", "fp exception ieee754" }, 277*0Sstevel@tonic-gate { "fp-xcp-other", "fp exception other" }, 278*0Sstevel@tonic-gate { "tag-oflow", "tag overflow" }, 279*0Sstevel@tonic-gate { "cleanwin", "clean window" }, 280*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 281*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 282*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 283*0Sstevel@tonic-gate { "div-zero", "division by zero" }, 284*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 285*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 286*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 287*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 288*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 289*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 290*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 291*0Sstevel@tonic-gate { "dmmu-xcp", "data access exception" }, 292*0Sstevel@tonic-gate { "dmmu-miss", "data access MMU miss" }, 293*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 294*0Sstevel@tonic-gate { "dmmu-prot", "data access protection" }, 295*0Sstevel@tonic-gate { "unalign", "mem address not aligned" }, 296*0Sstevel@tonic-gate { "lddf-unalign", "LDDF mem address not aligned" }, 297*0Sstevel@tonic-gate { "stdf-unalign", "STDF mem address not aligned" }, 298*0Sstevel@tonic-gate { "priv-act", "privileged action" }, 299*0Sstevel@tonic-gate { "ldqf-unalign", "LDQF mem address not aligned" }, 300*0Sstevel@tonic-gate { "stqf-unalign", "STQF mem address not aligned" }, 301*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 302*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 303*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 304*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 305*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 306*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 307*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 308*0Sstevel@tonic-gate { "level-1", "interrupt level 1" }, 309*0Sstevel@tonic-gate { "level-2", "interrupt level 2" }, 310*0Sstevel@tonic-gate { "level-3", "interrupt level 3" }, 311*0Sstevel@tonic-gate { "level-4", "interrupt level 4" }, 312*0Sstevel@tonic-gate { "level-5", "interrupt level 5" }, 313*0Sstevel@tonic-gate { "level-6", "interrupt level 6" }, 314*0Sstevel@tonic-gate { "level-7", "interrupt level 7" }, 315*0Sstevel@tonic-gate { "level-8", "interrupt level 8" }, 316*0Sstevel@tonic-gate { "level-9", "interrupt level 9" }, 317*0Sstevel@tonic-gate { "level-10", "interrupt level 10" }, 318*0Sstevel@tonic-gate { "level-11", "interrupt level 11" }, 319*0Sstevel@tonic-gate { "level-12", "interrupt level 12" }, 320*0Sstevel@tonic-gate { "level-13", "interrupt level 13" }, 321*0Sstevel@tonic-gate { "level-14", "interrupt level 14" }, 322*0Sstevel@tonic-gate { "level-15", "interrupt level 15" }, 323*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 324*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 325*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 326*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 327*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 328*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 329*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 330*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 331*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 332*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 333*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 334*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 335*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 336*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 337*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 338*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 339*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 340*0Sstevel@tonic-gate { "pa-watch", "PA watchpoint" }, 341*0Sstevel@tonic-gate { "va-watch", "VA watchpoint" }, 342*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 343*0Sstevel@tonic-gate { "itlb-miss", "instruction access MMU miss" }, 344*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 345*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 346*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 347*0Sstevel@tonic-gate { "dtlb-miss", "data access MMU miss" }, 348*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 349*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 350*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 351*0Sstevel@tonic-gate { "dtlb-prot", "data access protection" }, 352*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 353*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 354*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 355*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 356*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 357*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 358*0Sstevel@tonic-gate { "ctl-xfer", "control transfer" }, 359*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 360*0Sstevel@tonic-gate { "instr-brkpt", "instruction breakpoint" }, 361*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 362*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 363*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 364*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 365*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 366*0Sstevel@tonic-gate { "hw-changed", "hardware changed" }, 367*0Sstevel@tonic-gate { "cpu_mondo", "cpu mondo trap" }, 368*0Sstevel@tonic-gate { "dev_mondo", "device mondo trap" }, 369*0Sstevel@tonic-gate { "res-err", "resumable error" }, 370*0Sstevel@tonic-gate { "nonres-err", "non-resumable error" }, 371*0Sstevel@tonic-gate #endif /* sun4v */ 372*0Sstevel@tonic-gate { "spill-0-normal", "spill 0 normal" }, 373*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 374*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 375*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 376*0Sstevel@tonic-gate { "spill-user-32", "spill user window, 32-bit" }, 377*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 378*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 379*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 380*0Sstevel@tonic-gate { "spill-user-64", "spill user window, 64-bit" }, 381*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 382*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 383*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 384*0Sstevel@tonic-gate { "spill-user-32-cln", "spill, clean user window, 32-bit" }, 385*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 386*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 387*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 388*0Sstevel@tonic-gate { "spill-user-64-cln", "spill, clean user window, 64-bit" }, 389*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 390*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 391*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 392*0Sstevel@tonic-gate { "spill-kern-32", "spill kernel window, 32-bit" }, 393*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 394*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 395*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 396*0Sstevel@tonic-gate { "spill-kern-64", "spill kernel window, 64-bit" }, 397*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 398*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 399*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 400*0Sstevel@tonic-gate { "spill-mixed", "spill window, mixed 32-bit/64-bit" }, 401*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 402*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 403*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 404*0Sstevel@tonic-gate { "spill-0-other", "spill 0 other" }, 405*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 406*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 407*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 408*0Sstevel@tonic-gate { "spill-asuser-32", "spill user window as kernel, 32-bit" }, 409*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 410*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 411*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 412*0Sstevel@tonic-gate { "spill-asuser-64", "spill user window as kernel, 64-bit" }, 413*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 414*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 415*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 416*0Sstevel@tonic-gate { "spill-asuser-32-cln", "spill, clean user window as kernel, 32-bit" }, 417*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 418*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 419*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 420*0Sstevel@tonic-gate { "spill-asuser-64-cln", "spill, clean user window as kernel, 64-bit" }, 421*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 422*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 423*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 424*0Sstevel@tonic-gate { "spill-5-other", "spill 5 other" }, 425*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 426*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 427*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 428*0Sstevel@tonic-gate { "spill-6-other", "spill 6 other" }, 429*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 430*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 431*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 432*0Sstevel@tonic-gate { "spill-7-other", "spill 7 other" }, 433*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 434*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 435*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 436*0Sstevel@tonic-gate { "fill-0-normal", "fill 0 normal" }, 437*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 438*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 439*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 440*0Sstevel@tonic-gate { "fill-user-32", "fill user window, 32-bit" }, 441*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 442*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 443*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 444*0Sstevel@tonic-gate { "fill-user-64", "fill user window, 64-bit" }, 445*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 446*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 447*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 448*0Sstevel@tonic-gate { "fill-user-32-cln", "fill user window, 32-bit" }, 449*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 450*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 451*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 452*0Sstevel@tonic-gate { "fill-user-64-cln", "fill user window, 64-bit" }, 453*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 454*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 455*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 456*0Sstevel@tonic-gate { "fill-kern-32", "fill kernel window, 32-bit" }, 457*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 458*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 459*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 460*0Sstevel@tonic-gate { "fill-kern-64", "fill kernel window, 64-bit" }, 461*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 462*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 463*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 464*0Sstevel@tonic-gate { "fill-mixed", "fill window, mixed 32-bit/64-bit" }, 465*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 466*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 467*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 468*0Sstevel@tonic-gate { "fill-0-other", "fill 0 other" }, 469*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 470*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 471*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 472*0Sstevel@tonic-gate { "fill-asuser-32", "fill user window as kernel, 32-bit" }, 473*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 474*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 475*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 476*0Sstevel@tonic-gate { "fill-asuser-64", "fill user window as kernel, 64-bit" }, 477*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 478*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 479*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 480*0Sstevel@tonic-gate { "fill-asuser-32-cln", "fill user window as kernel, 32-bit" }, 481*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 482*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 483*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 484*0Sstevel@tonic-gate { "fill-asuser-64-cln", "fill user window as kernel, 64-bit" }, 485*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 486*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 487*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 488*0Sstevel@tonic-gate { "fill-5-other", "fill 5 other" }, 489*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 490*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 491*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 492*0Sstevel@tonic-gate { "fill-6-other", "fill 6 other" }, 493*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 494*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 495*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 496*0Sstevel@tonic-gate { "fill-7-other", "fill 7 other" }, 497*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 498*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 499*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_CONTINUED }, 500*0Sstevel@tonic-gate { "syscall-4x", "old system call" }, 501*0Sstevel@tonic-gate { "usr-brkpt", "user breakpoint" }, 502*0Sstevel@tonic-gate { "usr-div-zero", "user divide by zero" }, 503*0Sstevel@tonic-gate { "flush-wins", "flush windows" }, 504*0Sstevel@tonic-gate { "clean-wins", "clean windows" }, 505*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 506*0Sstevel@tonic-gate { "fix-align", "fix unaligned references" }, 507*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 508*0Sstevel@tonic-gate { "syscall-32", "ILP32 system call" }, 509*0Sstevel@tonic-gate { "set-t0-addr", "set trap0 address" }, 510*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 511*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 512*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 513*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 514*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 515*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 516*0Sstevel@tonic-gate { "trap-inst-16", "trap instruction 16", }, 517*0Sstevel@tonic-gate { "trap-inst-17", "trap instruction 17", }, 518*0Sstevel@tonic-gate { "trap-inst-18", "trap instruction 18", }, 519*0Sstevel@tonic-gate { "trap-inst-19", "trap instruction 19", }, 520*0Sstevel@tonic-gate { "trap-inst-20", "trap instruction 20", }, 521*0Sstevel@tonic-gate { "trap-inst-21", "trap instruction 21", }, 522*0Sstevel@tonic-gate { "trap-inst-22", "trap instruction 22", }, 523*0Sstevel@tonic-gate { "trap-inst-23", "trap instruction 23", }, 524*0Sstevel@tonic-gate { "trap-inst-24", "trap instruction 24", }, 525*0Sstevel@tonic-gate { "trap-inst-25", "trap instruction 25", }, 526*0Sstevel@tonic-gate { "trap-inst-26", "trap instruction 26", }, 527*0Sstevel@tonic-gate { "trap-inst-27", "trap instruction 27", }, 528*0Sstevel@tonic-gate { "trap-inst-28", "trap instruction 28", }, 529*0Sstevel@tonic-gate { "trap-inst-29", "trap instruction 29", }, 530*0Sstevel@tonic-gate { "trap-inst-30", "trap instruction 30", }, 531*0Sstevel@tonic-gate { "trap-inst-31", "trap instruction 31", }, 532*0Sstevel@tonic-gate { "get-cc", "get condition codes" }, 533*0Sstevel@tonic-gate { "set-cc", "set condition codes" }, 534*0Sstevel@tonic-gate { "get-psr", "get psr" }, 535*0Sstevel@tonic-gate { "set-psr", "set psr (some fields)" }, 536*0Sstevel@tonic-gate { "getts", "get timestamp" }, 537*0Sstevel@tonic-gate { "gethrvtime", "get lwp virtual time" }, 538*0Sstevel@tonic-gate { "self-xcall", "self xcall" }, 539*0Sstevel@tonic-gate { "gethrtime", "get hrestime" }, 540*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 541*0Sstevel@tonic-gate { "getlgrp", "get lgrpid" }, 542*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 543*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 544*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 545*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 546*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 547*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 548*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 549*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 550*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 551*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 552*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 553*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 554*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 555*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 556*0Sstevel@tonic-gate { "dtrace-pid", "DTrace pid provider" }, 557*0Sstevel@tonic-gate { "dtrace-fasttrap", "DTrace fasttrap provider" }, 558*0Sstevel@tonic-gate { "dtrace-return", "DTrace pid provider return" }, 559*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 560*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 561*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 562*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 563*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 564*0Sstevel@tonic-gate { "syscall-64", "LP64 system call" }, 565*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 566*0Sstevel@tonic-gate { "tt-freeze", "freeze traptrace" }, 567*0Sstevel@tonic-gate { "tt-unfreeze", "unfreeze traptrace" }, 568*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 569*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 570*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 571*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 572*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 573*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 574*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 575*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 576*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 577*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 578*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 579*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 580*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 581*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 582*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 583*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 584*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 585*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 586*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 587*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 588*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 589*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 590*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 591*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 592*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 593*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 594*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 595*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 596*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 597*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 598*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 599*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 600*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 601*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 602*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 603*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 604*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 605*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 606*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 607*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 608*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 609*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 610*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 611*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 612*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 613*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 614*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 615*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 616*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 617*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 618*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 619*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 620*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 621*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 622*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 623*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_UNUSED }, 624*0Sstevel@tonic-gate { "ptl1-panic", "test ptl1-panic" }, 625*0Sstevel@tonic-gate { "kmdb-enter", "kmdb enter (L1-A)" }, 626*0Sstevel@tonic-gate { "kmdb-brkpt", "kmdb breakpoint" }, 627*0Sstevel@tonic-gate { "obp-brkpt", "obp breakpoint" }, 628*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 629*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 630*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 631*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 632*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 633*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 634*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 635*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 636*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 637*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 638*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 639*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 640*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 641*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 642*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 643*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 644*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 645*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 646*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 647*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 648*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 649*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 650*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 651*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 652*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 653*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 654*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 655*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 656*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 657*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 658*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 659*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 660*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 661*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 662*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 663*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 664*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 665*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 666*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 667*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 668*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 669*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 670*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 671*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 672*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 673*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 674*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 675*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 676*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 677*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 678*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 679*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 680*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 681*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 682*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 683*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 684*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 685*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 686*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 687*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 688*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 689*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 690*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 691*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 692*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 693*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 694*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 695*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 696*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 697*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 698*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 699*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 700*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 701*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 702*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 703*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 704*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 705*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 706*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 707*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 708*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 709*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 710*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 711*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 712*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 713*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 714*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 715*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 716*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 717*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 718*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 719*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 720*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 721*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 722*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 723*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 724*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 725*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 726*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 727*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 728*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 729*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 730*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 731*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 732*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 733*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 734*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 735*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 736*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 737*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 738*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 739*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 740*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 741*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 742*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 743*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 744*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 745*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 746*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 747*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 748*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 749*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 750*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 751*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 752*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 753*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 754*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED }, 755*0Sstevel@tonic-gate { NULL, NULL, TSTAT_ENT_RESERVED } 756*0Sstevel@tonic-gate }; 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate static void 759*0Sstevel@tonic-gate usage(void) 760*0Sstevel@tonic-gate { 761*0Sstevel@tonic-gate (void) fprintf(stderr, 762*0Sstevel@tonic-gate "\nusage: trapstat [ -t | -T | -e entrylist ]\n" 763*0Sstevel@tonic-gate " [ -C psrset | -c cpulist ]\n" 764*0Sstevel@tonic-gate " [ -P ] [ -a ] [ -r rate ] [[ interval [ count ] ] | " 765*0Sstevel@tonic-gate "command [ args ] ]\n\n" 766*0Sstevel@tonic-gate "Trap selection options:\n\n" 767*0Sstevel@tonic-gate " -t TLB statistics\n" 768*0Sstevel@tonic-gate " -T TLB statistics, with pagesize information\n" 769*0Sstevel@tonic-gate " -e entrylist Enable statistics only for entries specified " 770*0Sstevel@tonic-gate "by entrylist\n\n" 771*0Sstevel@tonic-gate "CPU selection options:\n\n" 772*0Sstevel@tonic-gate " -c cpulist Enable statistics only for specified CPU list\n" 773*0Sstevel@tonic-gate " -C psrset Enable statistics only for specified processor " 774*0Sstevel@tonic-gate "set\n\n" 775*0Sstevel@tonic-gate "Other options:\n\n" 776*0Sstevel@tonic-gate " -a Display trap values as accumulating values " 777*0Sstevel@tonic-gate "instead of rates\n" 778*0Sstevel@tonic-gate " -l List trap table entries and exit\n" 779*0Sstevel@tonic-gate " -P Display output in parsable format\n" 780*0Sstevel@tonic-gate " -r hz Set sampling rate to be hz samples " 781*0Sstevel@tonic-gate "per second\n\n"); 782*0Sstevel@tonic-gate 783*0Sstevel@tonic-gate exit(EXIT_FAILURE); 784*0Sstevel@tonic-gate } 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate static void 787*0Sstevel@tonic-gate fatal(char *fmt, ...) 788*0Sstevel@tonic-gate { 789*0Sstevel@tonic-gate va_list ap; 790*0Sstevel@tonic-gate int error = errno; 791*0Sstevel@tonic-gate 792*0Sstevel@tonic-gate va_start(ap, fmt); 793*0Sstevel@tonic-gate 794*0Sstevel@tonic-gate (void) fprintf(stderr, TSTAT_COMMAND ": "); 795*0Sstevel@tonic-gate (void) vfprintf(stderr, fmt, ap); 796*0Sstevel@tonic-gate 797*0Sstevel@tonic-gate if (fmt[strlen(fmt) - 1] != '\n') 798*0Sstevel@tonic-gate (void) fprintf(stderr, ": %s\n", strerror(error)); 799*0Sstevel@tonic-gate 800*0Sstevel@tonic-gate exit(EXIT_FAILURE); 801*0Sstevel@tonic-gate } 802*0Sstevel@tonic-gate 803*0Sstevel@tonic-gate static void 804*0Sstevel@tonic-gate set_width(void) 805*0Sstevel@tonic-gate { 806*0Sstevel@tonic-gate struct winsize win; 807*0Sstevel@tonic-gate 808*0Sstevel@tonic-gate if (!isatty(fileno(stdout))) 809*0Sstevel@tonic-gate return; 810*0Sstevel@tonic-gate 811*0Sstevel@tonic-gate if (ioctl(fileno(stdout), TIOCGWINSZ, &win) == -1) 812*0Sstevel@tonic-gate return; 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gate if (win.ws_col == 0) { 815*0Sstevel@tonic-gate /* 816*0Sstevel@tonic-gate * If TIOCGWINSZ returned 0 for the columns, just return -- 817*0Sstevel@tonic-gate * thereby using the default value of g_cpus_per_line. (This 818*0Sstevel@tonic-gate * happens, e.g., when running over a tip line.) 819*0Sstevel@tonic-gate */ 820*0Sstevel@tonic-gate return; 821*0Sstevel@tonic-gate } 822*0Sstevel@tonic-gate 823*0Sstevel@tonic-gate g_cpus_per_line = (win.ws_col - TSTAT_COLUMN_OFFS) / 824*0Sstevel@tonic-gate TSTAT_COLUMNS_PER_CPU; 825*0Sstevel@tonic-gate 826*0Sstevel@tonic-gate if (g_cpus_per_line < 1) 827*0Sstevel@tonic-gate g_cpus_per_line = 1; 828*0Sstevel@tonic-gate } 829*0Sstevel@tonic-gate 830*0Sstevel@tonic-gate static void 831*0Sstevel@tonic-gate intr(int signo) 832*0Sstevel@tonic-gate { 833*0Sstevel@tonic-gate int error = errno; 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate switch (signo) { 836*0Sstevel@tonic-gate case SIGWINCH: 837*0Sstevel@tonic-gate g_winch = 1; 838*0Sstevel@tonic-gate set_width(); 839*0Sstevel@tonic-gate break; 840*0Sstevel@tonic-gate 841*0Sstevel@tonic-gate case SIGCHLD: 842*0Sstevel@tonic-gate g_child_exited = 1; 843*0Sstevel@tonic-gate 844*0Sstevel@tonic-gate while (wait(&g_child_status) == -1 && errno == EINTR) 845*0Sstevel@tonic-gate continue; 846*0Sstevel@tonic-gate break; 847*0Sstevel@tonic-gate 848*0Sstevel@tonic-gate default: 849*0Sstevel@tonic-gate break; 850*0Sstevel@tonic-gate } 851*0Sstevel@tonic-gate 852*0Sstevel@tonic-gate errno = error; 853*0Sstevel@tonic-gate } 854*0Sstevel@tonic-gate 855*0Sstevel@tonic-gate static void 856*0Sstevel@tonic-gate setup(void) 857*0Sstevel@tonic-gate { 858*0Sstevel@tonic-gate struct sigaction act; 859*0Sstevel@tonic-gate struct sigevent ev; 860*0Sstevel@tonic-gate sigset_t set; 861*0Sstevel@tonic-gate int i; 862*0Sstevel@tonic-gate 863*0Sstevel@tonic-gate for (i = 0; i < TSTAT_NENT; i++) { 864*0Sstevel@tonic-gate if (g_traps[i].tent_type == TSTAT_ENT_RESERVED) 865*0Sstevel@tonic-gate g_traps[i].tent_name = "reserved"; 866*0Sstevel@tonic-gate 867*0Sstevel@tonic-gate if (g_traps[i].tent_type == TSTAT_ENT_UNUSED) 868*0Sstevel@tonic-gate g_traps[i].tent_name = "unused"; 869*0Sstevel@tonic-gate } 870*0Sstevel@tonic-gate 871*0Sstevel@tonic-gate g_max_cpus = (processorid_t)sysconf(_SC_CPUID_MAX) + 1; 872*0Sstevel@tonic-gate 873*0Sstevel@tonic-gate if ((g_selected = malloc(sizeof (int8_t) * g_max_cpus)) == NULL) 874*0Sstevel@tonic-gate fatal("could not allocate g_selected"); 875*0Sstevel@tonic-gate 876*0Sstevel@tonic-gate bzero(g_selected, sizeof (int8_t) * g_max_cpus); 877*0Sstevel@tonic-gate 878*0Sstevel@tonic-gate g_pset_cpus = malloc(sizeof (processorid_t) * g_max_cpus); 879*0Sstevel@tonic-gate if (g_pset_cpus == NULL) 880*0Sstevel@tonic-gate fatal("could not allocate g_pset_cpus"); 881*0Sstevel@tonic-gate 882*0Sstevel@tonic-gate bzero(g_pset_cpus, sizeof (processorid_t) * g_max_cpus); 883*0Sstevel@tonic-gate 884*0Sstevel@tonic-gate if ((g_pgsizes = getpagesizes(NULL, 0)) == -1) 885*0Sstevel@tonic-gate fatal("getpagesizes()"); 886*0Sstevel@tonic-gate 887*0Sstevel@tonic-gate if ((g_pgsize = malloc(sizeof (size_t) * g_pgsizes)) == NULL) 888*0Sstevel@tonic-gate fatal("could not allocate g_pgsize array"); 889*0Sstevel@tonic-gate 890*0Sstevel@tonic-gate if (getpagesizes(g_pgsize, g_pgsizes) == -1) 891*0Sstevel@tonic-gate fatal("getpagesizes(%d)", g_pgsizes); 892*0Sstevel@tonic-gate 893*0Sstevel@tonic-gate if ((g_pgnames = malloc(sizeof (char *) * g_pgsizes)) == NULL) 894*0Sstevel@tonic-gate fatal("could not allocate g_pgnames"); 895*0Sstevel@tonic-gate 896*0Sstevel@tonic-gate for (i = 0; i < g_pgsizes; i++) { 897*0Sstevel@tonic-gate size_t j, mul; 898*0Sstevel@tonic-gate size_t sz = g_pgsize[i]; 899*0Sstevel@tonic-gate 900*0Sstevel@tonic-gate if ((g_pgnames[i] = malloc(TSTAT_PAGESIZE_STRLEN)) == NULL) 901*0Sstevel@tonic-gate fatal("could not allocate g_pgnames[%d]", i); 902*0Sstevel@tonic-gate 903*0Sstevel@tonic-gate for (j = 0, mul = 10; (1 << mul) <= sz; j++, mul += 10) 904*0Sstevel@tonic-gate continue; 905*0Sstevel@tonic-gate 906*0Sstevel@tonic-gate (void) snprintf(g_pgnames[i], TSTAT_PAGESIZE_STRLEN, 907*0Sstevel@tonic-gate "%d%c", sz >> (mul - 10), " kmgtpe"[j]); 908*0Sstevel@tonic-gate } 909*0Sstevel@tonic-gate 910*0Sstevel@tonic-gate g_datasize = 911*0Sstevel@tonic-gate sizeof (tstat_data_t) + (g_pgsizes - 1) * sizeof (tstat_pgszdata_t); 912*0Sstevel@tonic-gate 913*0Sstevel@tonic-gate if ((g_data[0] = malloc(g_datasize * g_max_cpus)) == NULL) 914*0Sstevel@tonic-gate fatal("could not allocate data buffer 0"); 915*0Sstevel@tonic-gate 916*0Sstevel@tonic-gate if ((g_data[1] = malloc(g_datasize * g_max_cpus)) == NULL) 917*0Sstevel@tonic-gate fatal("could not allocate data buffer 1"); 918*0Sstevel@tonic-gate 919*0Sstevel@tonic-gate (void) sigemptyset(&act.sa_mask); 920*0Sstevel@tonic-gate act.sa_flags = 0; 921*0Sstevel@tonic-gate act.sa_handler = intr; 922*0Sstevel@tonic-gate (void) sigaction(SIGUSR1, &act, NULL); 923*0Sstevel@tonic-gate (void) sigaction(SIGCHLD, &act, NULL); 924*0Sstevel@tonic-gate 925*0Sstevel@tonic-gate (void) sigaddset(&act.sa_mask, SIGCHLD); 926*0Sstevel@tonic-gate (void) sigaddset(&act.sa_mask, SIGUSR1); 927*0Sstevel@tonic-gate (void) sigaction(SIGWINCH, &act, NULL); 928*0Sstevel@tonic-gate set_width(); 929*0Sstevel@tonic-gate 930*0Sstevel@tonic-gate (void) sigemptyset(&set); 931*0Sstevel@tonic-gate (void) sigaddset(&set, SIGCHLD); 932*0Sstevel@tonic-gate (void) sigaddset(&set, SIGUSR1); 933*0Sstevel@tonic-gate (void) sigaddset(&set, SIGWINCH); 934*0Sstevel@tonic-gate (void) sigprocmask(SIG_BLOCK, &set, &g_oset); 935*0Sstevel@tonic-gate 936*0Sstevel@tonic-gate ev.sigev_notify = SIGEV_SIGNAL; 937*0Sstevel@tonic-gate ev.sigev_signo = SIGUSR1; 938*0Sstevel@tonic-gate 939*0Sstevel@tonic-gate if (timer_create(CLOCK_HIGHRES, &ev, &g_tid) == -1) 940*0Sstevel@tonic-gate fatal("cannot create CLOCK_HIGHRES timer"); 941*0Sstevel@tonic-gate } 942*0Sstevel@tonic-gate 943*0Sstevel@tonic-gate static void 944*0Sstevel@tonic-gate set_interval(hrtime_t nsec) 945*0Sstevel@tonic-gate { 946*0Sstevel@tonic-gate struct itimerspec ts; 947*0Sstevel@tonic-gate 948*0Sstevel@tonic-gate /* 949*0Sstevel@tonic-gate * If the interval is less than one second, we'll report the 950*0Sstevel@tonic-gate * numbers in terms of rate-per-interval. If the interval is 951*0Sstevel@tonic-gate * greater than one second, we'll report numbers in terms of 952*0Sstevel@tonic-gate * rate-per-second. 953*0Sstevel@tonic-gate */ 954*0Sstevel@tonic-gate g_interval = nsec < NANOSEC ? nsec : NANOSEC; 955*0Sstevel@tonic-gate 956*0Sstevel@tonic-gate ts.it_value.tv_sec = nsec / NANOSEC; 957*0Sstevel@tonic-gate ts.it_value.tv_nsec = nsec % NANOSEC; 958*0Sstevel@tonic-gate ts.it_interval.tv_sec = nsec / NANOSEC; 959*0Sstevel@tonic-gate ts.it_interval.tv_nsec = nsec % NANOSEC; 960*0Sstevel@tonic-gate 961*0Sstevel@tonic-gate if (timer_settime(g_tid, TIMER_RELTIME, &ts, NULL) == -1) 962*0Sstevel@tonic-gate fatal("cannot set time on CLOCK_HIGHRES timer"); 963*0Sstevel@tonic-gate } 964*0Sstevel@tonic-gate 965*0Sstevel@tonic-gate static void 966*0Sstevel@tonic-gate print_entries(FILE *stream, int parsable) 967*0Sstevel@tonic-gate { 968*0Sstevel@tonic-gate int entno; 969*0Sstevel@tonic-gate 970*0Sstevel@tonic-gate if (!parsable) { 971*0Sstevel@tonic-gate (void) fprintf(stream, " %3s %3s | %-20s | %s\n", "hex", 972*0Sstevel@tonic-gate "dec", "entry name", "description"); 973*0Sstevel@tonic-gate 974*0Sstevel@tonic-gate (void) fprintf(stream, "----------+----------------------" 975*0Sstevel@tonic-gate "+-----------------------\n"); 976*0Sstevel@tonic-gate } 977*0Sstevel@tonic-gate 978*0Sstevel@tonic-gate for (entno = 0; entno < TSTAT_NENT; entno++) { 979*0Sstevel@tonic-gate if (g_traps[entno].tent_type != TSTAT_ENT_USED) 980*0Sstevel@tonic-gate continue; 981*0Sstevel@tonic-gate 982*0Sstevel@tonic-gate (void) fprintf(stream, "0x%03x %3d %s%-20s %s%s\n", 983*0Sstevel@tonic-gate entno, entno, 984*0Sstevel@tonic-gate parsable ? "" : "| ", g_traps[entno].tent_name, 985*0Sstevel@tonic-gate parsable ? "" : "| ", g_traps[entno].tent_descr); 986*0Sstevel@tonic-gate } 987*0Sstevel@tonic-gate } 988*0Sstevel@tonic-gate 989*0Sstevel@tonic-gate static void 990*0Sstevel@tonic-gate select_entry(char *entry) 991*0Sstevel@tonic-gate { 992*0Sstevel@tonic-gate ulong_t entno; 993*0Sstevel@tonic-gate char *end; 994*0Sstevel@tonic-gate 995*0Sstevel@tonic-gate /* 996*0Sstevel@tonic-gate * The entry may be specified as a number (e.g., "0x68", "104") or 997*0Sstevel@tonic-gate * as a name ("dtlb-miss"). 998*0Sstevel@tonic-gate */ 999*0Sstevel@tonic-gate entno = strtoul(entry, &end, 0); 1000*0Sstevel@tonic-gate 1001*0Sstevel@tonic-gate if (*end == '\0') { 1002*0Sstevel@tonic-gate if (entno >= TSTAT_NENT) 1003*0Sstevel@tonic-gate goto bad_entry; 1004*0Sstevel@tonic-gate } else { 1005*0Sstevel@tonic-gate for (entno = 0; entno < TSTAT_NENT; entno++) { 1006*0Sstevel@tonic-gate if (g_traps[entno].tent_type != TSTAT_ENT_USED) 1007*0Sstevel@tonic-gate continue; 1008*0Sstevel@tonic-gate 1009*0Sstevel@tonic-gate if (strcmp(entry, g_traps[entno].tent_name) == 0) 1010*0Sstevel@tonic-gate break; 1011*0Sstevel@tonic-gate } 1012*0Sstevel@tonic-gate 1013*0Sstevel@tonic-gate if (entno == TSTAT_NENT) 1014*0Sstevel@tonic-gate goto bad_entry; 1015*0Sstevel@tonic-gate } 1016*0Sstevel@tonic-gate 1017*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_ENTRY, entno) == -1) 1018*0Sstevel@tonic-gate fatal("TSTATIOC_ENTRY failed for entry 0x%x", entno); 1019*0Sstevel@tonic-gate 1020*0Sstevel@tonic-gate g_active[entno] = 1; 1021*0Sstevel@tonic-gate return; 1022*0Sstevel@tonic-gate 1023*0Sstevel@tonic-gate bad_entry: 1024*0Sstevel@tonic-gate (void) fprintf(stderr, TSTAT_COMMAND ": invalid entry '%s'", entry); 1025*0Sstevel@tonic-gate (void) fprintf(stderr, "; valid entries:\n\n"); 1026*0Sstevel@tonic-gate print_entries(stderr, 0); 1027*0Sstevel@tonic-gate exit(EXIT_FAILURE); 1028*0Sstevel@tonic-gate } 1029*0Sstevel@tonic-gate 1030*0Sstevel@tonic-gate static void 1031*0Sstevel@tonic-gate select_cpu(processorid_t cpu) 1032*0Sstevel@tonic-gate { 1033*0Sstevel@tonic-gate if (g_pset != PS_NONE) 1034*0Sstevel@tonic-gate fatal("cannot specify both a processor set and a processor\n"); 1035*0Sstevel@tonic-gate 1036*0Sstevel@tonic-gate if (cpu < 0 || cpu >= g_max_cpus) 1037*0Sstevel@tonic-gate fatal("cpu %d out of range\n", cpu); 1038*0Sstevel@tonic-gate 1039*0Sstevel@tonic-gate if (p_online(cpu, P_STATUS) == -1) { 1040*0Sstevel@tonic-gate if (errno != EINVAL) 1041*0Sstevel@tonic-gate fatal("could not get status for cpu %d", cpu); 1042*0Sstevel@tonic-gate fatal("cpu %d not present\n", cpu); 1043*0Sstevel@tonic-gate } 1044*0Sstevel@tonic-gate 1045*0Sstevel@tonic-gate g_selected[cpu] = 1; 1046*0Sstevel@tonic-gate } 1047*0Sstevel@tonic-gate 1048*0Sstevel@tonic-gate static void 1049*0Sstevel@tonic-gate select_cpus(processorid_t low, processorid_t high) 1050*0Sstevel@tonic-gate { 1051*0Sstevel@tonic-gate if (g_pset != PS_NONE) 1052*0Sstevel@tonic-gate fatal("cannot specify both a processor set and processors\n"); 1053*0Sstevel@tonic-gate 1054*0Sstevel@tonic-gate if (low < 0 || low >= g_max_cpus) 1055*0Sstevel@tonic-gate fatal("invalid cpu '%d'\n", low); 1056*0Sstevel@tonic-gate 1057*0Sstevel@tonic-gate if (high < 0 || high >= g_max_cpus) 1058*0Sstevel@tonic-gate fatal("invalid cpu '%d'\n", high); 1059*0Sstevel@tonic-gate 1060*0Sstevel@tonic-gate if (low >= high) 1061*0Sstevel@tonic-gate fatal("invalid range '%d' to '%d'\n", low, high); 1062*0Sstevel@tonic-gate 1063*0Sstevel@tonic-gate do { 1064*0Sstevel@tonic-gate if (p_online(low, P_STATUS) != -1) 1065*0Sstevel@tonic-gate g_selected[low] = 1; 1066*0Sstevel@tonic-gate } while (++low <= high); 1067*0Sstevel@tonic-gate } 1068*0Sstevel@tonic-gate 1069*0Sstevel@tonic-gate static void 1070*0Sstevel@tonic-gate select_pset(psetid_t pset) 1071*0Sstevel@tonic-gate { 1072*0Sstevel@tonic-gate processorid_t i; 1073*0Sstevel@tonic-gate 1074*0Sstevel@tonic-gate if (pset < 0) 1075*0Sstevel@tonic-gate fatal("processor set %d is out of range\n", pset); 1076*0Sstevel@tonic-gate 1077*0Sstevel@tonic-gate /* 1078*0Sstevel@tonic-gate * Only one processor set can be specified. 1079*0Sstevel@tonic-gate */ 1080*0Sstevel@tonic-gate if (g_pset != PS_NONE) 1081*0Sstevel@tonic-gate fatal("at most one processor set may be specified\n"); 1082*0Sstevel@tonic-gate 1083*0Sstevel@tonic-gate /* 1084*0Sstevel@tonic-gate * One cannot select processors _and_ a processor set. 1085*0Sstevel@tonic-gate */ 1086*0Sstevel@tonic-gate for (i = 0; i < g_max_cpus; i++) 1087*0Sstevel@tonic-gate if (g_selected[i]) 1088*0Sstevel@tonic-gate break; 1089*0Sstevel@tonic-gate 1090*0Sstevel@tonic-gate if (i != g_max_cpus) 1091*0Sstevel@tonic-gate fatal("cannot specify both a processor and a processor set\n"); 1092*0Sstevel@tonic-gate 1093*0Sstevel@tonic-gate g_pset = pset; 1094*0Sstevel@tonic-gate g_pset_ncpus = g_max_cpus; 1095*0Sstevel@tonic-gate 1096*0Sstevel@tonic-gate if (pset_info(g_pset, NULL, &g_pset_ncpus, g_pset_cpus) == -1) 1097*0Sstevel@tonic-gate fatal("invalid processor set: %d\n", g_pset); 1098*0Sstevel@tonic-gate 1099*0Sstevel@tonic-gate if (g_pset_ncpus == 0) 1100*0Sstevel@tonic-gate fatal("processor set %d empty\n", g_pset); 1101*0Sstevel@tonic-gate 1102*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_NOCPU) == -1) 1103*0Sstevel@tonic-gate fatal("TSTATIOC_NOCPU failed"); 1104*0Sstevel@tonic-gate 1105*0Sstevel@tonic-gate for (i = 0; i < g_pset_ncpus; i++) 1106*0Sstevel@tonic-gate g_selected[g_pset_cpus[i]] = 1; 1107*0Sstevel@tonic-gate } 1108*0Sstevel@tonic-gate 1109*0Sstevel@tonic-gate static void 1110*0Sstevel@tonic-gate check_pset(void) 1111*0Sstevel@tonic-gate { 1112*0Sstevel@tonic-gate uint_t ncpus = g_max_cpus; 1113*0Sstevel@tonic-gate processorid_t i; 1114*0Sstevel@tonic-gate 1115*0Sstevel@tonic-gate if (g_pset == PS_NONE) 1116*0Sstevel@tonic-gate return; 1117*0Sstevel@tonic-gate 1118*0Sstevel@tonic-gate if (pset_info(g_pset, NULL, &ncpus, g_pset_cpus) == -1) { 1119*0Sstevel@tonic-gate if (errno == EINVAL) 1120*0Sstevel@tonic-gate fatal("processor set %d destroyed\n", g_pset); 1121*0Sstevel@tonic-gate 1122*0Sstevel@tonic-gate fatal("couldn't get info for processor set %d", g_pset); 1123*0Sstevel@tonic-gate } 1124*0Sstevel@tonic-gate 1125*0Sstevel@tonic-gate if (ncpus == 0) 1126*0Sstevel@tonic-gate fatal("processor set %d empty\n", g_pset); 1127*0Sstevel@tonic-gate 1128*0Sstevel@tonic-gate if (ncpus == g_pset_ncpus) { 1129*0Sstevel@tonic-gate for (i = 0; i < g_pset_ncpus; i++) { 1130*0Sstevel@tonic-gate if (!g_selected[g_pset_cpus[i]]) 1131*0Sstevel@tonic-gate break; 1132*0Sstevel@tonic-gate } 1133*0Sstevel@tonic-gate 1134*0Sstevel@tonic-gate /* 1135*0Sstevel@tonic-gate * If the number of CPUs hasn't changed, and every CPU 1136*0Sstevel@tonic-gate * in the processor set is also selected, we know that the 1137*0Sstevel@tonic-gate * processor set itself hasn't changed. 1138*0Sstevel@tonic-gate */ 1139*0Sstevel@tonic-gate if (i == g_pset_ncpus) 1140*0Sstevel@tonic-gate return; 1141*0Sstevel@tonic-gate } 1142*0Sstevel@tonic-gate 1143*0Sstevel@tonic-gate /* 1144*0Sstevel@tonic-gate * If we're here, we have a new processor set. First, we need 1145*0Sstevel@tonic-gate * to zero out the selection array. 1146*0Sstevel@tonic-gate */ 1147*0Sstevel@tonic-gate bzero(g_selected, sizeof (int8_t) * g_max_cpus); 1148*0Sstevel@tonic-gate 1149*0Sstevel@tonic-gate g_pset_ncpus = ncpus; 1150*0Sstevel@tonic-gate 1151*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_STOP) == -1) 1152*0Sstevel@tonic-gate fatal("TSTATIOC_STOP failed"); 1153*0Sstevel@tonic-gate 1154*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_NOCPU) == -1) 1155*0Sstevel@tonic-gate fatal("TSATIOC_NOCPU failed"); 1156*0Sstevel@tonic-gate 1157*0Sstevel@tonic-gate for (i = 0; i < g_pset_ncpus; i++) { 1158*0Sstevel@tonic-gate g_selected[g_pset_cpus[i]] = 1; 1159*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_CPU, g_pset_cpus[i]) == -1) 1160*0Sstevel@tonic-gate fatal("TSTATIOC_CPU failed for cpu %d", i); 1161*0Sstevel@tonic-gate } 1162*0Sstevel@tonic-gate 1163*0Sstevel@tonic-gate /* 1164*0Sstevel@tonic-gate * Now that we have selected the CPUs, we're going to reenable 1165*0Sstevel@tonic-gate * trapstat, and reread the data for the current generation. 1166*0Sstevel@tonic-gate */ 1167*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_GO) == -1) 1168*0Sstevel@tonic-gate fatal("TSTATIOC_GO failed"); 1169*0Sstevel@tonic-gate 1170*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_READ, g_data[g_gen]) == -1) 1171*0Sstevel@tonic-gate fatal("TSTATIOC_READ failed"); 1172*0Sstevel@tonic-gate } 1173*0Sstevel@tonic-gate 1174*0Sstevel@tonic-gate static void 1175*0Sstevel@tonic-gate missdata(tstat_missdata_t *miss, tstat_missdata_t *omiss) 1176*0Sstevel@tonic-gate { 1177*0Sstevel@tonic-gate hrtime_t ts = g_ndata->tdata_snapts - g_odata->tdata_snapts; 1178*0Sstevel@tonic-gate hrtime_t tick = g_ndata->tdata_snaptick - g_odata->tdata_snaptick; 1179*0Sstevel@tonic-gate uint64_t raw = miss->tmiss_count - omiss->tmiss_count; 1180*0Sstevel@tonic-gate uint64_t diff = g_absolute ? miss->tmiss_count : 1181*0Sstevel@tonic-gate (uint64_t)(0.5 + g_interval / 1182*0Sstevel@tonic-gate (double)ts * (double)(miss->tmiss_count - omiss->tmiss_count)); 1183*0Sstevel@tonic-gate hrtime_t peffect = raw * g_ndata->tdata_peffect * g_peffect, time; 1184*0Sstevel@tonic-gate double p; 1185*0Sstevel@tonic-gate 1186*0Sstevel@tonic-gate /* 1187*0Sstevel@tonic-gate * Now we need to account for the trapstat probe effect. Take 1188*0Sstevel@tonic-gate * the amount of time spent in the handler, and add the 1189*0Sstevel@tonic-gate * amount of time known to be due to the trapstat probe effect. 1190*0Sstevel@tonic-gate */ 1191*0Sstevel@tonic-gate time = miss->tmiss_time - omiss->tmiss_time + peffect; 1192*0Sstevel@tonic-gate 1193*0Sstevel@tonic-gate if (time >= tick) { 1194*0Sstevel@tonic-gate /* 1195*0Sstevel@tonic-gate * This really shouldn't happen unless our calculation of 1196*0Sstevel@tonic-gate * the probe effect was vastly incorrect. In any case, 1197*0Sstevel@tonic-gate * print 99.9 for the time instead of printing negative 1198*0Sstevel@tonic-gate * values... 1199*0Sstevel@tonic-gate */ 1200*0Sstevel@tonic-gate time = tick / 1000 * 999; 1201*0Sstevel@tonic-gate } 1202*0Sstevel@tonic-gate 1203*0Sstevel@tonic-gate p = (double)time / (double)tick * (double)100.0; 1204*0Sstevel@tonic-gate 1205*0Sstevel@tonic-gate (*g_process)(g_arg, diff, p); 1206*0Sstevel@tonic-gate } 1207*0Sstevel@tonic-gate 1208*0Sstevel@tonic-gate static void 1209*0Sstevel@tonic-gate tlbdata(tstat_tlbdata_t *tlb, tstat_tlbdata_t *otlb) 1210*0Sstevel@tonic-gate { 1211*0Sstevel@tonic-gate missdata(&tlb->ttlb_tlb, &otlb->ttlb_tlb); 1212*0Sstevel@tonic-gate missdata(&tlb->ttlb_tsb, &otlb->ttlb_tsb); 1213*0Sstevel@tonic-gate } 1214*0Sstevel@tonic-gate 1215*0Sstevel@tonic-gate static void 1216*0Sstevel@tonic-gate print_missdata(double *ttl, uint64_t diff, double p) 1217*0Sstevel@tonic-gate { 1218*0Sstevel@tonic-gate TSTAT_PRINT_MISSDATA(diff, p); 1219*0Sstevel@tonic-gate 1220*0Sstevel@tonic-gate if (ttl != NULL) 1221*0Sstevel@tonic-gate *ttl += p; 1222*0Sstevel@tonic-gate } 1223*0Sstevel@tonic-gate 1224*0Sstevel@tonic-gate static void 1225*0Sstevel@tonic-gate print_modepgsz(char *prefix, tstat_modedata_t *data, tstat_modedata_t *odata) 1226*0Sstevel@tonic-gate { 1227*0Sstevel@tonic-gate int ps; 1228*0Sstevel@tonic-gate size_t incr = sizeof (tstat_pgszdata_t); 1229*0Sstevel@tonic-gate 1230*0Sstevel@tonic-gate for (ps = 0; ps < g_pgsizes; ps++) { 1231*0Sstevel@tonic-gate double ttl = 0.0; 1232*0Sstevel@tonic-gate 1233*0Sstevel@tonic-gate g_process = (void(*)(void *, uint64_t, double))print_missdata; 1234*0Sstevel@tonic-gate g_arg = &ttl; 1235*0Sstevel@tonic-gate 1236*0Sstevel@tonic-gate (void) printf("%s %4s|", prefix, g_pgnames[ps]); 1237*0Sstevel@tonic-gate tlbdata(&data->tmode_itlb, &odata->tmode_itlb); 1238*0Sstevel@tonic-gate (void) printf(" |"); 1239*0Sstevel@tonic-gate tlbdata(&data->tmode_dtlb, &odata->tmode_dtlb); 1240*0Sstevel@tonic-gate 1241*0Sstevel@tonic-gate (void) printf(" |%4.1f\n", ttl); 1242*0Sstevel@tonic-gate 1243*0Sstevel@tonic-gate data = (tstat_modedata_t *)((uintptr_t)data + incr); 1244*0Sstevel@tonic-gate odata = (tstat_modedata_t *)((uintptr_t)odata + incr); 1245*0Sstevel@tonic-gate } 1246*0Sstevel@tonic-gate } 1247*0Sstevel@tonic-gate 1248*0Sstevel@tonic-gate static void 1249*0Sstevel@tonic-gate parsable_modepgsz(char *prefix, tstat_modedata_t *data, tstat_modedata_t *odata) 1250*0Sstevel@tonic-gate { 1251*0Sstevel@tonic-gate int ps; 1252*0Sstevel@tonic-gate size_t incr = sizeof (tstat_pgszdata_t); 1253*0Sstevel@tonic-gate 1254*0Sstevel@tonic-gate g_process = (void(*)(void *, uint64_t, double))print_missdata; 1255*0Sstevel@tonic-gate g_arg = NULL; 1256*0Sstevel@tonic-gate 1257*0Sstevel@tonic-gate for (ps = 0; ps < g_pgsizes; ps++) { 1258*0Sstevel@tonic-gate (void) printf("%s %7d", prefix, g_pgsize[ps]); 1259*0Sstevel@tonic-gate tlbdata(&data->tmode_itlb, &odata->tmode_itlb); 1260*0Sstevel@tonic-gate tlbdata(&data->tmode_dtlb, &odata->tmode_dtlb); 1261*0Sstevel@tonic-gate (void) printf("\n"); 1262*0Sstevel@tonic-gate 1263*0Sstevel@tonic-gate data = (tstat_modedata_t *)((uintptr_t)data + incr); 1264*0Sstevel@tonic-gate odata = (tstat_modedata_t *)((uintptr_t)odata + incr); 1265*0Sstevel@tonic-gate } 1266*0Sstevel@tonic-gate } 1267*0Sstevel@tonic-gate 1268*0Sstevel@tonic-gate static void 1269*0Sstevel@tonic-gate sum_missdata(void *sump, uint64_t diff, double p) 1270*0Sstevel@tonic-gate { 1271*0Sstevel@tonic-gate tstat_sum_t *sum = *((tstat_sum_t **)sump); 1272*0Sstevel@tonic-gate 1273*0Sstevel@tonic-gate sum->tsum_diff += diff; 1274*0Sstevel@tonic-gate sum->tsum_time += p; 1275*0Sstevel@tonic-gate 1276*0Sstevel@tonic-gate (*(tstat_sum_t **)sump)++; 1277*0Sstevel@tonic-gate } 1278*0Sstevel@tonic-gate 1279*0Sstevel@tonic-gate static void 1280*0Sstevel@tonic-gate sum_modedata(tstat_modedata_t *data, tstat_modedata_t *odata, tstat_sum_t *sum) 1281*0Sstevel@tonic-gate { 1282*0Sstevel@tonic-gate int ps, incr = sizeof (tstat_pgszdata_t); 1283*0Sstevel@tonic-gate tstat_sum_t *sump; 1284*0Sstevel@tonic-gate 1285*0Sstevel@tonic-gate for (ps = 0; ps < g_pgsizes; ps++) { 1286*0Sstevel@tonic-gate sump = sum; 1287*0Sstevel@tonic-gate 1288*0Sstevel@tonic-gate g_process = sum_missdata; 1289*0Sstevel@tonic-gate g_arg = &sump; 1290*0Sstevel@tonic-gate 1291*0Sstevel@tonic-gate tlbdata(&data->tmode_itlb, &odata->tmode_itlb); 1292*0Sstevel@tonic-gate tlbdata(&data->tmode_dtlb, &odata->tmode_dtlb); 1293*0Sstevel@tonic-gate 1294*0Sstevel@tonic-gate data = (tstat_modedata_t *)((uintptr_t)data + incr); 1295*0Sstevel@tonic-gate odata = (tstat_modedata_t *)((uintptr_t)odata + incr); 1296*0Sstevel@tonic-gate } 1297*0Sstevel@tonic-gate } 1298*0Sstevel@tonic-gate 1299*0Sstevel@tonic-gate static void 1300*0Sstevel@tonic-gate print_sum(tstat_sum_t *sum, int divisor) 1301*0Sstevel@tonic-gate { 1302*0Sstevel@tonic-gate int i; 1303*0Sstevel@tonic-gate double ttl = 0.0; 1304*0Sstevel@tonic-gate 1305*0Sstevel@tonic-gate for (i = 0; i < 4; i++) { 1306*0Sstevel@tonic-gate if (i == 2) 1307*0Sstevel@tonic-gate (void) printf(" |"); 1308*0Sstevel@tonic-gate 1309*0Sstevel@tonic-gate sum[i].tsum_time /= divisor; 1310*0Sstevel@tonic-gate 1311*0Sstevel@tonic-gate TSTAT_PRINT_MISSDATA(sum[i].tsum_diff, sum[i].tsum_time); 1312*0Sstevel@tonic-gate ttl += sum[i].tsum_time; 1313*0Sstevel@tonic-gate } 1314*0Sstevel@tonic-gate 1315*0Sstevel@tonic-gate (void) printf(" |%4.1f\n", ttl); 1316*0Sstevel@tonic-gate } 1317*0Sstevel@tonic-gate 1318*0Sstevel@tonic-gate static void 1319*0Sstevel@tonic-gate print_tlbpgsz(tstat_data_t *data, tstat_data_t *odata) 1320*0Sstevel@tonic-gate { 1321*0Sstevel@tonic-gate int i, cpu, ncpus = 0; 1322*0Sstevel@tonic-gate char pre[12]; 1323*0Sstevel@tonic-gate tstat_sum_t sum[4]; 1324*0Sstevel@tonic-gate 1325*0Sstevel@tonic-gate (void) printf("cpu m size| %9s %4s %9s %4s | %9s %4s %9s %4s |%4s\n" 1326*0Sstevel@tonic-gate "----------+-------------------------------+-----------------------" 1327*0Sstevel@tonic-gate "--------+----\n", "itlb-miss", "%tim", "itsb-miss", "%tim", 1328*0Sstevel@tonic-gate "dtlb-miss", "%tim", "dtsb-miss", "%tim", "%tim"); 1329*0Sstevel@tonic-gate 1330*0Sstevel@tonic-gate bzero(sum, sizeof (sum)); 1331*0Sstevel@tonic-gate 1332*0Sstevel@tonic-gate for (i = 0; i < g_max_cpus; i++) { 1333*0Sstevel@tonic-gate tstat_pgszdata_t *pgsz = data->tdata_pgsz; 1334*0Sstevel@tonic-gate tstat_pgszdata_t *opgsz = odata->tdata_pgsz; 1335*0Sstevel@tonic-gate 1336*0Sstevel@tonic-gate if ((cpu = data->tdata_cpuid) == -1) 1337*0Sstevel@tonic-gate break; 1338*0Sstevel@tonic-gate 1339*0Sstevel@tonic-gate if (i != 0) 1340*0Sstevel@tonic-gate (void) printf("----------+-----------------------------" 1341*0Sstevel@tonic-gate "--+-------------------------------+----\n"); 1342*0Sstevel@tonic-gate 1343*0Sstevel@tonic-gate g_ndata = data; 1344*0Sstevel@tonic-gate g_odata = odata; 1345*0Sstevel@tonic-gate 1346*0Sstevel@tonic-gate (void) sprintf(pre, "%3d u", cpu); 1347*0Sstevel@tonic-gate print_modepgsz(pre, &pgsz->tpgsz_user, &opgsz->tpgsz_user); 1348*0Sstevel@tonic-gate sum_modedata(&pgsz->tpgsz_user, &opgsz->tpgsz_user, sum); 1349*0Sstevel@tonic-gate 1350*0Sstevel@tonic-gate (void) printf("- - - - - + - - - - - - - - - - - - - -" 1351*0Sstevel@tonic-gate " - + - - - - - - - - - - - - - - - + - -\n"); 1352*0Sstevel@tonic-gate 1353*0Sstevel@tonic-gate (void) sprintf(pre, "%3d k", cpu); 1354*0Sstevel@tonic-gate print_modepgsz(pre, &pgsz->tpgsz_kernel, &opgsz->tpgsz_kernel); 1355*0Sstevel@tonic-gate sum_modedata(&pgsz->tpgsz_kernel, &opgsz->tpgsz_kernel, sum); 1356*0Sstevel@tonic-gate 1357*0Sstevel@tonic-gate data = (tstat_data_t *)((uintptr_t)data + g_datasize); 1358*0Sstevel@tonic-gate odata = (tstat_data_t *)((uintptr_t)odata + g_datasize); 1359*0Sstevel@tonic-gate ncpus++; 1360*0Sstevel@tonic-gate } 1361*0Sstevel@tonic-gate 1362*0Sstevel@tonic-gate (void) printf("==========+===============================+=========" 1363*0Sstevel@tonic-gate "======================+====\n"); 1364*0Sstevel@tonic-gate (void) printf(" ttl |"); 1365*0Sstevel@tonic-gate print_sum(sum, ncpus); 1366*0Sstevel@tonic-gate (void) printf("\n"); 1367*0Sstevel@tonic-gate } 1368*0Sstevel@tonic-gate 1369*0Sstevel@tonic-gate static void 1370*0Sstevel@tonic-gate parsable_tlbpgsz(tstat_data_t *data, tstat_data_t *odata) 1371*0Sstevel@tonic-gate { 1372*0Sstevel@tonic-gate int i, cpu; 1373*0Sstevel@tonic-gate char pre[30]; 1374*0Sstevel@tonic-gate 1375*0Sstevel@tonic-gate for (i = 0; i < g_max_cpus; i++) { 1376*0Sstevel@tonic-gate tstat_pgszdata_t *pgsz = data->tdata_pgsz; 1377*0Sstevel@tonic-gate tstat_pgszdata_t *opgsz = odata->tdata_pgsz; 1378*0Sstevel@tonic-gate 1379*0Sstevel@tonic-gate if ((cpu = data->tdata_cpuid) == -1) 1380*0Sstevel@tonic-gate break; 1381*0Sstevel@tonic-gate 1382*0Sstevel@tonic-gate g_ndata = data; 1383*0Sstevel@tonic-gate g_odata = odata; 1384*0Sstevel@tonic-gate 1385*0Sstevel@tonic-gate (void) sprintf(pre, "%lld %3d u", 1386*0Sstevel@tonic-gate data->tdata_snapts - g_start, cpu); 1387*0Sstevel@tonic-gate parsable_modepgsz(pre, &pgsz->tpgsz_user, &opgsz->tpgsz_user); 1388*0Sstevel@tonic-gate 1389*0Sstevel@tonic-gate pre[strlen(pre) - 1] = 'k'; 1390*0Sstevel@tonic-gate parsable_modepgsz(pre, &pgsz->tpgsz_kernel, 1391*0Sstevel@tonic-gate &opgsz->tpgsz_kernel); 1392*0Sstevel@tonic-gate 1393*0Sstevel@tonic-gate data = (tstat_data_t *)((uintptr_t)data + g_datasize); 1394*0Sstevel@tonic-gate odata = (tstat_data_t *)((uintptr_t)odata + g_datasize); 1395*0Sstevel@tonic-gate } 1396*0Sstevel@tonic-gate } 1397*0Sstevel@tonic-gate 1398*0Sstevel@tonic-gate static void 1399*0Sstevel@tonic-gate print_modedata(tstat_modedata_t *data, tstat_modedata_t *odata, int parsable) 1400*0Sstevel@tonic-gate { 1401*0Sstevel@tonic-gate int ps, i; 1402*0Sstevel@tonic-gate size_t incr = sizeof (tstat_pgszdata_t); 1403*0Sstevel@tonic-gate tstat_sum_t sum[4], *sump = sum; 1404*0Sstevel@tonic-gate double ttl = 0.0; 1405*0Sstevel@tonic-gate 1406*0Sstevel@tonic-gate bzero(sum, sizeof (sum)); 1407*0Sstevel@tonic-gate g_process = sum_missdata; 1408*0Sstevel@tonic-gate g_arg = &sump; 1409*0Sstevel@tonic-gate 1410*0Sstevel@tonic-gate for (ps = 0; ps < g_pgsizes; ps++) { 1411*0Sstevel@tonic-gate tlbdata(&data->tmode_itlb, &odata->tmode_itlb); 1412*0Sstevel@tonic-gate tlbdata(&data->tmode_dtlb, &odata->tmode_dtlb); 1413*0Sstevel@tonic-gate 1414*0Sstevel@tonic-gate data = (tstat_modedata_t *)((uintptr_t)data + incr); 1415*0Sstevel@tonic-gate odata = (tstat_modedata_t *)((uintptr_t)odata + incr); 1416*0Sstevel@tonic-gate sump = sum; 1417*0Sstevel@tonic-gate } 1418*0Sstevel@tonic-gate 1419*0Sstevel@tonic-gate for (i = 0; i < 4; i++) { 1420*0Sstevel@tonic-gate if (i == 2 && !parsable) 1421*0Sstevel@tonic-gate (void) printf(" |"); 1422*0Sstevel@tonic-gate 1423*0Sstevel@tonic-gate TSTAT_PRINT_MISSDATA(sum[i].tsum_diff, sum[i].tsum_time); 1424*0Sstevel@tonic-gate ttl += sum[i].tsum_time; 1425*0Sstevel@tonic-gate } 1426*0Sstevel@tonic-gate 1427*0Sstevel@tonic-gate if (parsable) { 1428*0Sstevel@tonic-gate (void) printf("\n"); 1429*0Sstevel@tonic-gate return; 1430*0Sstevel@tonic-gate } 1431*0Sstevel@tonic-gate 1432*0Sstevel@tonic-gate (void) printf(" |%4.1f\n", ttl); 1433*0Sstevel@tonic-gate } 1434*0Sstevel@tonic-gate 1435*0Sstevel@tonic-gate static void 1436*0Sstevel@tonic-gate print_tlb(tstat_data_t *data, tstat_data_t *odata) 1437*0Sstevel@tonic-gate { 1438*0Sstevel@tonic-gate int i, cpu, ncpus = 0; 1439*0Sstevel@tonic-gate tstat_sum_t sum[4]; 1440*0Sstevel@tonic-gate 1441*0Sstevel@tonic-gate (void) printf("cpu m| %9s %4s %9s %4s | %9s %4s %9s %4s |%4s\n" 1442*0Sstevel@tonic-gate "-----+-------------------------------+-----------------------" 1443*0Sstevel@tonic-gate "--------+----\n", "itlb-miss", "%tim", "itsb-miss", "%tim", 1444*0Sstevel@tonic-gate "dtlb-miss", "%tim", "dtsb-miss", "%tim", "%tim"); 1445*0Sstevel@tonic-gate 1446*0Sstevel@tonic-gate bzero(sum, sizeof (sum)); 1447*0Sstevel@tonic-gate 1448*0Sstevel@tonic-gate for (i = 0; i < g_max_cpus; i++) { 1449*0Sstevel@tonic-gate tstat_pgszdata_t *pgsz = data->tdata_pgsz; 1450*0Sstevel@tonic-gate tstat_pgszdata_t *opgsz = odata->tdata_pgsz; 1451*0Sstevel@tonic-gate 1452*0Sstevel@tonic-gate if ((cpu = data->tdata_cpuid) == -1) 1453*0Sstevel@tonic-gate break; 1454*0Sstevel@tonic-gate 1455*0Sstevel@tonic-gate if (i != 0) 1456*0Sstevel@tonic-gate (void) printf("-----+-------------------------------+-" 1457*0Sstevel@tonic-gate "------------------------------+----\n"); 1458*0Sstevel@tonic-gate 1459*0Sstevel@tonic-gate g_ndata = data; 1460*0Sstevel@tonic-gate g_odata = odata; 1461*0Sstevel@tonic-gate 1462*0Sstevel@tonic-gate (void) printf("%3d u|", cpu); 1463*0Sstevel@tonic-gate print_modedata(&pgsz->tpgsz_user, &opgsz->tpgsz_user, 0); 1464*0Sstevel@tonic-gate sum_modedata(&pgsz->tpgsz_user, &opgsz->tpgsz_user, sum); 1465*0Sstevel@tonic-gate 1466*0Sstevel@tonic-gate (void) printf("%3d k|", cpu); 1467*0Sstevel@tonic-gate print_modedata(&pgsz->tpgsz_kernel, &opgsz->tpgsz_kernel, 0); 1468*0Sstevel@tonic-gate sum_modedata(&pgsz->tpgsz_kernel, &opgsz->tpgsz_kernel, sum); 1469*0Sstevel@tonic-gate 1470*0Sstevel@tonic-gate data = (tstat_data_t *)((uintptr_t)data + g_datasize); 1471*0Sstevel@tonic-gate odata = (tstat_data_t *)((uintptr_t)odata + g_datasize); 1472*0Sstevel@tonic-gate ncpus++; 1473*0Sstevel@tonic-gate } 1474*0Sstevel@tonic-gate 1475*0Sstevel@tonic-gate (void) printf("=====+===============================+=========" 1476*0Sstevel@tonic-gate "======================+====\n"); 1477*0Sstevel@tonic-gate 1478*0Sstevel@tonic-gate (void) printf(" ttl |"); 1479*0Sstevel@tonic-gate print_sum(sum, ncpus); 1480*0Sstevel@tonic-gate (void) printf("\n"); 1481*0Sstevel@tonic-gate } 1482*0Sstevel@tonic-gate 1483*0Sstevel@tonic-gate static void 1484*0Sstevel@tonic-gate parsable_tlb(tstat_data_t *data, tstat_data_t *odata) 1485*0Sstevel@tonic-gate { 1486*0Sstevel@tonic-gate int i, cpu; 1487*0Sstevel@tonic-gate 1488*0Sstevel@tonic-gate for (i = 0; i < g_max_cpus; i++) { 1489*0Sstevel@tonic-gate tstat_pgszdata_t *pgsz = data->tdata_pgsz; 1490*0Sstevel@tonic-gate tstat_pgszdata_t *opgsz = odata->tdata_pgsz; 1491*0Sstevel@tonic-gate 1492*0Sstevel@tonic-gate if ((cpu = data->tdata_cpuid) == -1) 1493*0Sstevel@tonic-gate break; 1494*0Sstevel@tonic-gate 1495*0Sstevel@tonic-gate g_ndata = data; 1496*0Sstevel@tonic-gate g_odata = odata; 1497*0Sstevel@tonic-gate 1498*0Sstevel@tonic-gate (void) printf("%lld %3d u ", data->tdata_snapts - g_start, cpu); 1499*0Sstevel@tonic-gate print_modedata(&pgsz->tpgsz_user, &opgsz->tpgsz_user, 1); 1500*0Sstevel@tonic-gate (void) printf("%lld %3d k ", data->tdata_snapts - g_start, cpu); 1501*0Sstevel@tonic-gate print_modedata(&pgsz->tpgsz_kernel, &opgsz->tpgsz_kernel, 1); 1502*0Sstevel@tonic-gate 1503*0Sstevel@tonic-gate data = (tstat_data_t *)((uintptr_t)data + g_datasize); 1504*0Sstevel@tonic-gate odata = (tstat_data_t *)((uintptr_t)odata + g_datasize); 1505*0Sstevel@tonic-gate } 1506*0Sstevel@tonic-gate } 1507*0Sstevel@tonic-gate 1508*0Sstevel@tonic-gate static void 1509*0Sstevel@tonic-gate print_stats(tstat_data_t *data, tstat_data_t *odata) 1510*0Sstevel@tonic-gate { 1511*0Sstevel@tonic-gate int i, j, k, done; 1512*0Sstevel@tonic-gate processorid_t id; 1513*0Sstevel@tonic-gate tstat_data_t *base = data; 1514*0Sstevel@tonic-gate 1515*0Sstevel@tonic-gate /* 1516*0Sstevel@tonic-gate * First, blast through all of the data updating our array 1517*0Sstevel@tonic-gate * of active traps. We keep an array of active traps to prevent 1518*0Sstevel@tonic-gate * printing lines for traps that are never seen -- while still printing 1519*0Sstevel@tonic-gate * lines for traps that have been seen only once on some CPU. 1520*0Sstevel@tonic-gate */ 1521*0Sstevel@tonic-gate for (i = 0; i < g_max_cpus; i++) { 1522*0Sstevel@tonic-gate if (data[i].tdata_cpuid == -1) 1523*0Sstevel@tonic-gate break; 1524*0Sstevel@tonic-gate 1525*0Sstevel@tonic-gate for (j = 0; j < TSTAT_NENT; j++) { 1526*0Sstevel@tonic-gate if (!data[i].tdata_traps[j] || g_active[j]) 1527*0Sstevel@tonic-gate continue; 1528*0Sstevel@tonic-gate 1529*0Sstevel@tonic-gate g_active[j] = 1; 1530*0Sstevel@tonic-gate } 1531*0Sstevel@tonic-gate } 1532*0Sstevel@tonic-gate 1533*0Sstevel@tonic-gate data = base; 1534*0Sstevel@tonic-gate 1535*0Sstevel@tonic-gate for (done = 0; !done; data += g_cpus_per_line) { 1536*0Sstevel@tonic-gate for (i = 0; i < g_cpus_per_line; i++) { 1537*0Sstevel@tonic-gate if (&data[i] - base >= g_max_cpus) 1538*0Sstevel@tonic-gate break; 1539*0Sstevel@tonic-gate 1540*0Sstevel@tonic-gate if ((id = data[i].tdata_cpuid) == -1) 1541*0Sstevel@tonic-gate break; 1542*0Sstevel@tonic-gate 1543*0Sstevel@tonic-gate if (i == 0) 1544*0Sstevel@tonic-gate (void) printf("vct name |"); 1545*0Sstevel@tonic-gate 1546*0Sstevel@tonic-gate (void) printf(" %scpu%d", id >= 100 ? "" : 1547*0Sstevel@tonic-gate id >= 10 ? " " : " ", id); 1548*0Sstevel@tonic-gate } 1549*0Sstevel@tonic-gate 1550*0Sstevel@tonic-gate if (i == 0) 1551*0Sstevel@tonic-gate break; 1552*0Sstevel@tonic-gate 1553*0Sstevel@tonic-gate if (i != g_cpus_per_line) 1554*0Sstevel@tonic-gate done = 1; 1555*0Sstevel@tonic-gate 1556*0Sstevel@tonic-gate (void) printf("\n------------------------+"); 1557*0Sstevel@tonic-gate 1558*0Sstevel@tonic-gate for (j = 0; j < i; j++) 1559*0Sstevel@tonic-gate (void) printf("---------"); 1560*0Sstevel@tonic-gate (void) printf("\n"); 1561*0Sstevel@tonic-gate 1562*0Sstevel@tonic-gate for (j = 0; j < TSTAT_NENT; j++) { 1563*0Sstevel@tonic-gate if (!g_active[j]) 1564*0Sstevel@tonic-gate continue; 1565*0Sstevel@tonic-gate 1566*0Sstevel@tonic-gate (void) printf("%3x %-20s|", j, g_traps[j].tent_name); 1567*0Sstevel@tonic-gate for (k = 0; k < i; k++) { 1568*0Sstevel@tonic-gate (void) printf(" %8lld", TSTAT_DELTA(&data[k], 1569*0Sstevel@tonic-gate &odata[data - base + k], tdata_traps[j])); 1570*0Sstevel@tonic-gate } 1571*0Sstevel@tonic-gate (void) printf("\n"); 1572*0Sstevel@tonic-gate } 1573*0Sstevel@tonic-gate (void) printf("\n"); 1574*0Sstevel@tonic-gate } 1575*0Sstevel@tonic-gate } 1576*0Sstevel@tonic-gate 1577*0Sstevel@tonic-gate static void 1578*0Sstevel@tonic-gate parsable_stats(tstat_data_t *data, tstat_data_t *odata) 1579*0Sstevel@tonic-gate { 1580*0Sstevel@tonic-gate tstat_data_t *base; 1581*0Sstevel@tonic-gate int i; 1582*0Sstevel@tonic-gate 1583*0Sstevel@tonic-gate for (base = data; data - base < g_max_cpus; data++, odata++) { 1584*0Sstevel@tonic-gate if (data->tdata_cpuid == -1) 1585*0Sstevel@tonic-gate break; 1586*0Sstevel@tonic-gate 1587*0Sstevel@tonic-gate for (i = 0; i < TSTAT_NENT; i++) { 1588*0Sstevel@tonic-gate if (!data->tdata_traps[i] && !g_active[i]) 1589*0Sstevel@tonic-gate continue; 1590*0Sstevel@tonic-gate 1591*0Sstevel@tonic-gate (void) printf("%lld %d %x %s ", 1592*0Sstevel@tonic-gate data->tdata_snapts - g_start, data->tdata_cpuid, i, 1593*0Sstevel@tonic-gate g_traps[i].tent_name); 1594*0Sstevel@tonic-gate 1595*0Sstevel@tonic-gate (void) printf("%lld\n", TSTAT_DELTA(data, odata, 1596*0Sstevel@tonic-gate tdata_traps[i])); 1597*0Sstevel@tonic-gate } 1598*0Sstevel@tonic-gate } 1599*0Sstevel@tonic-gate } 1600*0Sstevel@tonic-gate 1601*0Sstevel@tonic-gate static void 1602*0Sstevel@tonic-gate check_data(tstat_data_t *data, tstat_data_t *odata) 1603*0Sstevel@tonic-gate { 1604*0Sstevel@tonic-gate tstat_data_t *ndata; 1605*0Sstevel@tonic-gate int i; 1606*0Sstevel@tonic-gate 1607*0Sstevel@tonic-gate if (data->tdata_cpuid == -1) { 1608*0Sstevel@tonic-gate /* 1609*0Sstevel@tonic-gate * The last CPU we were watching must have been DR'd out 1610*0Sstevel@tonic-gate * of the system. Print a vaguely useful message and exit. 1611*0Sstevel@tonic-gate */ 1612*0Sstevel@tonic-gate fatal("all initially selected CPUs have been unconfigured\n"); 1613*0Sstevel@tonic-gate } 1614*0Sstevel@tonic-gate 1615*0Sstevel@tonic-gate /* 1616*0Sstevel@tonic-gate * If a CPU is DR'd out of the system, we'll stop receiving data 1617*0Sstevel@tonic-gate * for it. CPUs are never added, however (that is, if a CPU is 1618*0Sstevel@tonic-gate * DR'd into the system, we won't automatically start receiving 1619*0Sstevel@tonic-gate * data for it). We check for this by making sure that all of 1620*0Sstevel@tonic-gate * the CPUs present in the old data are present in the new data. 1621*0Sstevel@tonic-gate * If we find one missing in the new data, we correct the old data 1622*0Sstevel@tonic-gate * by removing the old CPU. This assures that delta are printed 1623*0Sstevel@tonic-gate * correctly. 1624*0Sstevel@tonic-gate */ 1625*0Sstevel@tonic-gate for (i = 0; i < g_max_cpus; i++) { 1626*0Sstevel@tonic-gate if (odata->tdata_cpuid == -1) 1627*0Sstevel@tonic-gate return; 1628*0Sstevel@tonic-gate 1629*0Sstevel@tonic-gate if (data->tdata_cpuid != odata->tdata_cpuid) 1630*0Sstevel@tonic-gate break; 1631*0Sstevel@tonic-gate 1632*0Sstevel@tonic-gate data = (tstat_data_t *)((uintptr_t)data + g_datasize); 1633*0Sstevel@tonic-gate odata = (tstat_data_t *)((uintptr_t)odata + g_datasize); 1634*0Sstevel@tonic-gate } 1635*0Sstevel@tonic-gate 1636*0Sstevel@tonic-gate if (i == g_max_cpus) 1637*0Sstevel@tonic-gate return; 1638*0Sstevel@tonic-gate 1639*0Sstevel@tonic-gate /* 1640*0Sstevel@tonic-gate * If we're here, we know that the odata is a CPU which has been 1641*0Sstevel@tonic-gate * DR'd out. We'll now smoosh it out of the old data. 1642*0Sstevel@tonic-gate */ 1643*0Sstevel@tonic-gate for (odata->tdata_cpuid = -1; i < g_max_cpus - 1; i++) { 1644*0Sstevel@tonic-gate ndata = (tstat_data_t *)((uintptr_t)odata + g_datasize); 1645*0Sstevel@tonic-gate bcopy(ndata, odata, g_datasize); 1646*0Sstevel@tonic-gate ndata->tdata_cpuid = -1; 1647*0Sstevel@tonic-gate } 1648*0Sstevel@tonic-gate 1649*0Sstevel@tonic-gate /* 1650*0Sstevel@tonic-gate * There may be other CPUs DR'd out; tail-call recurse. 1651*0Sstevel@tonic-gate */ 1652*0Sstevel@tonic-gate check_data(data, odata); 1653*0Sstevel@tonic-gate } 1654*0Sstevel@tonic-gate 1655*0Sstevel@tonic-gate int 1656*0Sstevel@tonic-gate main(int argc, char **argv) 1657*0Sstevel@tonic-gate { 1658*0Sstevel@tonic-gate processorid_t id; 1659*0Sstevel@tonic-gate char c, *end; 1660*0Sstevel@tonic-gate ulong_t indefinite; 1661*0Sstevel@tonic-gate long count = 0, rate = 0; 1662*0Sstevel@tonic-gate int list = 0, parsable = 0; 1663*0Sstevel@tonic-gate void (*print)(tstat_data_t *, tstat_data_t *); 1664*0Sstevel@tonic-gate sigset_t set; 1665*0Sstevel@tonic-gate 1666*0Sstevel@tonic-gate struct { 1667*0Sstevel@tonic-gate char opt; 1668*0Sstevel@tonic-gate void (*print)(tstat_data_t *, tstat_data_t *); 1669*0Sstevel@tonic-gate void (*parsable)(tstat_data_t *, tstat_data_t *); 1670*0Sstevel@tonic-gate int repeat; 1671*0Sstevel@tonic-gate } tab[] = { 1672*0Sstevel@tonic-gate { '\0', print_stats, parsable_stats, 0 }, 1673*0Sstevel@tonic-gate { 'e', print_stats, parsable_stats, 1 }, 1674*0Sstevel@tonic-gate { 't', print_tlb, parsable_tlb, 0 }, 1675*0Sstevel@tonic-gate { 'T', print_tlbpgsz, parsable_tlbpgsz, 0 }, 1676*0Sstevel@tonic-gate { -1, NULL, NULL, 0 } 1677*0Sstevel@tonic-gate }, *tabent = NULL, *iter; 1678*0Sstevel@tonic-gate 1679*0Sstevel@tonic-gate uintptr_t offs = (uintptr_t)&tab->print - (uintptr_t)tab; 1680*0Sstevel@tonic-gate 1681*0Sstevel@tonic-gate /* 1682*0Sstevel@tonic-gate * If argv[0] is non-NULL, set argv[0] to keep any getopt(3C) output 1683*0Sstevel@tonic-gate * consistent with other error output. 1684*0Sstevel@tonic-gate */ 1685*0Sstevel@tonic-gate if (argv[0] != NULL) 1686*0Sstevel@tonic-gate argv[0] = TSTAT_COMMAND; 1687*0Sstevel@tonic-gate 1688*0Sstevel@tonic-gate if ((g_fd = open(TSTAT_DEVICE, O_RDWR)) == -1) 1689*0Sstevel@tonic-gate fatal("couldn't open " TSTAT_DEVICE); 1690*0Sstevel@tonic-gate 1691*0Sstevel@tonic-gate setup(); 1692*0Sstevel@tonic-gate 1693*0Sstevel@tonic-gate while ((c = getopt(argc, argv, "alnNtTc:C:r:e:P")) != EOF) { 1694*0Sstevel@tonic-gate /* 1695*0Sstevel@tonic-gate * First, check to see if this option changes our printing 1696*0Sstevel@tonic-gate * function. 1697*0Sstevel@tonic-gate */ 1698*0Sstevel@tonic-gate for (iter = tab; iter->opt >= 0; iter++) { 1699*0Sstevel@tonic-gate if (c != iter->opt) 1700*0Sstevel@tonic-gate continue; 1701*0Sstevel@tonic-gate 1702*0Sstevel@tonic-gate if (tabent != NULL) { 1703*0Sstevel@tonic-gate if (tabent == iter) { 1704*0Sstevel@tonic-gate if (tabent->repeat) { 1705*0Sstevel@tonic-gate /* 1706*0Sstevel@tonic-gate * This option is allowed to 1707*0Sstevel@tonic-gate * have repeats; break out. 1708*0Sstevel@tonic-gate */ 1709*0Sstevel@tonic-gate break; 1710*0Sstevel@tonic-gate } 1711*0Sstevel@tonic-gate 1712*0Sstevel@tonic-gate fatal("expected -%c at most once\n", c); 1713*0Sstevel@tonic-gate } 1714*0Sstevel@tonic-gate 1715*0Sstevel@tonic-gate fatal("only one of -%c, -%c expected\n", 1716*0Sstevel@tonic-gate tabent->opt, c); 1717*0Sstevel@tonic-gate } 1718*0Sstevel@tonic-gate 1719*0Sstevel@tonic-gate tabent = iter; 1720*0Sstevel@tonic-gate break; 1721*0Sstevel@tonic-gate } 1722*0Sstevel@tonic-gate 1723*0Sstevel@tonic-gate switch (c) { 1724*0Sstevel@tonic-gate case 'a': 1725*0Sstevel@tonic-gate g_absolute = 1; 1726*0Sstevel@tonic-gate break; 1727*0Sstevel@tonic-gate 1728*0Sstevel@tonic-gate case 'e': { 1729*0Sstevel@tonic-gate char *s = strtok(optarg, ","); 1730*0Sstevel@tonic-gate 1731*0Sstevel@tonic-gate while (s != NULL) { 1732*0Sstevel@tonic-gate select_entry(s); 1733*0Sstevel@tonic-gate s = strtok(NULL, ","); 1734*0Sstevel@tonic-gate } 1735*0Sstevel@tonic-gate 1736*0Sstevel@tonic-gate break; 1737*0Sstevel@tonic-gate } 1738*0Sstevel@tonic-gate 1739*0Sstevel@tonic-gate case 'l': 1740*0Sstevel@tonic-gate list = 1; 1741*0Sstevel@tonic-gate break; 1742*0Sstevel@tonic-gate 1743*0Sstevel@tonic-gate case 'n': 1744*0Sstevel@tonic-gate /* 1745*0Sstevel@tonic-gate * This undocumented option prevents trapstat from 1746*0Sstevel@tonic-gate * actually switching the %tba to point to the 1747*0Sstevel@tonic-gate * interposing trap table. It's very useful when 1748*0Sstevel@tonic-gate * debugging trapstat bugs: one can specify "-n" 1749*0Sstevel@tonic-gate * and then examine the would-be interposing trap 1750*0Sstevel@tonic-gate * table without running the risk of RED stating. 1751*0Sstevel@tonic-gate */ 1752*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_NOGO) == -1) 1753*0Sstevel@tonic-gate fatal("TSTATIOC_NOGO"); 1754*0Sstevel@tonic-gate break; 1755*0Sstevel@tonic-gate 1756*0Sstevel@tonic-gate case 'N': 1757*0Sstevel@tonic-gate /* 1758*0Sstevel@tonic-gate * This undocumented option forces trapstat to ignore 1759*0Sstevel@tonic-gate * its determined probe effect. This may be useful 1760*0Sstevel@tonic-gate * if it is believed that the probe effect has been 1761*0Sstevel@tonic-gate * grossly overestimated. 1762*0Sstevel@tonic-gate */ 1763*0Sstevel@tonic-gate g_peffect = 0; 1764*0Sstevel@tonic-gate break; 1765*0Sstevel@tonic-gate 1766*0Sstevel@tonic-gate case 't': 1767*0Sstevel@tonic-gate case 'T': 1768*0Sstevel@tonic-gate /* 1769*0Sstevel@tonic-gate * When running with TLB statistics, we want to 1770*0Sstevel@tonic-gate * minimize probe effect by running with all other 1771*0Sstevel@tonic-gate * entries explicitly disabled. 1772*0Sstevel@tonic-gate */ 1773*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_NOENTRY) == -1) 1774*0Sstevel@tonic-gate fatal("TSTATIOC_NOENTRY"); 1775*0Sstevel@tonic-gate 1776*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_TLBDATA) == -1) 1777*0Sstevel@tonic-gate fatal("TSTATIOC_TLBDATA"); 1778*0Sstevel@tonic-gate break; 1779*0Sstevel@tonic-gate 1780*0Sstevel@tonic-gate case 'c': { 1781*0Sstevel@tonic-gate /* 1782*0Sstevel@tonic-gate * We allow CPUs to be specified as an optionally 1783*0Sstevel@tonic-gate * comma separated list of either CPU IDs or ranges 1784*0Sstevel@tonic-gate * of CPU IDs. 1785*0Sstevel@tonic-gate */ 1786*0Sstevel@tonic-gate char *s = strtok(optarg, ","); 1787*0Sstevel@tonic-gate 1788*0Sstevel@tonic-gate while (s != NULL) { 1789*0Sstevel@tonic-gate id = strtoul(s, &end, 0); 1790*0Sstevel@tonic-gate 1791*0Sstevel@tonic-gate if (id == ULONG_MAX && errno == ERANGE) { 1792*0Sstevel@tonic-gate *end = '\0'; 1793*0Sstevel@tonic-gate fatal("invalid cpu '%s'\n", s); 1794*0Sstevel@tonic-gate } 1795*0Sstevel@tonic-gate 1796*0Sstevel@tonic-gate if (*(s = end) != '\0') { 1797*0Sstevel@tonic-gate processorid_t p; 1798*0Sstevel@tonic-gate 1799*0Sstevel@tonic-gate if (*s != '-') 1800*0Sstevel@tonic-gate fatal("invalid cpu '%s'\n", s); 1801*0Sstevel@tonic-gate p = strtoul(++s, &end, 0); 1802*0Sstevel@tonic-gate 1803*0Sstevel@tonic-gate if (*end != '\0' || 1804*0Sstevel@tonic-gate (p == ULONG_MAX && errno == ERANGE)) 1805*0Sstevel@tonic-gate fatal("invalid cpu '%s'\n", s); 1806*0Sstevel@tonic-gate 1807*0Sstevel@tonic-gate select_cpus(id, p); 1808*0Sstevel@tonic-gate } else { 1809*0Sstevel@tonic-gate select_cpu(id); 1810*0Sstevel@tonic-gate } 1811*0Sstevel@tonic-gate 1812*0Sstevel@tonic-gate s = strtok(NULL, ","); 1813*0Sstevel@tonic-gate } 1814*0Sstevel@tonic-gate 1815*0Sstevel@tonic-gate break; 1816*0Sstevel@tonic-gate } 1817*0Sstevel@tonic-gate 1818*0Sstevel@tonic-gate case 'C': { 1819*0Sstevel@tonic-gate psetid_t pset = strtoul(optarg, &end, 0); 1820*0Sstevel@tonic-gate 1821*0Sstevel@tonic-gate if (*end != '\0' || 1822*0Sstevel@tonic-gate (pset == ULONG_MAX && errno == ERANGE)) 1823*0Sstevel@tonic-gate fatal("invalid processor set '%s'\n", optarg); 1824*0Sstevel@tonic-gate 1825*0Sstevel@tonic-gate select_pset(pset); 1826*0Sstevel@tonic-gate break; 1827*0Sstevel@tonic-gate } 1828*0Sstevel@tonic-gate 1829*0Sstevel@tonic-gate case 'r': { 1830*0Sstevel@tonic-gate rate = strtol(optarg, &end, 0); 1831*0Sstevel@tonic-gate 1832*0Sstevel@tonic-gate if (*end != '\0' || 1833*0Sstevel@tonic-gate (rate == LONG_MAX && errno == ERANGE)) 1834*0Sstevel@tonic-gate fatal("invalid rate '%s'\n", optarg); 1835*0Sstevel@tonic-gate 1836*0Sstevel@tonic-gate if (rate <= 0) 1837*0Sstevel@tonic-gate fatal("rate must be greater than zero\n"); 1838*0Sstevel@tonic-gate 1839*0Sstevel@tonic-gate if (rate > TSTAT_MAX_RATE) 1840*0Sstevel@tonic-gate fatal("rate may not exceed %d\n", 1841*0Sstevel@tonic-gate TSTAT_MAX_RATE); 1842*0Sstevel@tonic-gate 1843*0Sstevel@tonic-gate set_interval(NANOSEC / rate); 1844*0Sstevel@tonic-gate break; 1845*0Sstevel@tonic-gate } 1846*0Sstevel@tonic-gate 1847*0Sstevel@tonic-gate case 'P': 1848*0Sstevel@tonic-gate offs = (uintptr_t)&tab->parsable - (uintptr_t)tab; 1849*0Sstevel@tonic-gate parsable = 1; 1850*0Sstevel@tonic-gate break; 1851*0Sstevel@tonic-gate 1852*0Sstevel@tonic-gate default: 1853*0Sstevel@tonic-gate usage(); 1854*0Sstevel@tonic-gate } 1855*0Sstevel@tonic-gate } 1856*0Sstevel@tonic-gate 1857*0Sstevel@tonic-gate if (list) { 1858*0Sstevel@tonic-gate print_entries(stdout, parsable); 1859*0Sstevel@tonic-gate exit(EXIT_SUCCESS); 1860*0Sstevel@tonic-gate } 1861*0Sstevel@tonic-gate 1862*0Sstevel@tonic-gate if (optind != argc) { 1863*0Sstevel@tonic-gate 1864*0Sstevel@tonic-gate int interval = strtol(argv[optind], &end, 0); 1865*0Sstevel@tonic-gate 1866*0Sstevel@tonic-gate if (*end != '\0') { 1867*0Sstevel@tonic-gate /* 1868*0Sstevel@tonic-gate * That wasn't a valid number. It must be that we're 1869*0Sstevel@tonic-gate * to execute this command. 1870*0Sstevel@tonic-gate */ 1871*0Sstevel@tonic-gate switch (vfork()) { 1872*0Sstevel@tonic-gate case 0: 1873*0Sstevel@tonic-gate (void) close(g_fd); 1874*0Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &g_oset, NULL); 1875*0Sstevel@tonic-gate (void) execvp(argv[optind], &argv[optind]); 1876*0Sstevel@tonic-gate 1877*0Sstevel@tonic-gate /* 1878*0Sstevel@tonic-gate * No luck. Set errno. 1879*0Sstevel@tonic-gate */ 1880*0Sstevel@tonic-gate g_exec_errno = errno; 1881*0Sstevel@tonic-gate _exit(EXIT_FAILURE); 1882*0Sstevel@tonic-gate /*NOTREACHED*/ 1883*0Sstevel@tonic-gate case -1: 1884*0Sstevel@tonic-gate fatal("cannot fork"); 1885*0Sstevel@tonic-gate /*NOTREACHED*/ 1886*0Sstevel@tonic-gate default: 1887*0Sstevel@tonic-gate break; 1888*0Sstevel@tonic-gate } 1889*0Sstevel@tonic-gate } else { 1890*0Sstevel@tonic-gate if (interval <= 0) 1891*0Sstevel@tonic-gate fatal("interval must be greater than zero.\n"); 1892*0Sstevel@tonic-gate 1893*0Sstevel@tonic-gate if (interval == LONG_MAX && errno == ERANGE) 1894*0Sstevel@tonic-gate fatal("invalid interval '%s'\n", argv[optind]); 1895*0Sstevel@tonic-gate 1896*0Sstevel@tonic-gate set_interval(NANOSEC * (hrtime_t)interval); 1897*0Sstevel@tonic-gate 1898*0Sstevel@tonic-gate if (++optind != argc) { 1899*0Sstevel@tonic-gate char *s = argv[optind]; 1900*0Sstevel@tonic-gate 1901*0Sstevel@tonic-gate count = strtol(s, &end, 0); 1902*0Sstevel@tonic-gate 1903*0Sstevel@tonic-gate if (*end != '\0' || count <= 0 || 1904*0Sstevel@tonic-gate (count == LONG_MAX && errno == ERANGE)) 1905*0Sstevel@tonic-gate fatal("invalid count '%s'\n", s); 1906*0Sstevel@tonic-gate } 1907*0Sstevel@tonic-gate } 1908*0Sstevel@tonic-gate } else { 1909*0Sstevel@tonic-gate if (!rate) 1910*0Sstevel@tonic-gate set_interval(NANOSEC); 1911*0Sstevel@tonic-gate } 1912*0Sstevel@tonic-gate 1913*0Sstevel@tonic-gate if (tabent == NULL) 1914*0Sstevel@tonic-gate tabent = tab; 1915*0Sstevel@tonic-gate 1916*0Sstevel@tonic-gate print = *(void(**)(tstat_data_t *, tstat_data_t *)) 1917*0Sstevel@tonic-gate ((uintptr_t)tabent + offs); 1918*0Sstevel@tonic-gate 1919*0Sstevel@tonic-gate for (id = 0; id < g_max_cpus; id++) { 1920*0Sstevel@tonic-gate if (!g_selected[id]) 1921*0Sstevel@tonic-gate continue; 1922*0Sstevel@tonic-gate 1923*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_CPU, id) == -1) 1924*0Sstevel@tonic-gate fatal("TSTATIOC_CPU failed for cpu %d", id); 1925*0Sstevel@tonic-gate } 1926*0Sstevel@tonic-gate 1927*0Sstevel@tonic-gate g_start = gethrtime(); 1928*0Sstevel@tonic-gate 1929*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_GO) == -1) 1930*0Sstevel@tonic-gate fatal("TSTATIOC_GO failed"); 1931*0Sstevel@tonic-gate 1932*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_READ, g_data[g_gen ^ 1]) == -1) 1933*0Sstevel@tonic-gate fatal("initial TSTATIOC_READ failed"); 1934*0Sstevel@tonic-gate 1935*0Sstevel@tonic-gate (void) sigemptyset(&set); 1936*0Sstevel@tonic-gate 1937*0Sstevel@tonic-gate for (indefinite = (count == 0); indefinite || count; count--) { 1938*0Sstevel@tonic-gate 1939*0Sstevel@tonic-gate (void) sigsuspend(&set); 1940*0Sstevel@tonic-gate 1941*0Sstevel@tonic-gate if (g_winch) { 1942*0Sstevel@tonic-gate g_winch = 0; 1943*0Sstevel@tonic-gate continue; 1944*0Sstevel@tonic-gate } 1945*0Sstevel@tonic-gate 1946*0Sstevel@tonic-gate if (g_child_exited && g_exec_errno != 0) { 1947*0Sstevel@tonic-gate errno = g_exec_errno; 1948*0Sstevel@tonic-gate fatal("could not execute %s", argv[optind]); 1949*0Sstevel@tonic-gate } 1950*0Sstevel@tonic-gate 1951*0Sstevel@tonic-gate if (ioctl(g_fd, TSTATIOC_READ, g_data[g_gen]) == -1) 1952*0Sstevel@tonic-gate fatal("TSTATIOC_READ failed"); 1953*0Sstevel@tonic-gate 1954*0Sstevel@tonic-gate /* 1955*0Sstevel@tonic-gate * Before we blithely print the data, we need to 1956*0Sstevel@tonic-gate * make sure that we haven't lost a CPU. 1957*0Sstevel@tonic-gate */ 1958*0Sstevel@tonic-gate check_data(g_data[g_gen], g_data[g_gen ^ 1]); 1959*0Sstevel@tonic-gate (*print)(g_data[g_gen], g_data[g_gen ^ 1]); 1960*0Sstevel@tonic-gate (void) fflush(stdout); 1961*0Sstevel@tonic-gate 1962*0Sstevel@tonic-gate if (g_child_exited) { 1963*0Sstevel@tonic-gate if (WIFEXITED(g_child_status)) { 1964*0Sstevel@tonic-gate if (WEXITSTATUS(g_child_status) == 0) 1965*0Sstevel@tonic-gate break; 1966*0Sstevel@tonic-gate 1967*0Sstevel@tonic-gate (void) fprintf(stderr, TSTAT_COMMAND ": " 1968*0Sstevel@tonic-gate "warning: %s exited with code %d\n", 1969*0Sstevel@tonic-gate argv[optind], WEXITSTATUS(g_child_status)); 1970*0Sstevel@tonic-gate } else { 1971*0Sstevel@tonic-gate (void) fprintf(stderr, TSTAT_COMMAND ": " 1972*0Sstevel@tonic-gate "warning: %s died on signal %d\n", 1973*0Sstevel@tonic-gate argv[optind], WTERMSIG(g_child_status)); 1974*0Sstevel@tonic-gate } 1975*0Sstevel@tonic-gate break; 1976*0Sstevel@tonic-gate } 1977*0Sstevel@tonic-gate 1978*0Sstevel@tonic-gate check_pset(); 1979*0Sstevel@tonic-gate 1980*0Sstevel@tonic-gate g_gen ^= 1; 1981*0Sstevel@tonic-gate } 1982*0Sstevel@tonic-gate 1983*0Sstevel@tonic-gate return (0); 1984*0Sstevel@tonic-gate } 1985