Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/top/screen.c

    r79ae36dd rd76a329  
    3737
    3838#include <stdio.h>
     39#include <stdlib.h>
    3940#include <io/console.h>
    4041#include <io/style.h>
     
    4344#include <stats.h>
    4445#include <inttypes.h>
     46#include <macros.h>
    4547#include "screen.h"
    4648#include "top.h"
     
    4850#define USEC_COUNT  1000000
    4951
    50 static sysarg_t warn_col = 0;
    51 static sysarg_t warn_row = 0;
    5252static suseconds_t timeleft = 0;
    5353
    5454console_ctrl_t *console;
    5555
     56static sysarg_t warning_col = 0;
     57static sysarg_t warning_row = 0;
     58static suseconds_t warning_timeleft = 0;
     59static char *warning_text = NULL;
     60
    5661static void screen_style_normal(void)
    5762{
     
    6469        console_flush(console);
    6570        console_set_style(console, STYLE_INVERTED);
     71}
     72
     73static void screen_style_emphasis(void)
     74{
     75        console_flush(console);
     76        console_set_style(console, STYLE_EMPHASIS);
    6677}
    6778
     
    126137void screen_done(void)
    127138{
     139        free(warning_text);
     140        warning_text = NULL;
     141
    128142        screen_restart(true);
    129143       
     
    277291}
    278292
    279 static inline void print_tasks_head(void)
     293static inline void print_help_head(void)
    280294{
    281295        screen_style_inverted();
    282         printf("[taskid] [thrds] [resident] [%%resi] [virtual] [%%virt]"
    283             " [%%user] [%%kern] [name");
     296        printf("Help");
    284297        screen_newline();
    285298        screen_style_normal();
    286299}
    287300
    288 static inline void print_tasks(data_t *data)
    289 {
    290         sysarg_t cols;
    291         sysarg_t rows;
    292         screen_get_size(&cols, &rows);
     301static inline void print_help(void)
     302{
     303        sysarg_t cols;
     304        sysarg_t rows;
     305        screen_get_size(&cols, &rows);
     306       
     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();
    293340       
    294341        sysarg_t col;
     
    296343        screen_get_pos(&col, &row);
    297344       
    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        
    326345        while (row < rows) {
    327346                screen_newline();
     
    330349}
    331350
    332 static inline void print_ipc_head(void)
    333 {
     351static inline void print_table_head(const table_t *table)
     352{
     353        sysarg_t cols;
     354        sysarg_t rows;
     355        screen_get_size(&cols, &rows);
     356
    334357        screen_style_inverted();
    335         printf("[taskid] [cls snt] [cls rcv] [ans snt]"
    336             " [ans rcv] [irq rcv] [forward] [name");
     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        }
    337372        screen_newline();
    338373        screen_style_normal();
    339374}
    340375
    341 static inline void print_ipc(data_t *data)
     376static inline void print_table(const table_t *table)
    342377{
    343378        sysarg_t cols;
     
    350385       
    351386        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();
     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                }
    392441        }
    393442       
     
    398447}
    399448
    400 static inline void print_excs_head(void)
    401 {
    402         screen_style_inverted();
    403         printf("[exc   ] [count   ] [%%count] [cycles  ] [%%cycles] [description");
    404         screen_newline();
    405         screen_style_normal();
    406 }
    407 
    408 static inline void print_excs(data_t *data)
     449static inline void print_sort(table_t *table)
    409450{
    410451        sysarg_t cols;
     
    415456        sysarg_t row;
    416457        screen_get_pos(&col, &row);
    417        
    418         size_t i;
    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                
     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);
    441462                screen_newline();
    442463                row++;
     
    449470}
    450471
    451 static void print_help(void)
    452 {
    453         sysarg_t cols;
    454         sysarg_t rows;
    455         screen_get_size(&cols, &rows);
    456        
    457         sysarg_t col;
    458         sysarg_t row;
    459         screen_get_pos(&col, &row);
    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) {
    481                 screen_newline();
    482                 row++;
    483         }
     472static 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        
    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);
     494        print_warning();
     495       
     496        switch (screen_mode) {
     497        case SCREEN_TABLE:
     498                print_table_head(&data->table);
     499                print_table(&data->table);
    503500                break;
    504         case OP_IPC:
    505                 print_ipc_head();
    506                 print_ipc(data);
     501        case SCREEN_SORT:
     502                print_sort(&data->table);
    507503                break;
    508         case OP_EXCS:
    509                 print_excs_head();
    510                 print_excs(data);
    511                 break;
    512         case OP_HELP:
    513                 print_tasks_head();
     504        case SCREEN_HELP:
     505                print_help_head();
    514506                print_help();
    515507        }
     
    518510}
    519511
    520 void print_warning(const char *fmt, ...)
    521 {
    522         screen_moveto(warn_col, warn_row);
    523        
     512void 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
    524524        va_list args;
    525525        va_start(args, fmt);
    526         vprintf(fmt, args);
     526        vsnprintf(warning_text, warning_text_size, fmt, args);
    527527        va_end(args);
    528528       
    529         screen_newline();
     529        warning_timeleft = 2 * USEC_COUNT;
     530
     531        screen_moveto(warning_col, warning_row);
     532        print_warning();
    530533        console_flush(console);
    531534}
     
    555558                kbd_event_t event;
    556559               
     560                warning_timeleft -= timeleft;
    557561                if (!console_get_kbd_event_timeout(console, &event, &timeleft)) {
    558562                        timeleft = 0;
    559563                        return -1;
    560564                }
     565                warning_timeleft += timeleft;
    561566               
    562567                if (event.type == KEY_PRESS)
Note: See TracChangeset for help on using the changeset viewer.