Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/dist/src/c/demos/top/screen.c

    r5042706 r07b7c48  
    3737
    3838#include <stdio.h>
    39 #include <stdlib.h>
    4039#include <io/console.h>
    4140#include <io/style.h>
     
    4443#include <stats.h>
    4544#include <inttypes.h>
    46 #include <macros.h>
    4745#include "screen.h"
    4846#include "top.h"
     
    5048#define USEC_COUNT  1000000
    5149
     50static sysarg_t warn_col = 0;
     51static sysarg_t warn_row = 0;
    5252static suseconds_t timeleft = 0;
    5353
    5454console_ctrl_t *console;
    5555
    56 static sysarg_t warning_col = 0;
    57 static sysarg_t warning_row = 0;
    58 static suseconds_t warning_timeleft = 0;
    59 static char *warning_text = NULL;
    60 
    6156static void screen_style_normal(void)
    6257{
     
    6964        console_flush(console);
    7065        console_set_style(console, STYLE_INVERTED);
    71 }
    72 
    73 static void screen_style_emphasis(void)
    74 {
    75         console_flush(console);
    76         console_set_style(console, STYLE_EMPHASIS);
    7766}
    7867
     
    137126void screen_done(void)
    138127{
    139         free(warning_text);
    140         warning_text = NULL;
    141 
    142128        screen_restart(true);
    143129       
     
    291277}
    292278
    293 static inline void print_help_head(void)
     279static inline void print_tasks_head(void)
    294280{
    295281        screen_style_inverted();
    296         printf("Help");
     282        printf("[taskid] [thrds] [resident] [%%resi] [virtual] [%%virt]"
     283            " [%%user] [%%kern] [name");
    297284        screen_newline();
    298285        screen_style_normal();
    299286}
    300287
    301 static inline void print_help(void)
     288static inline void print_tasks(data_t *data)
    302289{
    303290        sysarg_t cols;
     
    305292        screen_get_size(&cols, &rows);
    306293       
    307         screen_newline();
    308        
    309         printf("Operation modes:");
    310         screen_newline();
    311        
    312         printf(" t .. tasks statistics");
    313         screen_newline();
    314        
    315         printf(" i .. IPC statistics");
    316         screen_newline();
    317        
    318         printf(" e .. exceptions statistics");
    319         screen_newline();
    320        
    321         printf("      a .. toggle display of all/hot exceptions");
    322         screen_newline();
    323 
    324         printf(" h .. toggle this help screen");
    325         screen_newline();
    326 
    327         screen_newline();
    328 
    329         printf("Other keys:");
    330         screen_newline();
    331        
    332         printf(" s .. choose column to sort by");
    333         screen_newline();
    334        
    335         printf(" r .. toggle reversed sorting");
    336         screen_newline();
    337        
    338         printf(" q .. quit");
    339         screen_newline();
    340        
    341294        sysarg_t col;
    342295        sysarg_t row;
    343296        screen_get_pos(&col, &row);
    344297       
     298        size_t i;
     299        for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {
     300                stats_task_t *task = data->tasks + data->tasks_map[i];
     301                perc_task_t *perc = data->tasks_perc + data->tasks_map[i];
     302               
     303                uint64_t resmem;
     304                const char *resmem_suffix;
     305                bin_order_suffix(task->resmem, &resmem, &resmem_suffix, true);
     306               
     307                uint64_t virtmem;
     308                const char *virtmem_suffix;
     309                bin_order_suffix(task->virtmem, &virtmem, &virtmem_suffix, true);
     310               
     311                printf("%-8" PRIu64 " %7zu %7" PRIu64 "%s ",
     312                    task->task_id, task->threads, resmem, resmem_suffix);
     313                print_percent(perc->resmem, 2);
     314                printf(" %6" PRIu64 "%s ", virtmem, virtmem_suffix);
     315                print_percent(perc->virtmem, 2);
     316                puts(" ");
     317                print_percent(perc->ucycles, 2);
     318                puts(" ");
     319                print_percent(perc->kcycles, 2);
     320                puts(" ");
     321                print_string(task->name);
     322               
     323                screen_newline();
     324        }
     325       
    345326        while (row < rows) {
    346327                screen_newline();
     
    349330}
    350331
    351 static inline void print_table_head(const table_t *table)
     332static inline void print_ipc_head(void)
     333{
     334        screen_style_inverted();
     335        printf("[taskid] [cls snt] [cls rcv] [ans snt]"
     336            " [ans rcv] [irq rcv] [forward] [name");
     337        screen_newline();
     338        screen_style_normal();
     339}
     340
     341static inline void print_ipc(data_t *data)
    352342{
    353343        sysarg_t cols;
    354344        sysarg_t rows;
    355345        screen_get_size(&cols, &rows);
    356 
     346       
     347        sysarg_t col;
     348        sysarg_t row;
     349        screen_get_pos(&col, &row);
     350       
     351        size_t i;
     352        for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {
     353                uint64_t call_sent;
     354                uint64_t call_received;
     355                uint64_t answer_sent;
     356                uint64_t answer_received;
     357                uint64_t irq_notif_received;
     358                uint64_t forwarded;
     359               
     360                char call_sent_suffix;
     361                char call_received_suffix;
     362                char answer_sent_suffix;
     363                char answer_received_suffix;
     364                char irq_notif_received_suffix;
     365                char forwarded_suffix;
     366               
     367                order_suffix(data->tasks[i].ipc_info.call_sent, &call_sent,
     368                    &call_sent_suffix);
     369                order_suffix(data->tasks[i].ipc_info.call_received,
     370                    &call_received, &call_received_suffix);
     371                order_suffix(data->tasks[i].ipc_info.answer_sent,
     372                    &answer_sent, &answer_sent_suffix);
     373                order_suffix(data->tasks[i].ipc_info.answer_received,
     374                    &answer_received, &answer_received_suffix);
     375                order_suffix(data->tasks[i].ipc_info.irq_notif_received,
     376                    &irq_notif_received, &irq_notif_received_suffix);
     377                order_suffix(data->tasks[i].ipc_info.forwarded, &forwarded,
     378                    &forwarded_suffix);
     379               
     380                printf("%-8" PRIu64 " %8" PRIu64 "%c %8" PRIu64 "%c"
     381                     " %8" PRIu64 "%c %8" PRIu64 "%c %8" PRIu64 "%c"
     382                     " %8" PRIu64 "%c ", data->tasks[i].task_id,
     383                     call_sent, call_sent_suffix,
     384                     call_received, call_received_suffix,
     385                     answer_sent, answer_sent_suffix,
     386                     answer_received, answer_received_suffix,
     387                     irq_notif_received, irq_notif_received_suffix,
     388                     forwarded, forwarded_suffix);
     389                print_string(data->tasks[i].name);
     390               
     391                screen_newline();
     392        }
     393       
     394        while (row < rows) {
     395                screen_newline();
     396                row++;
     397        }
     398}
     399
     400static inline void print_excs_head(void)
     401{
    357402        screen_style_inverted();
    358         for (size_t i = 0; i < table->num_columns; i++) {
    359                 const char *name = table->columns[i].name;
    360                 int width = table->columns[i].width;
    361                 if (i != 0) {
    362                         puts(" ");
    363                 }
    364                 if (width == 0) {
    365                         sysarg_t col;
    366                         sysarg_t row;
    367                         screen_get_pos(&col, &row);
    368                         width = cols - col - 1;
    369                 }
    370                 printf("[%-*.*s]", width - 2, width - 2, name);
    371         }
     403        printf("[exc   ] [count   ] [%%count] [cycles  ] [%%cycles] [description");
    372404        screen_newline();
    373405        screen_style_normal();
    374406}
    375407
    376 static inline void print_table(const table_t *table)
     408static inline void print_excs(data_t *data)
    377409{
    378410        sysarg_t cols;
     
    385417       
    386418        size_t i;
    387         for (i = 0; (i < table->num_fields) && (row < rows); i++) {
    388                 size_t column_index = i % table->num_columns;
    389                 int width = table->columns[column_index].width;
    390                 field_t *field = &table->fields[i];
    391 
    392                 if (column_index != 0) {
    393                         puts(" ");
    394                 }
    395 
    396                 if (width == 0) {
    397                         screen_get_pos(&col, &row);
    398                         width = cols - col - 1;
    399                 }
    400 
    401                 switch (field->type) {
    402                 case FIELD_EMPTY:
    403                         printf("%*s", width, "");
    404                         break;
    405                 case FIELD_UINT:
    406                         printf("%*" PRIu64, width, field->uint);
    407                         break;
    408                 case FIELD_UINT_SUFFIX_BIN: {
    409                         uint64_t val = field->uint;
    410                         const char *suffix;
    411                         width -= 3;
    412                         bin_order_suffix(val, &val, &suffix, true);
    413                         printf("%*" PRIu64 "%s", width, val, suffix);
    414                         break;
    415                 }
    416                 case FIELD_UINT_SUFFIX_DEC: {
    417                         uint64_t val = field->uint;
    418                         char suffix;
    419                         width -= 1;
    420                         order_suffix(val, &val, &suffix);
    421                         printf("%*" PRIu64 "%c", width, val, suffix);
    422                         break;
    423                 }
    424                 case FIELD_PERCENT:
    425                         width -= 5; /* nnn.% */
    426                         if (width > 2) {
    427                                 printf("%*s", width - 2, "");
    428                                 width = 2;
    429                         }
    430                         print_percent(field->fixed, width);
    431                         break;
    432                 case FIELD_STRING:
    433                         printf("%-*.*s", width, width, field->string);
    434                         break;
    435                 }
    436 
    437                 if (column_index == table->num_columns - 1) {
    438                         screen_newline();
    439                         row++;
    440                 }
     419        for (i = 0; (i < data->exceptions_count) && (row < rows); i++) {
     420                /* Filter-out cold exceptions if not instructed otherwise */
     421                if ((!excs_all) && (!data->exceptions[i].hot))
     422                        continue;
     423               
     424                uint64_t count;
     425                uint64_t cycles;
     426               
     427                char count_suffix;
     428                char cycles_suffix;
     429               
     430                order_suffix(data->exceptions[i].count, &count, &count_suffix);
     431                order_suffix(data->exceptions[i].cycles, &cycles, &cycles_suffix);
     432               
     433                printf("%-8u %9" PRIu64 "%c  ",
     434                     data->exceptions[i].id, count, count_suffix);
     435                print_percent(data->exceptions_perc[i].count, 2);
     436                printf(" %9" PRIu64 "%c   ", cycles, cycles_suffix);
     437                print_percent(data->exceptions_perc[i].cycles, 2);
     438                puts(" ");
     439                print_string(data->exceptions[i].desc);
     440               
     441                screen_newline();
     442                row++;
    441443        }
    442444       
     
    447449}
    448450
    449 static inline void print_sort(table_t *table)
     451static void print_help(void)
    450452{
    451453        sysarg_t cols;
     
    456458        sysarg_t row;
    457459        screen_get_pos(&col, &row);
    458 
    459         size_t num = min(table->num_columns, rows - row);
    460         for (size_t i = 0; i < num; i++) {
    461                 printf("%c - %s", table->columns[i].key, table->columns[i].name);
     460       
     461        screen_newline();
     462       
     463        printf("Operation modes:");
     464        screen_newline();
     465       
     466        printf(" t .. tasks statistics");
     467        screen_newline();
     468       
     469        printf(" i .. IPC statistics");
     470        screen_newline();
     471       
     472        printf(" e .. exceptions statistics");
     473        screen_newline();
     474       
     475        printf("      a .. toggle display of all/hot exceptions");
     476        screen_newline();
     477       
     478        row += 6;
     479       
     480        while (row < rows) {
    462481                screen_newline();
    463482                row++;
    464483        }
    465        
    466         while (row < rows) {
    467                 screen_newline();
    468                 row++;
    469         }
    470 }
    471 
    472 static inline void print_warning(void)
    473 {
    474         screen_get_pos(&warning_col, &warning_row);
    475         if (warning_timeleft > 0) {
    476                 screen_style_emphasis();
    477                 print_string(warning_text);
    478                 screen_style_normal();
    479         } else {
    480                 free(warning_text);
    481                 warning_text = NULL;
    482         }
    483         screen_newline();
    484484}
    485485
     
    492492        print_cpu_info(data);
    493493        print_physmem_info(data);
    494         print_warning();
    495        
    496         switch (screen_mode) {
    497         case SCREEN_TABLE:
    498                 print_table_head(&data->table);
    499                 print_table(&data->table);
     494       
     495        /* Empty row for warnings */
     496        screen_get_pos(&warn_col, &warn_row);
     497        screen_newline();
     498       
     499        switch (op_mode) {
     500        case OP_TASKS:
     501                print_tasks_head();
     502                print_tasks(data);
    500503                break;
    501         case SCREEN_SORT:
    502                 print_sort(&data->table);
     504        case OP_IPC:
     505                print_ipc_head();
     506                print_ipc(data);
    503507                break;
    504         case SCREEN_HELP:
    505                 print_help_head();
     508        case OP_EXCS:
     509                print_excs_head();
     510                print_excs(data);
     511                break;
     512        case OP_HELP:
     513                print_tasks_head();
    506514                print_help();
    507515        }
     
    510518}
    511519
    512 void show_warning(const char *fmt, ...)
    513 {
    514         sysarg_t cols;
    515         sysarg_t rows;
    516         screen_get_size(&cols, &rows);
    517 
    518         size_t warning_text_size = 1 + cols * sizeof(*warning_text);
    519         free(warning_text);
    520         warning_text = malloc(warning_text_size);
    521         if (!warning_text)
    522                 return;
    523 
     520void print_warning(const char *fmt, ...)
     521{
     522        screen_moveto(warn_col, warn_row);
     523       
    524524        va_list args;
    525525        va_start(args, fmt);
    526         vsnprintf(warning_text, warning_text_size, fmt, args);
     526        vprintf(fmt, args);
    527527        va_end(args);
    528528       
    529         warning_timeleft = 2 * USEC_COUNT;
    530 
    531         screen_moveto(warning_col, warning_row);
    532         print_warning();
     529        screen_newline();
    533530        console_flush(console);
    534531}
     
    558555                cons_event_t event;
    559556               
    560                 warning_timeleft -= timeleft;
    561557                if (!console_get_event_timeout(console, &event, &timeleft)) {
    562558                        timeleft = 0;
    563559                        return -1;
    564560                }
    565                 warning_timeleft += timeleft;
    566561               
    567562                if (event.type == CEV_KEY && event.ev.key.type == KEY_PRESS)
Note: See TracChangeset for help on using the changeset viewer.