Ignore:
File:
1 edited

Legend:

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

    r933cadf r3d482e0  
    11/*
    22 * Copyright (c) 2010 Stanislav Kozina
    3  * Copyright (c) 2010 Martin Decky
    43 * All rights reserved.
    54 *
     
    3736
    3837#include <stdio.h>
    39 #include <task.h>
    40 #include <thread.h>
    4138#include <stats.h>
    42 #include <errno.h>
    43 #include <stdlib.h>
     39#include <sys/time.h>
     40#include <inttypes.h>
    4441#include <malloc.h>
    45 #include <inttypes.h>
    46 #include <bool.h>
    47 #include <str.h>
    48 #include <arg_parse.h>
    4942
    50 #define NAME  "stats"
     43#define NAME  "sysstat"
    5144
    5245#define DAY     86400
     
    5447#define MINUTE  60
    5548
    56 static void list_tasks(void)
     49int main(int argc, char *argv[])
    5750{
    58         size_t count;
    59         stats_task_t *stats_tasks = stats_get_tasks(&count);
    60        
    61         if (stats_tasks == NULL) {
    62                 fprintf(stderr, "%s: Unable to get tasks\n", NAME);
    63                 return;
     51        struct timeval time;
     52        if (gettimeofday(&time, NULL) != 0) {
     53                fprintf(stderr, "%s: Cannot get time of day\n", NAME);
     54                return -1;
    6455        }
    6556       
    66         printf("[taskid] [thrds] [resident] [virtual] [ucycles]"
    67             " [kcycles] [name\n");
     57        uint64_t sec = time.tv_sec;
     58        printf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64, (sec % DAY) / HOUR,
     59            (sec % HOUR) / MINUTE, sec % MINUTE);
    6860       
    69         size_t i;
    70         for (i = 0; i < count; i++) {
    71                 uint64_t resmem;
    72                 uint64_t virtmem;
    73                 uint64_t ucycles;
    74                 uint64_t kcycles;
    75                 const char *resmem_suffix;
    76                 const char *virtmem_suffix;
    77                 char usuffix;
    78                 char ksuffix;
    79                
    80                 bin_order_suffix(stats_tasks[i].resmem, &resmem, &resmem_suffix, true);
    81                 bin_order_suffix(stats_tasks[i].virtmem, &virtmem, &virtmem_suffix, true);
    82                 order_suffix(stats_tasks[i].ucycles, &ucycles, &usuffix);
    83                 order_suffix(stats_tasks[i].kcycles, &kcycles, &ksuffix);
    84                
    85                 printf("%-8" PRIu64 " %7zu %7" PRIu64 "%s %6" PRIu64 "%s"
    86                     " %8" PRIu64 "%c %8" PRIu64 "%c %s\n",
    87                     stats_tasks[i].task_id, stats_tasks[i].threads,
    88                     resmem, resmem_suffix, virtmem, virtmem_suffix,
    89                     ucycles, usuffix, kcycles, ksuffix, stats_tasks[i].name);
    90         }
     61        sysarg_t uptime = stats_get_uptime();
     62        printf(", up %u days, %u hours, %u minutes, %u seconds", uptime / DAY,
     63            (uptime % DAY) / HOUR, (uptime % HOUR) / MINUTE, uptime % MINUTE);
    9164       
    92         free(stats_tasks);
    93 }
    94 
    95 static void list_threads(task_id_t task_id, bool all)
    96 {
    97         size_t count;
    98         stats_thread_t *stats_threads = stats_get_threads(&count);
    99        
    100         if (stats_threads == NULL) {
    101                 fprintf(stderr, "%s: Unable to get threads\n", NAME);
    102                 return;
    103         }
    104        
    105         printf("[taskid] [threadid] [state ] [prio] [cpu ] [ucycles] [kcycles]\n");
    106        
    107         size_t i;
    108         for (i = 0; i < count; i++) {
    109                 if ((all) || (stats_threads[i].task_id == task_id)) {
    110                         uint64_t ucycles, kcycles;
    111                         char usuffix, ksuffix;
    112                        
    113                         order_suffix(stats_threads[i].ucycles, &ucycles, &usuffix);
    114                         order_suffix(stats_threads[i].kcycles, &kcycles, &ksuffix);
    115                        
    116                         printf("%-8" PRIu64 " %-10" PRIu64 " %-8s %6d ",
    117                             stats_threads[i].task_id, stats_threads[i].thread_id,
    118                             thread_get_state(stats_threads[i].state),
    119                             stats_threads[i].priority);
    120                        
    121                         if (stats_threads[i].on_cpu)
    122                                 printf("%6u ", stats_threads[i].cpu);
    123                         else
    124                                 printf("(none) ");
    125                        
    126                         printf("%8" PRIu64"%c %8" PRIu64"%c\n",
    127                             ucycles, usuffix, kcycles, ksuffix);
    128                 }
    129         }
    130        
    131         free(stats_threads);
    132 }
    133 
    134 static void list_cpus(void)
    135 {
    136         size_t count;
    137         stats_cpu_t *cpus = stats_get_cpus(&count);
    138        
    139         if (cpus == NULL) {
    140                 fprintf(stderr, "%s: Unable to get CPU statistics\n", NAME);
    141                 return;
    142         }
    143        
    144         printf("[id] [MHz     ] [busy cycles] [idle cycles]\n");
    145        
    146         size_t i;
    147         for (i = 0; i < count; i++) {
    148                 printf("%-4u ", cpus[i].id);
    149                 if (cpus[i].active) {
    150                         uint64_t bcycles, icycles;
    151                         char bsuffix, isuffix;
    152                        
    153                         order_suffix(cpus[i].busy_cycles, &bcycles, &bsuffix);
    154                         order_suffix(cpus[i].idle_cycles, &icycles, &isuffix);
    155                        
    156                         printf("%10" PRIu16 " %12" PRIu64 "%c %12" PRIu64 "%c\n",
    157                             cpus[i].frequency_mhz, bcycles, bsuffix,
    158                             icycles, isuffix);
    159                 } else
    160                         printf("inactive\n");
    161         }
    162        
    163         free(cpus);
    164 }
    165 
    166 static void print_load(void)
    167 {
    16865        size_t count;
    16966        load_t *load = stats_get_load(&count);
    170        
    171         if (load == NULL) {
    172                 fprintf(stderr, "%s: Unable to get load\n", NAME);
    173                 return;
    174         }
    175        
    176         printf("%s: Load average: ", NAME);
    177        
    178         size_t i;
    179         for (i = 0; i < count; i++) {
    180                 if (i > 0)
    181                         printf(" ");
     67        if (load != NULL) {
     68                printf(", load average: ");
    18269               
    183                 stats_print_load_fragment(load[i], 2);
     70                size_t i;
     71                for (i = 0; i < count; i++) {
     72                        if (i > 0)
     73                                printf(" ");
     74                       
     75                        stats_print_load_fragment(load[i], 2);
     76                }
     77               
     78                free(load);
    18479        }
    18580       
    18681        printf("\n");
    187        
    188         free(load);
    189 }
    190 
    191 static void print_uptime(void)
    192 {
    193         sysarg_t uptime = stats_get_uptime();
    194         printf("%s: Up %" PRIun " days, %" PRIun " hours, "
    195             "%" PRIun " minutes, %" PRIun " seconds\n", NAME,
    196             uptime / DAY, (uptime % DAY) / HOUR,
    197             (uptime % HOUR) / MINUTE, uptime % MINUTE);
    198 }
    199 
    200 static void usage(const char *name)
    201 {
    202         printf(
    203             "Usage: %s [-t task_id] [-a] [-c] [-l] [-u]\n" \
    204             "\n" \
    205             "Options:\n" \
    206             "\t-t task_id\n" \
    207             "\t--task=task_id\n" \
    208             "\t\tList threads of the given task\n" \
    209             "\n" \
    210             "\t-a\n" \
    211             "\t--all\n" \
    212             "\t\tList all threads\n" \
    213             "\n" \
    214             "\t-c\n" \
    215             "\t--cpus\n" \
    216             "\t\tList CPUs\n" \
    217             "\n" \
    218             "\t-l\n" \
    219             "\t--load\n" \
    220             "\t\tPrint system load\n" \
    221             "\n" \
    222             "\t-u\n" \
    223             "\t--uptime\n" \
    224             "\t\tPrint system uptime\n" \
    225             "\n" \
    226             "\t-h\n" \
    227             "\t--help\n" \
    228             "\t\tPrint this usage information\n"
    229             "\n" \
    230             "Without any options all tasks are listed\n",
    231             name
    232         );
    233 }
    234 
    235 int main(int argc, char *argv[])
    236 {
    237         bool toggle_tasks = true;
    238         bool toggle_threads = false;
    239         bool toggle_all = false;
    240         bool toggle_cpus = false;
    241         bool toggle_load = false;
    242         bool toggle_uptime = false;
    243        
    244         task_id_t task_id = 0;
    245        
    246         int i;
    247         for (i = 1; i < argc; i++) {
    248                 int off;
    249                
    250                 /* Usage */
    251                 if ((off = arg_parse_short_long(argv[i], "-h", "--help")) != -1) {
    252                         usage(argv[0]);
    253                         return 0;
    254                 }
    255                
    256                 /* All threads */
    257                 if ((off = arg_parse_short_long(argv[i], "-a", "--all")) != -1) {
    258                         toggle_tasks = false;
    259                         toggle_threads = true;
    260                         toggle_all = true;
    261                         continue;
    262                 }
    263                
    264                 /* CPUs */
    265                 if ((off = arg_parse_short_long(argv[i], "-c", "--cpus")) != -1) {
    266                         toggle_tasks = false;
    267                         toggle_cpus = true;
    268                         continue;
    269                 }
    270                
    271                 /* Threads */
    272                 if ((off = arg_parse_short_long(argv[i], "-t", "--task=")) != -1) {
    273                         // TODO: Support for 64b range
    274                         int tmp;
    275                         int ret = arg_parse_int(argc, argv, &i, &tmp, off);
    276                         if (ret != EOK) {
    277                                 printf("%s: Malformed task_id '%s'\n", NAME, argv[i]);
    278                                 return -1;
    279                         }
    280                        
    281                         task_id = tmp;
    282                        
    283                         toggle_tasks = false;
    284                         toggle_threads = true;
    285                         continue;
    286                 }
    287                
    288                 /* Load */
    289                 if ((off = arg_parse_short_long(argv[i], "-l", "--load")) != -1) {
    290                         toggle_tasks = false;
    291                         toggle_load = true;
    292                         continue;
    293                 }
    294                
    295                 /* Uptime */
    296                 if ((off = arg_parse_short_long(argv[i], "-u", "--uptime")) != -1) {
    297                         toggle_tasks = false;
    298                         toggle_uptime = true;
    299                         continue;
    300                 }
    301         }
    302        
    303         if (toggle_tasks)
    304                 list_tasks();
    305        
    306         if (toggle_threads)
    307                 list_threads(task_id, toggle_all);
    308        
    309         if (toggle_cpus)
    310                 list_cpus();
    311        
    312         if (toggle_load)
    313                 print_load();
    314        
    315         if (toggle_uptime)
    316                 print_uptime();
    317        
    31882        return 0;
    31983}
Note: See TracChangeset for help on using the changeset viewer.