Changeset f682f5a in mainline


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
Location:
uspace/app/top
Files:
3 edited

Legend:

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

    r94f6df7 rf682f5a  
    290290}
    291291
    292 static inline void print_tasks_head(void)
     292static inline void print_help_head(void)
    293293{
    294294        screen_style_inverted();
    295         printf("[taskid] [thrds] [resident] [%%resi] [virtual] [%%virt]"
    296             " [%%user] [%%kern] [name");
     295        printf("Help");
    297296        screen_newline();
    298297        screen_style_normal();
    299298}
    300299
    301 static inline void print_tasks(data_t *data)
     300static inline void print_help(void)
    302301{
    303302        sysarg_t cols;
     
    305304        screen_get_size(&cols, &rows);
    306305       
     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       
    307334        sysarg_t col;
    308335        sysarg_t row;
    309336        screen_get_pos(&col, &row);
    310337       
    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        
    339338        while (row < rows) {
    340339                screen_newline();
     
    343342}
    344343
    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)
     344static inline void print_table_head(const table_t *table)
    355345{
    356346        sysarg_t cols;
    357347        sysarg_t rows;
    358348        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
     369static inline void print_table(const table_t *table)
     370{
     371        sysarg_t cols;
     372        sysarg_t rows;
     373        screen_get_size(&cols, &rows);
    359374       
    360375        sysarg_t col;
     
    363378       
    364379        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                }
    405434        }
    406435       
     
    411440}
    412441
    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)
     442static inline void print_warning(void)
    517443{
    518444        screen_get_pos(&warning_col, &warning_row);
     
    538464        print_warning();
    539465       
    540         switch (op_mode) {
    541         case OP_TASKS:
    542                 print_tasks_head();
    543                 print_tasks(data);
     466        switch (screen_mode) {
     467        case SCREEN_TABLE:
     468                print_table_head(&data->table);
     469                print_table(&data->table);
    544470                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:
    554472                print_help_head();
    555473                print_help();
  • 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        }
  • uspace/app/top/top.h

    r94f6df7 rf682f5a  
    5151
    5252typedef 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;
    5856
    5957typedef enum {
     
    6159} sort_mode_t;
    6260
    63 extern op_mode_t op_mode;
     61extern screen_mode_t screen_mode;
    6462extern sort_mode_t sort_mode;
    65 extern bool excs_all;
    6663
    6764typedef struct {
     
    8683        fixed_float count;
    8784} perc_exc_t;
     85
     86typedef enum {
     87        FIELD_EMPTY, FIELD_UINT, FIELD_UINT_SUFFIX_BIN, FIELD_UINT_SUFFIX_DEC,
     88        FIELD_PERCENT, FIELD_STRING
     89} field_type_t;
     90
     91typedef 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
     100typedef struct {
     101        const char *name;
     102        char key;
     103        int width;
     104} column_t;
     105
     106typedef 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;
    88113
    89114typedef struct {
     
    122147        uint64_t *ecycles_diff;
    123148        uint64_t *ecount_diff;
     149
     150        table_t table;
    124151} data_t;
    125152
Note: See TracChangeset for help on using the changeset viewer.