1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 2723 cth * Common Development and Distribution License (the "License"). 6 2723 cth * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 9123 john * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #include <sys/pset.h> 27 0 stevel #include <sys/types.h> 28 0 stevel #include <sys/time.h> 29 0 stevel #include <sys/sysinfo.h> 30 0 stevel 31 0 stevel #include <assert.h> 32 0 stevel #include <stdio.h> 33 0 stevel #include <stdlib.h> 34 0 stevel #include <stdarg.h> 35 0 stevel #include <ctype.h> 36 0 stevel #include <unistd.h> 37 0 stevel #include <memory.h> 38 0 stevel #include <string.h> 39 0 stevel #include <strings.h> 40 0 stevel #include <fcntl.h> 41 0 stevel #include <errno.h> 42 0 stevel #include <kstat.h> 43 0 stevel #include <poll.h> 44 5461 tc35445 #include <signal.h> 45 9123 john #include <locale.h> 46 0 stevel 47 0 stevel #include "statcommon.h" 48 0 stevel 49 0 stevel #define SNAP(s, i, l, n) ((s) ? agg_proc_snap(s, i, l, n) : 0) 50 0 stevel 51 0 stevel #define REPRINT 20 52 0 stevel 53 5461 tc35445 char *cmdname = "mpstat"; 54 5461 tc35445 int caught_cont = 0; 55 9123 john 56 10265 Krishnendu static uint_t timestamp_fmt = NODATE; 57 0 stevel 58 0 stevel static int hz; 59 0 stevel static int display_pset = -1; 60 0 stevel static int show_set = 0; 61 0 stevel static int suppress_state; 62 0 stevel 63 0 stevel static void print_header(int, int); 64 0 stevel static void show_cpu_usage(struct snapshot *, struct snapshot *, int); 65 0 stevel static void usage(void); 66 0 stevel 67 0 stevel int 68 0 stevel main(int argc, char **argv) 69 0 stevel { 70 0 stevel int c; 71 0 stevel int display_agg = 0; 72 0 stevel int iter = 1; 73 0 stevel int interval = 0; 74 0 stevel char *endptr; 75 0 stevel int infinite_cycles = 0; 76 0 stevel kstat_ctl_t *kc; 77 0 stevel struct snapshot *old = NULL; 78 0 stevel struct snapshot *new = NULL; 79 0 stevel enum snapshot_types types = SNAP_CPUS; 80 5461 tc35445 hrtime_t start_n; 81 5461 tc35445 hrtime_t period_n; 82 0 stevel 83 9123 john (void) setlocale(LC_ALL, ""); 84 9123 john #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 85 9123 john #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 86 9123 john #endif 87 9123 john (void) textdomain(TEXT_DOMAIN); 88 9123 john 89 9123 john while ((c = getopt(argc, argv, "apP:qT:")) != (int)EOF) 90 0 stevel switch (c) { 91 0 stevel case 'a': 92 0 stevel /* 93 0 stevel * Display aggregate data for processor sets. 94 0 stevel */ 95 0 stevel display_agg = 1; 96 0 stevel break; 97 0 stevel case 'p': 98 0 stevel /* 99 0 stevel * Display all processor sets. 100 0 stevel */ 101 0 stevel if (display_pset != -1) 102 0 stevel usage(); 103 0 stevel show_set = 1; 104 0 stevel break; 105 0 stevel case 'P': 106 0 stevel /* 107 0 stevel * Display specific processor set. 108 0 stevel */ 109 0 stevel if (show_set == 1) 110 0 stevel usage(); 111 0 stevel display_pset = (int)strtol 112 0 stevel (optarg, &endptr, 10); 113 0 stevel if (*endptr != NULL) 114 0 stevel usage(); 115 0 stevel /* 116 0 stevel * Not valid to specify a negative processor 117 0 stevel * set value. 118 0 stevel */ 119 0 stevel if (display_pset < 0) 120 0 stevel usage(); 121 0 stevel break; 122 0 stevel case 'q': 123 0 stevel suppress_state = 1; 124 9123 john break; 125 9123 john case 'T': 126 9123 john if (optarg) { 127 9123 john if (*optarg == 'u') 128 9123 john timestamp_fmt = UDATE; 129 9123 john else if (*optarg == 'd') 130 9123 john timestamp_fmt = DDATE; 131 9123 john else 132 9123 john usage(); 133 9123 john } else { 134 9123 john usage(); 135 9123 john } 136 0 stevel break; 137 0 stevel case '?': 138 0 stevel usage(); 139 0 stevel break; 140 0 stevel } 141 0 stevel 142 0 stevel hz = sysconf(_SC_CLK_TCK); 143 0 stevel 144 0 stevel if (argc > optind) { 145 0 stevel interval = (int)strtol(argv[optind], &endptr, 10); 146 0 stevel if (*endptr != NULL) 147 0 stevel usage(); 148 5461 tc35445 period_n = (hrtime_t)interval * NANOSEC; 149 0 stevel if (argc > optind + 1) { 150 0 stevel iter = (unsigned int)strtoul 151 0 stevel (argv[optind + 1], &endptr, 10); 152 0 stevel if (*endptr != NULL || iter < 0) 153 0 stevel usage(); 154 0 stevel if (iter == 0) 155 0 stevel return (0); 156 0 stevel } else { 157 0 stevel infinite_cycles = 1; 158 0 stevel } 159 0 stevel } 160 0 stevel 161 0 stevel if (display_agg || show_set || display_pset != -1) 162 0 stevel types |= SNAP_PSETS; 163 0 stevel 164 0 stevel kc = open_kstat(); 165 5461 tc35445 166 5461 tc35445 /* Set up handler for SIGCONT */ 167 5461 tc35445 if (signal(SIGCONT, cont_handler) == SIG_ERR) 168 5461 tc35445 fail(1, "signal failed"); 169 5461 tc35445 170 5461 tc35445 start_n = gethrtime(); 171 0 stevel 172 0 stevel while (infinite_cycles || iter > 0) { 173 0 stevel free_snapshot(old); 174 0 stevel old = new; 175 0 stevel new = acquire_snapshot(kc, types, NULL); 176 0 stevel 177 0 stevel if (!suppress_state) 178 0 stevel snapshot_report_changes(old, new); 179 0 stevel 180 0 stevel /* if config changed, show stats from boot */ 181 0 stevel if (snapshot_has_changed(old, new)) { 182 0 stevel free_snapshot(old); 183 0 stevel old = NULL; 184 0 stevel } 185 0 stevel 186 0 stevel show_cpu_usage(old, new, display_agg); 187 0 stevel 188 0 stevel if (!infinite_cycles && --iter < 1) 189 0 stevel break; 190 0 stevel 191 5461 tc35445 /* Have a kip */ 192 5461 tc35445 sleep_until(&start_n, period_n, infinite_cycles, &caught_cont); 193 0 stevel } 194 2723 cth (void) kstat_close(kc); 195 2723 cth 196 0 stevel return (0); 197 0 stevel } 198 0 stevel 199 0 stevel /* 200 0 stevel * Print an mpstat output header. 201 0 stevel */ 202 0 stevel static void 203 0 stevel print_header(int display_agg, int show_set) 204 0 stevel { 205 0 stevel if (display_agg == 1) 206 0 stevel (void) printf("SET minf mjf xcal intr ithr csw icsw migr " 207 0 stevel "smtx srw syscl usr sys wt idl sze"); 208 0 stevel else { 209 0 stevel (void) printf("CPU minf mjf xcal intr ithr csw icsw migr " 210 0 stevel "smtx srw syscl usr sys wt idl"); 211 0 stevel if (show_set == 1) 212 0 stevel (void) printf(" set"); 213 0 stevel } 214 0 stevel (void) printf("\n"); 215 0 stevel } 216 0 stevel 217 0 stevel static void 218 0 stevel print_cpu(struct cpu_snapshot *c1, struct cpu_snapshot *c2) 219 0 stevel { 220 0 stevel uint64_t ticks = 0; 221 0 stevel double etime, percent; 222 0 stevel kstat_t *old_vm = NULL; 223 0 stevel kstat_t *old_sys = NULL; 224 0 stevel 225 0 stevel if (display_pset != -1 && display_pset != c2->cs_pset_id) 226 0 stevel return; 227 0 stevel 228 0 stevel /* 229 0 stevel * the first mpstat output will have c1 = NULL, to give 230 0 stevel * results since boot 231 0 stevel */ 232 0 stevel if (c1) { 233 0 stevel old_vm = &c1->cs_vm; 234 0 stevel old_sys = &c1->cs_sys; 235 0 stevel 236 0 stevel /* check there are stats to report */ 237 0 stevel if (!CPU_ACTIVE(c1)) 238 0 stevel return; 239 0 stevel } 240 0 stevel 241 0 stevel /* check there are stats to report */ 242 0 stevel if (!CPU_ACTIVE(c2)) 243 0 stevel return; 244 0 stevel 245 0 stevel ticks = cpu_ticks_delta(old_sys, &c2->cs_sys); 246 0 stevel 247 0 stevel etime = (double)ticks / hz; 248 0 stevel if (etime == 0.0) /* Prevent divide by zero errors */ 249 0 stevel etime = 1.0; 250 0 stevel percent = 100.0 / etime / hz; 251 0 stevel 252 0 stevel (void) printf("%3d %4.0f %3.0f %4.0f %5.0f %4.0f " 253 9123 john "%4.0f %4.0f %4.0f %4.0f %4.0f %5.0f %3.0f %3.0f " 254 9123 john "%3.0f %3.0f", 255 9123 john c2->cs_id, 256 9123 john (kstat_delta(old_vm, &c2->cs_vm, "hat_fault") + 257 9123 john kstat_delta(old_vm, &c2->cs_vm, "as_fault")) / etime, 258 9123 john kstat_delta(old_vm, &c2->cs_vm, "maj_fault") / etime, 259 9123 john kstat_delta(old_sys, &c2->cs_sys, "xcalls") / etime, 260 9123 john kstat_delta(old_sys, &c2->cs_sys, "intr") / etime, 261 9123 john kstat_delta(old_sys, &c2->cs_sys, "intrthread") / etime, 262 9123 john kstat_delta(old_sys, &c2->cs_sys, "pswitch") / etime, 263 9123 john kstat_delta(old_sys, &c2->cs_sys, "inv_swtch") / etime, 264 9123 john kstat_delta(old_sys, &c2->cs_sys, "cpumigrate") / etime, 265 9123 john kstat_delta(old_sys, &c2->cs_sys, "mutex_adenters") / etime, 266 9123 john (kstat_delta(old_sys, &c2->cs_sys, "rw_rdfails") + 267 9123 john kstat_delta(old_sys, &c2->cs_sys, "rw_wrfails")) / etime, 268 9123 john kstat_delta(old_sys, &c2->cs_sys, "syscall") / etime, 269 9123 john kstat_delta(old_sys, &c2->cs_sys, "cpu_ticks_user") * percent, 270 9123 john kstat_delta(old_sys, &c2->cs_sys, "cpu_ticks_kernel") * percent, 271 9123 john kstat_delta(old_sys, &c2->cs_sys, "cpu_ticks_wait") * percent, 272 9123 john kstat_delta(old_sys, &c2->cs_sys, "cpu_ticks_idle") * percent); 273 0 stevel 274 0 stevel if (show_set) 275 0 stevel (void) printf(" %3d", c2->cs_pset_id); 276 0 stevel (void) printf("\n"); 277 0 stevel } 278 0 stevel 279 0 stevel /*ARGSUSED*/ 280 0 stevel static void 281 0 stevel compare_cpu(void *v1, void *v2, void *data) 282 0 stevel { 283 0 stevel struct cpu_snapshot *c1 = (struct cpu_snapshot *)v1; 284 0 stevel struct cpu_snapshot *c2 = (struct cpu_snapshot *)v2; 285 0 stevel 286 0 stevel if (c2 == NULL) 287 0 stevel return; 288 0 stevel 289 0 stevel print_cpu(c1, c2); 290 0 stevel } 291 0 stevel 292 0 stevel static int 293 0 stevel pset_has_stats(struct pset_snapshot *p) 294 0 stevel { 295 0 stevel int count = 0; 296 0 stevel size_t i; 297 0 stevel for (i = 0; i < p->ps_nr_cpus; i++) { 298 0 stevel if (CPU_ACTIVE(p->ps_cpus[i])) 299 0 stevel count++; 300 0 stevel } 301 0 stevel return (count); 302 0 stevel } 303 0 stevel 304 0 stevel static void 305 0 stevel agg_stat(kstat_t *k1, kstat_t *k2, char *name) 306 0 stevel { 307 0 stevel kstat_named_t *ksn = kstat_data_lookup(k1, name); 308 0 stevel kstat_named_t *ksn2 = kstat_data_lookup(k2, name); 309 0 stevel ksn->value.ui64 += ksn2->value.ui64; 310 0 stevel } 311 0 stevel 312 0 stevel static kstat_t * 313 0 stevel agg_vm(struct pset_snapshot *p, kstat_t *ks) 314 0 stevel { 315 0 stevel size_t i; 316 0 stevel 317 0 stevel if (p->ps_nr_cpus == NULL) 318 0 stevel return (NULL); 319 0 stevel 320 0 stevel if (kstat_copy(&p->ps_cpus[0]->cs_vm, ks)) 321 0 stevel return (NULL); 322 0 stevel 323 0 stevel for (i = 1; i < p->ps_nr_cpus; i++) { 324 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_vm, "hat_fault"); 325 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_vm, "as_fault"); 326 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_vm, "maj_fault"); 327 0 stevel } 328 0 stevel 329 0 stevel return (ks); 330 0 stevel } 331 0 stevel 332 0 stevel static kstat_t * 333 0 stevel agg_sys(struct pset_snapshot *p, kstat_t *ks) 334 0 stevel { 335 0 stevel size_t i; 336 0 stevel 337 0 stevel if (p->ps_nr_cpus == NULL) 338 0 stevel return (NULL); 339 0 stevel 340 0 stevel if (kstat_copy(&p->ps_cpus[0]->cs_sys, ks)) 341 0 stevel return (NULL); 342 0 stevel 343 0 stevel for (i = 1; i < p->ps_nr_cpus; i++) { 344 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "xcalls"); 345 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "intr"); 346 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "intrthread"); 347 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "pswitch"); 348 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "inv_swtch"); 349 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "cpumigrate"); 350 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "mutex_adenters"); 351 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "rw_rdfails"); 352 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "rw_wrfails"); 353 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "syscall"); 354 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "cpu_ticks_user"); 355 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "cpu_ticks_kernel"); 356 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "cpu_ticks_wait"); 357 0 stevel agg_stat(ks, &p->ps_cpus[i]->cs_sys, "cpu_ticks_idle"); 358 0 stevel } 359 0 stevel 360 0 stevel return (ks); 361 0 stevel } 362 0 stevel 363 0 stevel static uint64_t 364 0 stevel get_nr_ticks(struct pset_snapshot *p1, struct pset_snapshot *p2) 365 0 stevel { 366 0 stevel kstat_t *old = NULL; 367 0 stevel kstat_t *new = NULL; 368 0 stevel size_t i = 0; 369 0 stevel 370 0 stevel for (i = 0; p1 && i < p1->ps_nr_cpus; i++) { 371 0 stevel if (p1->ps_cpus[i]->cs_sys.ks_data) { 372 0 stevel old = &p1->ps_cpus[i]->cs_sys; 373 0 stevel break; 374 0 stevel } 375 0 stevel } 376 0 stevel 377 0 stevel for (i = 0; p2 && i < p2->ps_nr_cpus; i++) { 378 0 stevel if (p2->ps_cpus[i]->cs_sys.ks_data) { 379 0 stevel new = &p2->ps_cpus[i]->cs_sys; 380 0 stevel break; 381 0 stevel } 382 0 stevel } 383 0 stevel 384 0 stevel if (old == NULL && new == NULL) 385 0 stevel return (0); 386 0 stevel 387 0 stevel if (new == NULL) { 388 0 stevel new = old; 389 0 stevel old = NULL; 390 0 stevel } 391 0 stevel 392 0 stevel return (cpu_ticks_delta(old, new)); 393 0 stevel } 394 0 stevel 395 0 stevel static void 396 0 stevel print_pset(struct pset_snapshot *p1, struct pset_snapshot *p2) 397 0 stevel { 398 0 stevel uint64_t ticks = 0; 399 0 stevel double etime, percent; 400 0 stevel kstat_t old_vm; 401 0 stevel kstat_t old_sys; 402 0 stevel kstat_t new_vm; 403 0 stevel kstat_t new_sys; 404 0 stevel 405 0 stevel if (display_pset != -1 && display_pset != p2->ps_id) 406 0 stevel return; 407 0 stevel 408 0 stevel if ((p1 && !pset_has_stats(p1)) || !pset_has_stats(p2)) 409 0 stevel return; 410 0 stevel 411 0 stevel old_vm.ks_data = old_sys.ks_data = NULL; 412 0 stevel new_vm.ks_data = new_sys.ks_data = NULL; 413 0 stevel 414 0 stevel /* 415 0 stevel * FIXME: these aggs will count "new" or disappeared cpus 416 0 stevel * in a set, leaving an apparent huge change. 417 0 stevel */ 418 0 stevel 419 0 stevel /* 420 0 stevel * the first mpstat output will have p1 = NULL, to give 421 0 stevel * results since boot 422 0 stevel */ 423 0 stevel if (p1) { 424 0 stevel if (!agg_vm(p1, &old_vm) || !agg_sys(p1, &old_sys)) 425 0 stevel goto out; 426 0 stevel } 427 0 stevel 428 0 stevel if (!agg_vm(p2, &new_vm) || !agg_sys(p2, &new_sys)) 429 0 stevel goto out; 430 0 stevel 431 0 stevel ticks = get_nr_ticks(p1, p2); 432 0 stevel 433 0 stevel etime = (double)ticks / hz; 434 0 stevel if (etime == 0.0) /* Prevent divide by zero errors */ 435 0 stevel etime = 1.0; 436 0 stevel percent = 100.0 / p2->ps_nr_cpus / etime / hz; 437 0 stevel 438 0 stevel (void) printf("%3d %4.0f %3.0f %4.0f %5.0f %4.0f " 439 9123 john "%4.0f %4.0f %4.0f %4.0f %4.0f %5.0f %3.0f %3.0f " 440 9123 john "%3.0f %3.0f %3d\n", 441 9123 john p2->ps_id, 442 9123 john (kstat_delta(&old_vm, &new_vm, "hat_fault") + 443 9123 john kstat_delta(&old_vm, &new_vm, "as_fault")) / etime, 444 9123 john kstat_delta(&old_vm, &new_vm, "maj_fault") / etime, 445 9123 john kstat_delta(&old_sys, &new_sys, "xcalls") / etime, 446 9123 john kstat_delta(&old_sys, &new_sys, "intr") / etime, 447 9123 john kstat_delta(&old_sys, &new_sys, "intrthread") / etime, 448 9123 john kstat_delta(&old_sys, &new_sys, "pswitch") / etime, 449 9123 john kstat_delta(&old_sys, &new_sys, "inv_swtch") / etime, 450 9123 john kstat_delta(&old_sys, &new_sys, "cpumigrate") / etime, 451 9123 john kstat_delta(&old_sys, &new_sys, "mutex_adenters") / etime, 452 9123 john (kstat_delta(&old_sys, &new_sys, "rw_rdfails") + 453 9123 john kstat_delta(&old_sys, &new_sys, "rw_wrfails")) / etime, 454 9123 john kstat_delta(&old_sys, &new_sys, "syscall") / etime, 455 9123 john kstat_delta(&old_sys, &new_sys, "cpu_ticks_user") * percent, 456 9123 john kstat_delta(&old_sys, &new_sys, "cpu_ticks_kernel") * percent, 457 9123 john kstat_delta(&old_sys, &new_sys, "cpu_ticks_wait") * percent, 458 9123 john kstat_delta(&old_sys, &new_sys, "cpu_ticks_idle") * percent, 459 9123 john p2->ps_nr_cpus); 460 0 stevel 461 0 stevel out: 462 0 stevel free(old_vm.ks_data); 463 0 stevel free(old_sys.ks_data); 464 0 stevel free(new_vm.ks_data); 465 0 stevel free(new_sys.ks_data); 466 0 stevel } 467 0 stevel 468 0 stevel /*ARGSUSED*/ 469 0 stevel static void 470 0 stevel compare_pset(void *v1, void *v2, void *data) 471 0 stevel { 472 0 stevel struct pset_snapshot *p1 = (struct pset_snapshot *)v1; 473 0 stevel struct pset_snapshot *p2 = (struct pset_snapshot *)v2; 474 0 stevel 475 0 stevel if (p2 == NULL) 476 0 stevel return; 477 0 stevel 478 0 stevel print_pset(p1, p2); 479 0 stevel } 480 0 stevel 481 0 stevel 482 0 stevel /* 483 0 stevel * Report statistics for a sample interval. 484 0 stevel */ 485 0 stevel static void 486 0 stevel show_cpu_usage(struct snapshot *old, struct snapshot *new, int display_agg) 487 0 stevel { 488 0 stevel static int lines_until_reprint = 0; 489 0 stevel enum snapshot_types type = SNAP_CPUS; 490 0 stevel snapshot_cb cb = compare_cpu; 491 9123 john 492 9123 john if (timestamp_fmt != NODATE) 493 10265 Krishnendu print_timestamp(timestamp_fmt); 494 0 stevel 495 0 stevel if (lines_until_reprint == 0 || nr_active_cpus(new) > 1) { 496 0 stevel print_header(display_agg, show_set); 497 0 stevel lines_until_reprint = REPRINT; 498 0 stevel } 499 0 stevel 500 0 stevel lines_until_reprint--; 501 0 stevel 502 0 stevel if (display_agg) { 503 0 stevel type = SNAP_PSETS; 504 0 stevel cb = compare_pset; 505 0 stevel } 506 0 stevel 507 0 stevel /* print stats since boot the first time round */ 508 0 stevel (void) snapshot_walk(type, old, new, cb, NULL); 509 0 stevel (void) fflush(stdout); 510 0 stevel } 511 0 stevel 512 0 stevel /* 513 0 stevel * Usage message on error. 514 0 stevel */ 515 0 stevel static void 516 0 stevel usage(void) 517 0 stevel { 518 0 stevel (void) fprintf(stderr, 519 9123 john "Usage: mpstat [-aq] [-p | -P processor_set] [-T d|u] " 520 9123 john "[interval [count]]\n"); 521 0 stevel exit(1); 522 0 stevel } 523