Changes in uspace/app/top/top.c [172aad6:9e05055] in mainline


Ignore:
File:
1 edited

Legend:

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

    r172aad6 r9e05055  
    4444#include <arch/barrier.h>
    4545#include <errno.h>
    46 #include <sort.h>
    4746#include "screen.h"
    4847#include "input.h"
     
    5756#define MINUTE  60
    5857
    59 op_mode_t op_mode = OP_TASKS;
    60 sort_mode_t sort_mode = SORT_TASK_CYCLES;
    61 bool excs_all = false;
     58int operation_type;
    6259
    6360static const char *read_data(data_t *target)
     
    6966        target->tasks = NULL;
    7067        target->tasks_perc = NULL;
    71         target->tasks_map = NULL;
    7268        target->threads = NULL;
    73         target->exceptions = NULL;
    74         target->exceptions_perc = NULL;
    7569        target->physmem = NULL;
    76         target->ucycles_diff = NULL;
    77         target->kcycles_diff = NULL;
    78         target->ecycles_diff = NULL;
    79         target->ecount_diff = NULL;
    8070       
    8171        /* Get current time */
     
    120110                return "Not enough memory for task utilization";
    121111       
    122         target->tasks_map =
    123             (size_t *) calloc(target->tasks_count, sizeof(size_t));
    124         if (target->tasks_map == NULL)
    125                 return "Not enough memory for task map";
    126        
    127112        /* Get threads */
    128113        target->threads = stats_get_threads(&(target->threads_count));
     
    130115                return "Cannot get threads";
    131116       
    132         /* Get Exceptions */
    133         target->exceptions = stats_get_exceptions(&(target->exceptions_count));
    134         if (target->exceptions == NULL)
    135                 return "Cannot get exceptions";
    136        
    137         target->exceptions_perc =
    138             (perc_exc_t *) calloc(target->exceptions_count, sizeof(perc_exc_t));
    139         if (target->exceptions_perc == NULL)
    140                 return "Not enough memory for exception utilization";
    141        
    142117        /* Get physical memory */
    143118        target->physmem = stats_get_physmem();
     
    145120                return "Cannot get physical memory";
    146121       
    147         target->ucycles_diff = calloc(target->tasks_count,
    148             sizeof(uint64_t));
    149         if (target->ucycles_diff == NULL)
    150                 return "Not enough memory for user utilization";
    151        
    152         /* Allocate memory for computed values */
    153         target->kcycles_diff = calloc(target->tasks_count,
    154             sizeof(uint64_t));
    155         if (target->kcycles_diff == NULL)
    156                 return "Not enough memory for kernel utilization";
    157        
    158         target->ecycles_diff = calloc(target->exceptions_count,
    159             sizeof(uint64_t));
    160         if (target->ecycles_diff == NULL)
    161                 return "Not enough memory for exception cycles utilization";
    162        
    163         target->ecount_diff = calloc(target->exceptions_count,
    164             sizeof(uint64_t));
    165         if (target->ecount_diff == NULL)
    166                 return "Not enough memory for exception count utilization";
    167        
    168122        return NULL;
    169123}
     
    175129 *
    176130 */
    177 static void compute_percentages(data_t *old_data, data_t *new_data)
     131static const char *compute_percentages(data_t *old_data, data_t *new_data)
    178132{
    179         /* For each CPU: Compute total cycles and divide it between
     133        /* Allocate memory */
     134       
     135        uint64_t *ucycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t));
     136        if (ucycles_diff == NULL)
     137                return "Not enough memory for user utilization";
     138       
     139        uint64_t *kcycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t));
     140        if (kcycles_diff == NULL) {
     141                free(ucycles_diff);
     142                return "Not enough memory for kernel utilization";
     143        }
     144       
     145        /* For each CPU: Compute total ticks and divide it between
    180146           user and kernel */
    181147       
     
    183149        for (i = 0; i < new_data->cpus_count; i++) {
    184150                uint64_t idle =
    185                     new_data->cpus[i].idle_cycles - old_data->cpus[i].idle_cycles;
     151                    new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
    186152                uint64_t busy =
    187                     new_data->cpus[i].busy_cycles - old_data->cpus[i].busy_cycles;
     153                    new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
    188154                uint64_t sum = idle + busy;
    189155               
     
    194160        /* For all tasks compute sum and differencies of all cycles */
    195161       
    196         uint64_t virtmem_total = 0;
    197         uint64_t ucycles_total = 0;
    198         uint64_t kcycles_total = 0;
     162        uint64_t virtmem_total = 1;  /* Must NOT be zero */
     163        uint64_t ucycles_total = 1;  /* Must NOT be zero */
     164        uint64_t kcycles_total = 1;  /* Must NOT be zero */
    199165       
    200166        for (i = 0; i < new_data->tasks_count; i++) {
     
    212178                if (!found) {
    213179                        /* This is newly borned task, ignore it */
    214                         new_data->ucycles_diff[i] = 0;
    215                         new_data->kcycles_diff[i] = 0;
     180                        ucycles_diff[i] = 0;
     181                        kcycles_diff[i] = 0;
    216182                        continue;
    217183                }
    218184               
    219                 new_data->ucycles_diff[i] =
     185                ucycles_diff[i] =
    220186                    new_data->tasks[i].ucycles - old_data->tasks[j].ucycles;
    221                 new_data->kcycles_diff[i] =
     187                kcycles_diff[i] =
    222188                    new_data->tasks[i].kcycles - old_data->tasks[j].kcycles;
    223189               
    224190                virtmem_total += new_data->tasks[i].virtmem;
    225                 ucycles_total += new_data->ucycles_diff[i];
    226                 kcycles_total += new_data->kcycles_diff[i];
    227         }
    228        
    229         /* For each task compute percential change */
     191                ucycles_total += ucycles_diff[i];
     192                kcycles_total += kcycles_diff[i];
     193        }
     194       
     195        /* For each task: Compute percential change */
    230196       
    231197        for (i = 0; i < new_data->tasks_count; i++) {
     
    233199                    new_data->tasks[i].virtmem * 100, virtmem_total);
    234200                FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles,
    235                     new_data->ucycles_diff[i] * 100, ucycles_total);
     201                    ucycles_diff[i] * 100, ucycles_total);
    236202                FRACTION_TO_FLOAT(new_data->tasks_perc[i].kcycles,
    237                     new_data->kcycles_diff[i] * 100, kcycles_total);
    238         }
    239        
    240         /* For all exceptions compute sum and differencies of cycles */
    241        
    242         uint64_t ecycles_total = 0;
    243         uint64_t ecount_total = 0;
    244        
    245         for (i = 0; i < new_data->exceptions_count; i++) {
    246                 /*
    247                  * March exception with the previous instance.
    248                  * This is quite paranoid since exceptions do not
    249                  * usually disappear, but it does not hurt.
    250                  */
    251                
    252                 bool found = false;
    253                 size_t j;
    254                 for (j = 0; j < old_data->exceptions_count; j++) {
    255                         if (new_data->exceptions[i].id == old_data->exceptions[j].id) {
    256                                 found = true;
    257                                 break;
    258                         }
    259                 }
    260                
    261                 if (!found) {
    262                         /* This is a new exception, ignore it */
    263                         new_data->ecycles_diff[i] = 0;
    264                         new_data->ecount_diff[i] = 0;
    265                         continue;
    266                 }
    267                
    268                 new_data->ecycles_diff[i] =
    269                     new_data->exceptions[i].cycles - old_data->exceptions[j].cycles;
    270                 new_data->ecount_diff[i] =
    271                     new_data->exceptions[i].count - old_data->exceptions[i].count;
    272                
    273                 ecycles_total += new_data->ecycles_diff[i];
    274                 ecount_total += new_data->ecount_diff[i];
    275         }
    276        
    277         /* For each exception compute percential change */
    278        
    279         for (i = 0; i < new_data->exceptions_count; i++) {
    280                 FRACTION_TO_FLOAT(new_data->exceptions_perc[i].cycles,
    281                     new_data->ecycles_diff[i] * 100, ecycles_total);
    282                 FRACTION_TO_FLOAT(new_data->exceptions_perc[i].count,
    283                     new_data->ecount_diff[i] * 100, ecount_total);
    284         }
    285 }
    286 
    287 static int cmp_data(void *a, void *b, void *arg)
    288 {
    289         size_t ia = *((size_t *) a);
    290         size_t ib = *((size_t *) b);
    291         data_t *data = (data_t *) arg;
    292        
    293         uint64_t acycles = data->ucycles_diff[ia] + data->kcycles_diff[ia];
    294         uint64_t bcycles = data->ucycles_diff[ib] + data->kcycles_diff[ib];
    295        
    296         if (acycles > bcycles)
    297                 return -1;
    298        
    299         if (acycles < bcycles)
    300                 return 1;
    301        
    302         return 0;
    303 }
    304 
    305 static void sort_data(data_t *data)
    306 {
    307         size_t i;
    308        
    309         for (i = 0; i < data->tasks_count; i++)
    310                 data->tasks_map[i] = i;
    311        
    312         qsort((void *) data->tasks_map, data->tasks_count,
    313             sizeof(size_t), cmp_data, (void *) data);
     203                    kcycles_diff[i] * 100, kcycles_total);
     204        }
     205       
     206        /* Cleanup */
     207       
     208        free(ucycles_diff);
     209        free(kcycles_diff);
     210       
     211        return NULL;
    314212}
    315213
     
    334232                free(target->threads);
    335233       
    336         if (target->exceptions != NULL)
    337                 free(target->exceptions);
    338        
    339         if (target->exceptions_perc != NULL)
    340                 free(target->exceptions_perc);
    341        
    342234        if (target->physmem != NULL)
    343235                free(target->physmem);
    344        
    345         if (target->ucycles_diff != NULL)
    346                 free(target->ucycles_diff);
    347        
    348         if (target->kcycles_diff != NULL)
    349                 free(target->kcycles_diff);
    350        
    351         if (target->ecycles_diff != NULL)
    352                 free(target->ecycles_diff);
    353        
    354         if (target->ecount_diff != NULL)
    355                 free(target->ecount_diff);
    356236}
    357237
     
    369249       
    370250        /* Compute some rubbish to have initialised values */
    371         compute_percentages(&data_prev, &data_prev);
     251        if ((ret = compute_percentages(&data_prev, &data_prev)) != NULL)
     252                goto out;
    372253       
    373254        /* And paint screen until death */
     255        operation_type = OP_TASKS;
    374256        while (true) {
    375257                int c = tgetchar(UPDATE_INTERVAL);
     
    380262                        }
    381263                       
    382                         compute_percentages(&data_prev, &data);
    383                         sort_data(&data);
     264                        if ((ret = compute_percentages(&data_prev, &data)) != NULL) {
     265                                free_data(&data);
     266                                goto out;
     267                        }
     268                       
    384269                        print_data(&data);
    385270                        free_data(&data_prev);
     
    390275               
    391276                switch (c) {
     277                        case 'q':
     278                                goto out;
     279                        case 'i':
     280                                print_warning("Showing IPC statistics");
     281                                operation_type = OP_IPC;
     282                                break;
    392283                        case 't':
    393284                                print_warning("Showing task statistics");
    394                                 op_mode = OP_TASKS;
     285                                operation_type = OP_TASKS;
    395286                                break;
    396                         case 'i':
    397                                 print_warning("Showing IPC statistics");
    398                                 op_mode = OP_IPC;
    399                                 break;
    400                         case 'e':
    401                                 print_warning("Showing exception statistics");
    402                                 op_mode = OP_EXCS;
    403                                 break;
    404                         case 'h':
    405                                 print_warning("Showing help");
    406                                 op_mode = OP_HELP;
    407                                 break;
    408                         case 'q':
    409                                 goto out;
    410                         case 'a':
    411                                 if (op_mode == OP_EXCS) {
    412                                         excs_all = !excs_all;
    413                                         if (excs_all)
    414                                                 print_warning("Showing all exceptions");
    415                                         else
    416                                                 print_warning("Showing only hot exceptions");
    417                                         break;
    418                                 }
    419287                        default:
    420                                 print_warning("Unknown command \"%c\", use \"h\" for help", c);
     288                                print_warning("Unknown command: %c", c);
    421289                                break;
    422290                }
Note: See TracChangeset for help on using the changeset viewer.