Changeset f682f5a in mainline for uspace/app/top/top.c


Ignore:
Timestamp:
2012-04-15T07:42:52Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b8d6783
Parents:
94f6df7
Message:

top: use generic handling for tables

  • each table has a name, columns, and fields
  • each column has a name, width, and shortcut key
  • each field has a type and value
  • this will help make top more configurable in the future
File:
1 edited

Legend:

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

    r94f6df7 rf682f5a  
    5555#define MINUTE  60
    5656
    57 op_mode_t op_mode = OP_TASKS;
     57typedef enum {
     58        OP_TASKS,
     59        OP_IPC,
     60        OP_EXCS,
     61} op_mode_t;
     62
     63screen_mode_t screen_mode = SCREEN_TABLE;
     64static op_mode_t op_mode = OP_TASKS;
    5865sort_mode_t sort_mode = SORT_TASK_CYCLES;
    59 bool excs_all = false;
     66static bool excs_all = false;
     67
     68static 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
     80enum {
     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
     93static 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
     103enum {
     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
     114static 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
     123enum {
     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};
    60132
    61133static const char *read_data(data_t *target)
     
    76148        target->ecycles_diff = NULL;
    77149        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;
    78155       
    79156        /* Get current time */
     
    316393}
    317394
     395static 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
     434static 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
     467static 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
     503static 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
    318521static void free_data(data_t *target)
    319522{
     
    356559        if (target->ecount_diff != NULL)
    357560                free(target->ecount_diff);
     561
     562        if (target->table.fields != NULL)
     563                free(target->table.fields);
    358564}
    359565
     
    389595                                break;
    390596                        case 't':
     597                                screen_mode = SCREEN_TABLE;
    391598                                op_mode = OP_TASKS;
    392599                                break;
    393600                        case 'i':
     601                                screen_mode = SCREEN_TABLE;
    394602                                op_mode = OP_IPC;
    395603                                break;
    396604                        case 'e':
     605                                screen_mode = SCREEN_TABLE;
    397606                                op_mode = OP_EXCS;
    398607                                break;
    399608                        case 'h':
    400609                        case '?':
    401                                 op_mode = OP_HELP;
     610                                if (screen_mode == SCREEN_HELP)
     611                                        screen_mode = SCREEN_TABLE;
     612                                else
     613                                        screen_mode = SCREEN_HELP;
    402614                                break;
    403615                        case 'q':
     
    405617                        case 'a':
    406618                                if (op_mode == OP_EXCS) {
     619                                        screen_mode = SCREEN_TABLE;
    407620                                        excs_all = !excs_all;
    408621                                        if (excs_all)
     
    419632
    420633                sort_data(&data);
     634                if ((ret = fill_table(&data)) != NULL) {
     635                        goto out;
     636                }
    421637                print_data(&data);
    422638        }
Note: See TracChangeset for help on using the changeset viewer.