Changeset f682f5a in mainline
- Timestamp:
- 2012-04-15T07:42:52Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b8d6783
- Parents:
- 94f6df7
- Location:
- uspace/app/top
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/top/screen.c
r94f6df7 rf682f5a 290 290 } 291 291 292 static inline void print_ tasks_head(void)292 static inline void print_help_head(void) 293 293 { 294 294 screen_style_inverted(); 295 printf("[taskid] [thrds] [resident] [%%resi] [virtual] [%%virt]" 296 " [%%user] [%%kern] [name"); 295 printf("Help"); 297 296 screen_newline(); 298 297 screen_style_normal(); 299 298 } 300 299 301 static inline void print_ tasks(data_t *data)300 static inline void print_help(void) 302 301 { 303 302 sysarg_t cols; … … 305 304 screen_get_size(&cols, &rows); 306 305 306 screen_newline(); 307 308 printf("Operation modes:"); 309 screen_newline(); 310 311 printf(" t .. tasks statistics"); 312 screen_newline(); 313 314 printf(" i .. IPC statistics"); 315 screen_newline(); 316 317 printf(" e .. exceptions statistics"); 318 screen_newline(); 319 320 printf(" a .. toggle display of all/hot exceptions"); 321 screen_newline(); 322 323 printf(" h .. toggle this help screen"); 324 screen_newline(); 325 326 screen_newline(); 327 328 printf("Other keys:"); 329 screen_newline(); 330 331 printf(" q .. quit"); 332 screen_newline(); 333 307 334 sysarg_t col; 308 335 sysarg_t row; 309 336 screen_get_pos(&col, &row); 310 337 311 size_t i;312 for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {313 stats_task_t *task = data->tasks + data->tasks_map[i];314 perc_task_t *perc = data->tasks_perc + data->tasks_map[i];315 316 uint64_t resmem;317 const char *resmem_suffix;318 bin_order_suffix(task->resmem, &resmem, &resmem_suffix, true);319 320 uint64_t virtmem;321 const char *virtmem_suffix;322 bin_order_suffix(task->virtmem, &virtmem, &virtmem_suffix, true);323 324 printf("%-8" PRIu64 " %7zu %7" PRIu64 "%s ",325 task->task_id, task->threads, resmem, resmem_suffix);326 print_percent(perc->resmem, 2);327 printf(" %6" PRIu64 "%s ", virtmem, virtmem_suffix);328 print_percent(perc->virtmem, 2);329 puts(" ");330 print_percent(perc->ucycles, 2);331 puts(" ");332 print_percent(perc->kcycles, 2);333 puts(" ");334 print_string(task->name);335 336 screen_newline();337 }338 339 338 while (row < rows) { 340 339 screen_newline(); … … 343 342 } 344 343 345 static inline void print_ipc_head(void) 346 { 347 screen_style_inverted(); 348 printf("[taskid] [cls snt] [cls rcv] [ans snt]" 349 " [ans rcv] [irq rcv] [forward] [name"); 350 screen_newline(); 351 screen_style_normal(); 352 } 353 354 static inline void print_ipc(data_t *data) 344 static inline void print_table_head(const table_t *table) 355 345 { 356 346 sysarg_t cols; 357 347 sysarg_t rows; 358 348 screen_get_size(&cols, &rows); 349 350 screen_style_inverted(); 351 for (size_t i = 0; i < table->num_columns; i++) { 352 const char *name = table->columns[i].name; 353 int width = table->columns[i].width; 354 if (i != 0) { 355 puts(" "); 356 } 357 if (width == 0) { 358 sysarg_t col; 359 sysarg_t row; 360 screen_get_pos(&col, &row); 361 width = cols - col - 1; 362 } 363 printf("[%-*.*s]", width - 2, width - 2, name); 364 } 365 screen_newline(); 366 screen_style_normal(); 367 } 368 369 static inline void print_table(const table_t *table) 370 { 371 sysarg_t cols; 372 sysarg_t rows; 373 screen_get_size(&cols, &rows); 359 374 360 375 sysarg_t col; … … 363 378 364 379 size_t i; 365 for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) { 366 uint64_t call_sent; 367 uint64_t call_received; 368 uint64_t answer_sent; 369 uint64_t answer_received; 370 uint64_t irq_notif_received; 371 uint64_t forwarded; 372 373 char call_sent_suffix; 374 char call_received_suffix; 375 char answer_sent_suffix; 376 char answer_received_suffix; 377 char irq_notif_received_suffix; 378 char forwarded_suffix; 379 380 order_suffix(data->tasks[i].ipc_info.call_sent, &call_sent, 381 &call_sent_suffix); 382 order_suffix(data->tasks[i].ipc_info.call_received, 383 &call_received, &call_received_suffix); 384 order_suffix(data->tasks[i].ipc_info.answer_sent, 385 &answer_sent, &answer_sent_suffix); 386 order_suffix(data->tasks[i].ipc_info.answer_received, 387 &answer_received, &answer_received_suffix); 388 order_suffix(data->tasks[i].ipc_info.irq_notif_received, 389 &irq_notif_received, &irq_notif_received_suffix); 390 order_suffix(data->tasks[i].ipc_info.forwarded, &forwarded, 391 &forwarded_suffix); 392 393 printf("%-8" PRIu64 " %8" PRIu64 "%c %8" PRIu64 "%c" 394 " %8" PRIu64 "%c %8" PRIu64 "%c %8" PRIu64 "%c" 395 " %8" PRIu64 "%c ", data->tasks[i].task_id, 396 call_sent, call_sent_suffix, 397 call_received, call_received_suffix, 398 answer_sent, answer_sent_suffix, 399 answer_received, answer_received_suffix, 400 irq_notif_received, irq_notif_received_suffix, 401 forwarded, forwarded_suffix); 402 print_string(data->tasks[i].name); 403 404 screen_newline(); 380 for (i = 0; (i < table->num_fields) && (row < rows); i++) { 381 size_t column_index = i % table->num_columns; 382 int width = table->columns[column_index].width; 383 field_t *field = &table->fields[i]; 384 385 if (column_index != 0) { 386 puts(" "); 387 } 388 389 if (width == 0) { 390 screen_get_pos(&col, &row); 391 width = cols - col - 1; 392 } 393 394 switch (field->type) { 395 case FIELD_EMPTY: 396 printf("%*s", width, ""); 397 break; 398 case FIELD_UINT: 399 printf("%*" PRIu64, width, field->uint); 400 break; 401 case FIELD_UINT_SUFFIX_BIN: { 402 uint64_t val = field->uint; 403 const char *suffix; 404 width -= 3; 405 bin_order_suffix(val, &val, &suffix, true); 406 printf("%*" PRIu64 "%s", width, val, suffix); 407 break; 408 } 409 case FIELD_UINT_SUFFIX_DEC: { 410 uint64_t val = field->uint; 411 char suffix; 412 width -= 1; 413 order_suffix(val, &val, &suffix); 414 printf("%*" PRIu64 "%c", width, val, suffix); 415 break; 416 } 417 case FIELD_PERCENT: 418 width -= 5; /* nnn.% */ 419 if (width > 2) { 420 printf("%*s", width - 2, ""); 421 width = 2; 422 } 423 print_percent(field->fixed, width); 424 break; 425 case FIELD_STRING: 426 printf("%-*.*s", width, width, field->string); 427 break; 428 } 429 430 if (column_index == table->num_columns - 1) { 431 screen_newline(); 432 row++; 433 } 405 434 } 406 435 … … 411 440 } 412 441 413 static inline void print_excs_head(void) 414 { 415 screen_style_inverted(); 416 printf("[exc ] [count ] [%%count] [cycles ] [%%cycles] [description"); 417 screen_newline(); 418 screen_style_normal(); 419 } 420 421 static inline void print_excs(data_t *data) 422 { 423 sysarg_t cols; 424 sysarg_t rows; 425 screen_get_size(&cols, &rows); 426 427 sysarg_t col; 428 sysarg_t row; 429 screen_get_pos(&col, &row); 430 431 size_t i; 432 for (i = 0; (i < data->exceptions_count) && (row < rows); i++) { 433 /* Filter-out cold exceptions if not instructed otherwise */ 434 if ((!excs_all) && (!data->exceptions[i].hot)) 435 continue; 436 437 uint64_t count; 438 uint64_t cycles; 439 440 char count_suffix; 441 char cycles_suffix; 442 443 order_suffix(data->exceptions[i].count, &count, &count_suffix); 444 order_suffix(data->exceptions[i].cycles, &cycles, &cycles_suffix); 445 446 printf("%-8u %9" PRIu64 "%c ", 447 data->exceptions[i].id, count, count_suffix); 448 print_percent(data->exceptions_perc[i].count, 2); 449 printf(" %9" PRIu64 "%c ", cycles, cycles_suffix); 450 print_percent(data->exceptions_perc[i].cycles, 2); 451 puts(" "); 452 print_string(data->exceptions[i].desc); 453 454 screen_newline(); 455 row++; 456 } 457 458 while (row < rows) { 459 screen_newline(); 460 row++; 461 } 462 } 463 464 static inline void print_help_head(void) 465 { 466 screen_style_inverted(); 467 printf("Help"); 468 screen_newline(); 469 screen_style_normal(); 470 } 471 472 static void print_help(void) 473 { 474 sysarg_t cols; 475 sysarg_t rows; 476 screen_get_size(&cols, &rows); 477 478 screen_newline(); 479 480 printf("Operation modes:"); 481 screen_newline(); 482 483 printf(" t .. tasks statistics"); 484 screen_newline(); 485 486 printf(" i .. IPC statistics"); 487 screen_newline(); 488 489 printf(" e .. exceptions statistics"); 490 screen_newline(); 491 492 printf(" a .. toggle display of all/hot exceptions"); 493 screen_newline(); 494 495 printf(" h .. this help screen"); 496 screen_newline(); 497 498 screen_newline(); 499 500 printf("Other keys:"); 501 screen_newline(); 502 503 printf(" q .. quit"); 504 screen_newline(); 505 506 sysarg_t col; 507 sysarg_t row; 508 screen_get_pos(&col, &row); 509 510 while (row < rows) { 511 screen_newline(); 512 row++; 513 } 514 } 515 516 static void print_warning(void) 442 static inline void print_warning(void) 517 443 { 518 444 screen_get_pos(&warning_col, &warning_row); … … 538 464 print_warning(); 539 465 540 switch ( op_mode) {541 case OP_TASKS:542 print_ta sks_head();543 print_ta sks(data);466 switch (screen_mode) { 467 case SCREEN_TABLE: 468 print_table_head(&data->table); 469 print_table(&data->table); 544 470 break; 545 case OP_IPC: 546 print_ipc_head(); 547 print_ipc(data); 548 break; 549 case OP_EXCS: 550 print_excs_head(); 551 print_excs(data); 552 break; 553 case OP_HELP: 471 case SCREEN_HELP: 554 472 print_help_head(); 555 473 print_help(); -
uspace/app/top/top.c
r94f6df7 rf682f5a 55 55 #define MINUTE 60 56 56 57 op_mode_t op_mode = OP_TASKS; 57 typedef enum { 58 OP_TASKS, 59 OP_IPC, 60 OP_EXCS, 61 } op_mode_t; 62 63 screen_mode_t screen_mode = SCREEN_TABLE; 64 static op_mode_t op_mode = OP_TASKS; 58 65 sort_mode_t sort_mode = SORT_TASK_CYCLES; 59 bool excs_all = false; 66 static bool excs_all = false; 67 68 static const column_t task_columns[] = { 69 {"taskid", 't', 8}, 70 {"thrds", 'h', 7}, 71 {"resident", 'r', 10}, 72 {"%resi", 'R', 7}, 73 {"virtual", 'v', 9}, 74 {"%virt", 'V', 7}, 75 {"%user", 'U', 7}, 76 {"%kern", 'K', 7}, 77 {"name", 'd', 0}, 78 }; 79 80 enum { 81 TASK_COL_ID = 0, 82 TASK_COL_NUM_THREADS, 83 TASK_COL_RESIDENT, 84 TASK_COL_PERCENT_RESIDENT, 85 TASK_COL_VIRTUAL, 86 TASK_COL_PERCENT_VIRTUAL, 87 TASK_COL_PERCENT_USER, 88 TASK_COL_PERCENT_KERNEL, 89 TASK_COL_NAME, 90 TASK_NUM_COLUMNS, 91 }; 92 93 static const column_t ipc_columns[] = { 94 {"taskid", 't', 8}, 95 {"cls snt", 'c', 9}, 96 {"cls rcv", 'C', 9}, 97 {"ans snt", 'a', 9}, 98 {"ans rcv", 'A', 9}, 99 {"forward", 'f', 9}, 100 {"name", 'd', 0}, 101 }; 102 103 enum { 104 IPC_COL_TASKID = 0, 105 IPC_COL_CLS_SNT, 106 IPC_COL_CLS_RCV, 107 IPC_COL_ANS_SNT, 108 IPC_COL_ANS_RCV, 109 IPC_COL_FORWARD, 110 IPC_COL_NAME, 111 IPC_NUM_COLUMNS, 112 }; 113 114 static const column_t exception_columns[] = { 115 {"exc", 'e', 8}, 116 {"count", 'n', 10}, 117 {"%count", 'N', 8}, 118 {"cycles", 'c', 10}, 119 {"%cycles", 'C', 9}, 120 {"description", 'd', 0}, 121 }; 122 123 enum { 124 EXCEPTION_COL_ID = 0, 125 EXCEPTION_COL_COUNT, 126 EXCEPTION_COL_PERCENT_COUNT, 127 EXCEPTION_COL_CYCLES, 128 EXCEPTION_COL_PERCENT_CYCLES, 129 EXCEPTION_COL_DESCRIPTION, 130 EXCEPTION_NUM_COLUMNS, 131 }; 60 132 61 133 static const char *read_data(data_t *target) … … 76 148 target->ecycles_diff = NULL; 77 149 target->ecount_diff = NULL; 150 target->table.name = NULL; 151 target->table.num_columns = 0; 152 target->table.columns = NULL; 153 target->table.num_fields = 0; 154 target->table.fields = NULL; 78 155 79 156 /* Get current time */ … … 316 393 } 317 394 395 static const char *fill_task_table(data_t *data) 396 { 397 data->table.name = "Tasks"; 398 data->table.num_columns = TASK_NUM_COLUMNS; 399 data->table.columns = task_columns; 400 data->table.num_fields = data->tasks_count * TASK_NUM_COLUMNS; 401 data->table.fields = calloc(data->table.num_fields, 402 sizeof(field_t)); 403 if (data->table.fields == NULL) 404 return "Not enough memory for table fields"; 405 406 field_t *field = data->table.fields; 407 for (size_t i = 0; i < data->tasks_count; i++) { 408 stats_task_t *task = data->tasks + data->tasks_map[i]; 409 perc_task_t *perc = data->tasks_perc + data->tasks_map[i]; 410 field[TASK_COL_ID].type = FIELD_UINT; 411 field[TASK_COL_ID].uint = task->task_id; 412 field[TASK_COL_NUM_THREADS].type = FIELD_UINT; 413 field[TASK_COL_NUM_THREADS].uint = task->threads; 414 field[TASK_COL_RESIDENT].type = FIELD_UINT_SUFFIX_BIN; 415 field[TASK_COL_RESIDENT].uint = task->resmem; 416 field[TASK_COL_PERCENT_RESIDENT].type = FIELD_PERCENT; 417 field[TASK_COL_PERCENT_RESIDENT].fixed = perc->resmem; 418 field[TASK_COL_VIRTUAL].type = FIELD_UINT_SUFFIX_BIN; 419 field[TASK_COL_VIRTUAL].uint = task->virtmem; 420 field[TASK_COL_PERCENT_VIRTUAL].type = FIELD_PERCENT; 421 field[TASK_COL_PERCENT_VIRTUAL].fixed = perc->virtmem; 422 field[TASK_COL_PERCENT_USER].type = FIELD_PERCENT; 423 field[TASK_COL_PERCENT_USER].fixed = perc->ucycles; 424 field[TASK_COL_PERCENT_KERNEL].type = FIELD_PERCENT; 425 field[TASK_COL_PERCENT_KERNEL].fixed = perc->kcycles; 426 field[TASK_COL_NAME].type = FIELD_STRING; 427 field[TASK_COL_NAME].string = task->name; 428 field += TASK_NUM_COLUMNS; 429 } 430 431 return NULL; 432 } 433 434 static const char *fill_ipc_table(data_t *data) 435 { 436 data->table.name = "IPC"; 437 data->table.num_columns = IPC_NUM_COLUMNS; 438 data->table.columns = ipc_columns; 439 data->table.num_fields = data->tasks_count * IPC_NUM_COLUMNS; 440 data->table.fields = calloc(data->table.num_fields, 441 sizeof(field_t)); 442 if (data->table.fields == NULL) 443 return "Not enough memory for table fields"; 444 445 field_t *field = data->table.fields; 446 for (size_t i = 0; i < data->tasks_count; i++) { 447 field[IPC_COL_TASKID].type = FIELD_UINT; 448 field[IPC_COL_TASKID].uint = data->tasks[i].task_id; 449 field[IPC_COL_CLS_SNT].type = FIELD_UINT_SUFFIX_DEC; 450 field[IPC_COL_CLS_SNT].uint = data->tasks[i].ipc_info.call_sent; 451 field[IPC_COL_CLS_RCV].type = FIELD_UINT_SUFFIX_DEC; 452 field[IPC_COL_CLS_RCV].uint = data->tasks[i].ipc_info.call_received; 453 field[IPC_COL_ANS_SNT].type = FIELD_UINT_SUFFIX_DEC; 454 field[IPC_COL_ANS_SNT].uint = data->tasks[i].ipc_info.answer_sent; 455 field[IPC_COL_ANS_RCV].type = FIELD_UINT_SUFFIX_DEC; 456 field[IPC_COL_ANS_RCV].uint = data->tasks[i].ipc_info.answer_received; 457 field[IPC_COL_FORWARD].type = FIELD_UINT_SUFFIX_DEC; 458 field[IPC_COL_FORWARD].uint = data->tasks[i].ipc_info.forwarded; 459 field[IPC_COL_NAME].type = FIELD_STRING; 460 field[IPC_COL_NAME].string = data->tasks[i].name; 461 field += IPC_NUM_COLUMNS; 462 } 463 464 return NULL; 465 } 466 467 static const char *fill_exception_table(data_t *data) 468 { 469 data->table.name = "Exceptions"; 470 data->table.num_columns = EXCEPTION_NUM_COLUMNS; 471 data->table.columns = exception_columns; 472 data->table.num_fields = data->exceptions_count * 473 EXCEPTION_NUM_COLUMNS; 474 data->table.fields = calloc(data->table.num_fields, sizeof(field_t)); 475 if (data->table.fields == NULL) 476 return "Not enough memory for table fields"; 477 478 field_t *field = data->table.fields; 479 for (size_t i = 0; i < data->exceptions_count; i++) { 480 if (!excs_all && !data->exceptions[i].hot) 481 continue; 482 field[EXCEPTION_COL_ID].type = FIELD_UINT; 483 field[EXCEPTION_COL_ID].uint = data->exceptions[i].id; 484 field[EXCEPTION_COL_COUNT].type = FIELD_UINT_SUFFIX_DEC; 485 field[EXCEPTION_COL_COUNT].uint = data->exceptions[i].count; 486 field[EXCEPTION_COL_PERCENT_COUNT].type = FIELD_PERCENT; 487 field[EXCEPTION_COL_PERCENT_COUNT].fixed = data->exceptions_perc[i].count; 488 field[EXCEPTION_COL_CYCLES].type = FIELD_UINT_SUFFIX_DEC; 489 field[EXCEPTION_COL_CYCLES].uint = data->exceptions[i].cycles; 490 field[EXCEPTION_COL_PERCENT_CYCLES].type = FIELD_PERCENT; 491 field[EXCEPTION_COL_PERCENT_CYCLES].fixed = data->exceptions_perc[i].cycles; 492 field[EXCEPTION_COL_DESCRIPTION].type = FIELD_STRING; 493 field[EXCEPTION_COL_DESCRIPTION].string = data->exceptions[i].desc; 494 field += EXCEPTION_NUM_COLUMNS; 495 } 496 497 /* in case any cold exceptions were ignored */ 498 data->table.num_fields = field - data->table.fields; 499 500 return NULL; 501 } 502 503 static const char *fill_table(data_t *data) 504 { 505 if (data->table.fields != NULL) { 506 free(data->table.fields); 507 data->table.fields = NULL; 508 } 509 510 switch (op_mode) { 511 case OP_TASKS: 512 return fill_task_table(data); 513 case OP_IPC: 514 return fill_ipc_table(data); 515 case OP_EXCS: 516 return fill_exception_table(data); 517 } 518 return NULL; 519 } 520 318 521 static void free_data(data_t *target) 319 522 { … … 356 559 if (target->ecount_diff != NULL) 357 560 free(target->ecount_diff); 561 562 if (target->table.fields != NULL) 563 free(target->table.fields); 358 564 } 359 565 … … 389 595 break; 390 596 case 't': 597 screen_mode = SCREEN_TABLE; 391 598 op_mode = OP_TASKS; 392 599 break; 393 600 case 'i': 601 screen_mode = SCREEN_TABLE; 394 602 op_mode = OP_IPC; 395 603 break; 396 604 case 'e': 605 screen_mode = SCREEN_TABLE; 397 606 op_mode = OP_EXCS; 398 607 break; 399 608 case 'h': 400 609 case '?': 401 op_mode = OP_HELP; 610 if (screen_mode == SCREEN_HELP) 611 screen_mode = SCREEN_TABLE; 612 else 613 screen_mode = SCREEN_HELP; 402 614 break; 403 615 case 'q': … … 405 617 case 'a': 406 618 if (op_mode == OP_EXCS) { 619 screen_mode = SCREEN_TABLE; 407 620 excs_all = !excs_all; 408 621 if (excs_all) … … 419 632 420 633 sort_data(&data); 634 if ((ret = fill_table(&data)) != NULL) { 635 goto out; 636 } 421 637 print_data(&data); 422 638 } -
uspace/app/top/top.h
r94f6df7 rf682f5a 51 51 52 52 typedef enum { 53 OP_TASKS, 54 OP_IPC, 55 OP_EXCS, 56 OP_HELP 57 } op_mode_t; 53 SCREEN_TABLE, 54 SCREEN_HELP, 55 } screen_mode_t; 58 56 59 57 typedef enum { … … 61 59 } sort_mode_t; 62 60 63 extern op_mode_t op_mode;61 extern screen_mode_t screen_mode; 64 62 extern sort_mode_t sort_mode; 65 extern bool excs_all;66 63 67 64 typedef struct { … … 86 83 fixed_float count; 87 84 } perc_exc_t; 85 86 typedef enum { 87 FIELD_EMPTY, FIELD_UINT, FIELD_UINT_SUFFIX_BIN, FIELD_UINT_SUFFIX_DEC, 88 FIELD_PERCENT, FIELD_STRING 89 } field_type_t; 90 91 typedef struct { 92 field_type_t type; 93 union { 94 fixed_float fixed; 95 uint64_t uint; 96 const char *string; 97 }; 98 } field_t; 99 100 typedef struct { 101 const char *name; 102 char key; 103 int width; 104 } column_t; 105 106 typedef struct { 107 const char *name; 108 size_t num_columns; 109 const column_t *columns; 110 size_t num_fields; 111 field_t *fields; 112 } table_t; 88 113 89 114 typedef struct { … … 122 147 uint64_t *ecycles_diff; 123 148 uint64_t *ecount_diff; 149 150 table_t table; 124 151 } data_t; 125 152
Note:
See TracChangeset
for help on using the changeset viewer.