Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset b8d6783 in mainline


Ignore:
Timestamp:
2012-04-15T08:21:20Z (10 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master
Children:
f76696f
Parents:
f682f5a
Message:

top: allow choosing column to sort by

Location:
uspace/app/top
Files:
3 edited

Legend:

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

    rf682f5a rb8d6783  
    4444#include <stats.h>
    4545#include <inttypes.h>
     46#include <macros.h>
    4647#include "screen.h"
    4748#include "top.h"
     
    327328
    328329        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");
    329336        screen_newline();
    330337       
     
    440447}
    441448
     449static inline void print_sort(table_t *table)
     450{
     451        sysarg_t cols;
     452        sysarg_t rows;
     453        screen_get_size(&cols, &rows);
     454       
     455        sysarg_t col;
     456        sysarg_t row;
     457        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);
     462                screen_newline();
     463                row++;
     464        }
     465       
     466        while (row < rows) {
     467                screen_newline();
     468                row++;
     469        }
     470}
     471
    442472static inline void print_warning(void)
    443473{
     
    469499                print_table(&data->table);
    470500                break;
     501        case SCREEN_SORT:
     502                print_sort(&data->table);
     503                break;
    471504        case SCREEN_HELP:
    472505                print_help_head();
  • uspace/app/top/top.c

    rf682f5a rb8d6783  
    6161} op_mode_t;
    6262
    63 screen_mode_t screen_mode = SCREEN_TABLE;
    64 static op_mode_t op_mode = OP_TASKS;
    65 sort_mode_t sort_mode = SORT_TASK_CYCLES;
    66 static bool excs_all = false;
    67 
    6863static const column_t task_columns[] = {
    6964        {"taskid",   't',  8},
     
    131126};
    132127
     128screen_mode_t screen_mode = SCREEN_TABLE;
     129static op_mode_t op_mode = OP_TASKS;
     130static size_t sort_column = TASK_COL_PERCENT_USER;
     131static int sort_reverse = -1;
     132static bool excs_all = false;
     133
    133134static const char *read_data(data_t *target)
    134135{
     
    139140        target->tasks = NULL;
    140141        target->tasks_perc = NULL;
    141         target->tasks_map = NULL;
    142142        target->threads = NULL;
    143143        target->exceptions = NULL;
     
    195195                return "Not enough memory for task utilization";
    196196       
    197         target->tasks_map =
    198             (size_t *) calloc(target->tasks_count, sizeof(size_t));
    199         if (target->tasks_map == NULL)
    200                 return "Not enough memory for task map";
    201        
    202197        /* Get threads */
    203198        target->threads = stats_get_threads(&(target->threads_count));
     
    366361static int cmp_data(void *a, void *b, void *arg)
    367362{
    368         size_t ia = *((size_t *) a);
    369         size_t ib = *((size_t *) b);
    370         data_t *data = (data_t *) arg;
    371        
    372         uint64_t acycles = data->ucycles_diff[ia] + data->kcycles_diff[ia];
    373         uint64_t bcycles = data->ucycles_diff[ib] + data->kcycles_diff[ib];
    374        
    375         if (acycles > bcycles)
    376                 return -1;
    377        
    378         if (acycles < bcycles)
    379                 return 1;
    380        
     363        field_t *fa = (field_t *)a + sort_column;
     364        field_t *fb = (field_t *)b + sort_column;
     365       
     366        if (fa->type > fb->type)
     367                return 1 * sort_reverse;
     368
     369        if (fa->type < fb->type)
     370                return -1 * sort_reverse;
     371
     372        switch (fa->type) {
     373                case FIELD_EMPTY:
     374                        return 0;
     375                case FIELD_UINT_SUFFIX_BIN: /* fallthrough */
     376                case FIELD_UINT_SUFFIX_DEC: /* fallthrough */
     377                case FIELD_UINT:
     378                        if (fa->uint > fb->uint)
     379                                return 1 * sort_reverse;
     380                        if (fa->uint < fb->uint)
     381                                return -1 * sort_reverse;
     382                        return 0;
     383                case FIELD_PERCENT:
     384                        if (fa->fixed.upper * fb->fixed.lower
     385                            > fb->fixed.upper * fa->fixed.lower)
     386                                return 1 * sort_reverse;
     387                        if (fa->fixed.upper * fb->fixed.lower
     388                            < fb->fixed.upper * fa->fixed.lower)
     389                                return -1 * sort_reverse;
     390                        return 0;
     391                case FIELD_STRING:
     392                        return str_cmp(fa->string, fb->string) * sort_reverse;
     393        }
     394
    381395        return 0;
    382396}
    383397
    384 static void sort_data(data_t *data)
    385 {
    386         size_t i;
    387        
    388         for (i = 0; i < data->tasks_count; i++)
    389                 data->tasks_map[i] = i;
    390        
    391         qsort((void *) data->tasks_map, data->tasks_count,
    392             sizeof(size_t), cmp_data, (void *) data);
     398static void sort_table(table_t *table)
     399{
     400        if (sort_column >= table->num_columns)
     401                sort_column = 0;
     402        /* stable sort is probably best, so we use gsort */
     403        gsort((void *) table->fields, table->num_fields / table->num_columns,
     404            sizeof(field_t) * table->num_columns, cmp_data, NULL);
    393405}
    394406
     
    406418        field_t *field = data->table.fields;
    407419        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];
     420                stats_task_t *task = &data->tasks[i];
     421                perc_task_t *perc = &data->tasks_perc[i];
    410422                field[TASK_COL_ID].type = FIELD_UINT;
    411423                field[TASK_COL_ID].uint = task->task_id;
     
    583595                int c = tgetchar(UPDATE_INTERVAL);
    584596
     597                if (c < 0) { /* timeout */
     598                        data_prev = data;
     599                        if ((ret = read_data(&data)) != NULL) {
     600                                free_data(&data_prev);
     601                                goto out;
     602                        }
     603                       
     604                        compute_percentages(&data_prev, &data);
     605                        free_data(&data_prev);
     606
     607                        c = -1;
     608                }
     609
     610                if (screen_mode == SCREEN_HELP && c >= 0) {
     611                        if (c == 'h' || c == '?')
     612                                c = -1;
     613                        /* go back to table and handle the key */
     614                        screen_mode = SCREEN_TABLE;
     615                }
     616
     617                if (screen_mode == SCREEN_SORT && c >= 0) {
     618                        for (size_t i = 0; i < data.table.num_columns; i++) {
     619                                if (data.table.columns[i].key == c) {
     620                                        sort_column = i;
     621                                        screen_mode = SCREEN_TABLE;
     622                                }
     623                        }
     624
     625                        c = -1;
     626                }
     627
    585628                switch (c) {
    586                         case -1: /* timeout */
    587                                 data_prev = data;
    588                                 if ((ret = read_data(&data)) != NULL) {
    589                                         free_data(&data_prev);
    590                                         goto out;
    591                                 }
    592                                
    593                                 compute_percentages(&data_prev, &data);
    594                                 free_data(&data_prev);
     629                        case -1: /* do nothing */
    595630                                break;
    596631                        case 't':
    597                                 screen_mode = SCREEN_TABLE;
    598632                                op_mode = OP_TASKS;
    599633                                break;
    600634                        case 'i':
    601                                 screen_mode = SCREEN_TABLE;
    602635                                op_mode = OP_IPC;
    603636                                break;
    604637                        case 'e':
    605                                 screen_mode = SCREEN_TABLE;
    606638                                op_mode = OP_EXCS;
     639                                break;
     640                        case 's':
     641                                screen_mode = SCREEN_SORT;
     642                                break;
     643                        case 'r':
     644                                sort_reverse = -sort_reverse;
    607645                                break;
    608646                        case 'h':
    609647                        case '?':
    610                                 if (screen_mode == SCREEN_HELP)
    611                                         screen_mode = SCREEN_TABLE;
    612                                 else
    613                                         screen_mode = SCREEN_HELP;
     648                                screen_mode = SCREEN_HELP;
    614649                                break;
    615650                        case 'q':
     
    617652                        case 'a':
    618653                                if (op_mode == OP_EXCS) {
    619                                         screen_mode = SCREEN_TABLE;
    620654                                        excs_all = !excs_all;
    621655                                        if (excs_all)
     
    631665                }
    632666
    633                 sort_data(&data);
    634667                if ((ret = fill_table(&data)) != NULL) {
    635668                        goto out;
    636669                }
     670                sort_table(&data.table);
    637671                print_data(&data);
    638672        }
  • uspace/app/top/top.h

    rf682f5a rb8d6783  
    5252typedef enum {
    5353        SCREEN_TABLE,
     54        SCREEN_SORT,
    5455        SCREEN_HELP,
    5556} screen_mode_t;
    5657
    57 typedef enum {
    58         SORT_TASK_CYCLES
    59 } sort_mode_t;
    60 
    6158extern screen_mode_t screen_mode;
    62 extern sort_mode_t sort_mode;
    6359
    6460typedef struct {
     
    132128        stats_task_t *tasks;
    133129        perc_task_t *tasks_perc;
    134         size_t *tasks_map;
    135130       
    136131        size_t threads_count;
Note: See TracChangeset for help on using the changeset viewer.