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


Ignore:
File:
1 edited

Legend:

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

    rb3b7e14a r172aad6  
    4444#include <arch/barrier.h>
    4545#include <errno.h>
     46#include <sort.h>
    4647#include "screen.h"
    4748#include "input.h"
     
    5758
    5859op_mode_t op_mode = OP_TASKS;
     60sort_mode_t sort_mode = SORT_TASK_CYCLES;
    5961bool excs_all = false;
    6062
     
    6769        target->tasks = NULL;
    6870        target->tasks_perc = NULL;
     71        target->tasks_map = NULL;
    6972        target->threads = NULL;
    7073        target->exceptions = NULL;
    7174        target->exceptions_perc = NULL;
    7275        target->physmem = NULL;
     76        target->ucycles_diff = NULL;
     77        target->kcycles_diff = NULL;
     78        target->ecycles_diff = NULL;
     79        target->ecount_diff = NULL;
    7380       
    7481        /* Get current time */
     
    113120                return "Not enough memory for task utilization";
    114121       
     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       
    115127        /* Get threads */
    116128        target->threads = stats_get_threads(&(target->threads_count));
     
    132144        if (target->physmem == NULL)
    133145                return "Cannot get physical memory";
     146       
     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";
    134167       
    135168        return NULL;
     
    142175 *
    143176 */
    144 static const char *compute_percentages(data_t *old_data, data_t *new_data)
    145 {
    146         /* Allocate memory */
    147        
    148         uint64_t *ucycles_diff = calloc(new_data->tasks_count,
    149             sizeof(uint64_t));
    150         if (ucycles_diff == NULL)
    151                 return "Not enough memory for user utilization";
    152        
    153         uint64_t *kcycles_diff = calloc(new_data->tasks_count,
    154             sizeof(uint64_t));
    155         if (kcycles_diff == NULL) {
    156                 free(ucycles_diff);
    157                 return "Not enough memory for kernel utilization";
    158         }
    159        
    160         uint64_t *ecycles_diff = calloc(new_data->exceptions_count,
    161             sizeof(uint64_t));
    162         if (ecycles_diff == NULL) {
    163                 free(ucycles_diff);
    164                 free(kcycles_diff);
    165                 return "Not enough memory for exception cycles utilization";
    166         }
    167        
    168         uint64_t *ecount_diff = calloc(new_data->exceptions_count,
    169             sizeof(uint64_t));
    170         if (ecount_diff == NULL) {
    171                 free(ucycles_diff);
    172                 free(kcycles_diff);
    173                 free(ecycles_diff);
    174                 return "Not enough memory for exception count utilization";
    175         }
    176        
    177         /* For each CPU: Compute total ticks and divide it between
     177static void compute_percentages(data_t *old_data, data_t *new_data)
     178{
     179        /* For each CPU: Compute total cycles and divide it between
    178180           user and kernel */
    179181       
     
    181183        for (i = 0; i < new_data->cpus_count; i++) {
    182184                uint64_t idle =
    183                     new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
     185                    new_data->cpus[i].idle_cycles - old_data->cpus[i].idle_cycles;
    184186                uint64_t busy =
    185                     new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
     187                    new_data->cpus[i].busy_cycles - old_data->cpus[i].busy_cycles;
    186188                uint64_t sum = idle + busy;
    187189               
     
    210212                if (!found) {
    211213                        /* This is newly borned task, ignore it */
    212                         ucycles_diff[i] = 0;
    213                         kcycles_diff[i] = 0;
     214                        new_data->ucycles_diff[i] = 0;
     215                        new_data->kcycles_diff[i] = 0;
    214216                        continue;
    215217                }
    216218               
    217                 ucycles_diff[i] =
     219                new_data->ucycles_diff[i] =
    218220                    new_data->tasks[i].ucycles - old_data->tasks[j].ucycles;
    219                 kcycles_diff[i] =
     221                new_data->kcycles_diff[i] =
    220222                    new_data->tasks[i].kcycles - old_data->tasks[j].kcycles;
    221223               
    222224                virtmem_total += new_data->tasks[i].virtmem;
    223                 ucycles_total += ucycles_diff[i];
    224                 kcycles_total += kcycles_diff[i];
     225                ucycles_total += new_data->ucycles_diff[i];
     226                kcycles_total += new_data->kcycles_diff[i];
    225227        }
    226228       
     
    231233                    new_data->tasks[i].virtmem * 100, virtmem_total);
    232234                FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles,
    233                     ucycles_diff[i] * 100, ucycles_total);
     235                    new_data->ucycles_diff[i] * 100, ucycles_total);
    234236                FRACTION_TO_FLOAT(new_data->tasks_perc[i].kcycles,
    235                     kcycles_diff[i] * 100, kcycles_total);
     237                    new_data->kcycles_diff[i] * 100, kcycles_total);
    236238        }
    237239       
     
    259261                if (!found) {
    260262                        /* This is a new exception, ignore it */
    261                         ecycles_diff[i] = 0;
    262                         ecount_diff[i] = 0;
     263                        new_data->ecycles_diff[i] = 0;
     264                        new_data->ecount_diff[i] = 0;
    263265                        continue;
    264266                }
    265267               
    266                 ecycles_diff[i] =
     268                new_data->ecycles_diff[i] =
    267269                    new_data->exceptions[i].cycles - old_data->exceptions[j].cycles;
    268                 ecount_diff[i] =
     270                new_data->ecount_diff[i] =
    269271                    new_data->exceptions[i].count - old_data->exceptions[i].count;
    270272               
    271                 ecycles_total += ecycles_diff[i];
    272                 ecount_total += ecount_diff[i];
     273                ecycles_total += new_data->ecycles_diff[i];
     274                ecount_total += new_data->ecount_diff[i];
    273275        }
    274276       
     
    277279        for (i = 0; i < new_data->exceptions_count; i++) {
    278280                FRACTION_TO_FLOAT(new_data->exceptions_perc[i].cycles,
    279                     ecycles_diff[i] * 100, ecycles_total);
     281                    new_data->ecycles_diff[i] * 100, ecycles_total);
    280282                FRACTION_TO_FLOAT(new_data->exceptions_perc[i].count,
    281                     ecount_diff[i] * 100, ecount_total);
    282         }
    283        
    284         /* Cleanup */
    285        
    286         free(ucycles_diff);
    287         free(kcycles_diff);
    288         free(ecycles_diff);
    289         free(ecount_diff);
    290        
    291         return NULL;
     283                    new_data->ecount_diff[i] * 100, ecount_total);
     284        }
     285}
     286
     287static 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
     305static 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);
    292314}
    293315
     
    320342        if (target->physmem != NULL)
    321343                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);
    322356}
    323357
     
    335369       
    336370        /* Compute some rubbish to have initialised values */
    337         if ((ret = compute_percentages(&data_prev, &data_prev)) != NULL)
    338                 goto out;
     371        compute_percentages(&data_prev, &data_prev);
    339372       
    340373        /* And paint screen until death */
     
    347380                        }
    348381                       
    349                         if ((ret = compute_percentages(&data_prev, &data)) != NULL) {
    350                                 free_data(&data);
    351                                 goto out;
    352                         }
    353                        
     382                        compute_percentages(&data_prev, &data);
     383                        sort_data(&data);
    354384                        print_data(&data);
    355385                        free_data(&data_prev);
Note: See TracChangeset for help on using the changeset viewer.