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

Changeset d0c82c5 in mainline


Ignore:
Timestamp:
2010-06-16T19:44:53Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
5387807
Parents:
5954241
Message:

perfect CPU cycles accounting, cherry-picked and adopted from lp:~ersin/helenos/measure2

Files:
10 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/cpu.h

    r5954241 rd0c82c5  
    7272        size_t missed_clock_ticks;
    7373       
     74        /**
     75         * Processor cycle accounting.
     76         */
    7477        bool idle;
    75         uint64_t idle_ticks;
    76         uint64_t busy_ticks;
     78        uint64_t last_cycle;
     79        uint64_t idle_cycles;
     80        uint64_t busy_cycles;
    7781       
    7882        /**
  • kernel/generic/include/sysinfo/abi.h

    r5954241 rd0c82c5  
    6969        bool active;             /**< CPU is activate */
    7070        uint16_t frequency_mhz;  /**< Frequency in MHz */
    71         uint64_t idle_ticks;     /**< Number of idle kernel quanta */
    72         uint64_t busy_ticks;     /**< Number of busy kernel quanta */
     71        uint64_t idle_cycles;    /**< Number of idle cycles */
     72        uint64_t busy_cycles;    /**< Number of busy cycles */
    7373} stats_cpu_t;
    7474
  • kernel/generic/src/cpu/cpu.c

    r5954241 rd0c82c5  
    4949#include <print.h>
    5050#include <sysinfo/sysinfo.h>
     51#include <arch/cycle.h>
    5152
    5253cpu_t *cpus;
     
    9495        CPU->tlb_active = true;
    9596       
     97        CPU->idle = false;
     98        CPU->last_cycle = get_cycle();
     99        CPU->idle_cycles = 0;
     100        CPU->busy_cycles = 0;
     101       
    96102        cpu_identify();
    97103        cpu_arch_init();
  • kernel/generic/src/interrupt/interrupt.c

    r5954241 rd0c82c5  
    9999void exc_dispatch(unsigned int n, istate_t *istate)
    100100{
     101        ASSERT(CPU);
     102       
    101103#if (IVT_ITEMS > 0)
    102104        ASSERT(n < IVT_ITEMS);
     
    109111                irq_spinlock_unlock(&THREAD->lock, false);
    110112        }
     113       
     114        /* Account CPU usage if it has waked up from sleep */
     115        irq_spinlock_lock(&CPU->lock, false);
     116        if (CPU->idle) {
     117                uint64_t now = get_cycle();
     118                CPU->idle_cycles += now - CPU->last_cycle;
     119                CPU->last_cycle = now;
     120                CPU->idle = false;
     121        }
     122        irq_spinlock_unlock(&CPU->lock, false);
    111123       
    112124        uint64_t begin_cycle = get_cycle();
  • kernel/generic/src/proc/scheduler.c

    r5954241 rd0c82c5  
    193193                 * This improves energy saving and hyperthreading.
    194194                 */
    195                
    196                  /* Mark CPU as it was idle this clock tick */
    197195                irq_spinlock_lock(&CPU->lock, false);
    198196                CPU->idle = true;
    199197                irq_spinlock_unlock(&CPU->lock, false);
    200                
    201198                interrupts_enable();
     199               
    202200                /*
    203201                 * An interrupt might occur right now and wake up a thread.
     
    386384        as_t *old_as = AS;
    387385       
    388         ASSERT(!THREAD || irq_spinlock_locked(&THREAD->lock));
     386        ASSERT((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
    389387        ASSERT(CPU != NULL);
    390388       
  • kernel/generic/src/sysinfo/stats.c

    r5954241 rd0c82c5  
    124124                stats_cpus[i].active = cpus[i].active;
    125125                stats_cpus[i].frequency_mhz = cpus[i].frequency_mhz;
    126                 stats_cpus[i].busy_ticks = cpus[i].busy_ticks;
    127                 stats_cpus[i].idle_ticks = cpus[i].idle_ticks;
     126                stats_cpus[i].busy_cycles = cpus[i].busy_cycles;
     127                stats_cpus[i].idle_cycles = cpus[i].idle_cycles;
    128128               
    129129                irq_spinlock_unlock(&cpus[i].lock, true);
  • kernel/generic/src/time/clock.c

    r5954241 rd0c82c5  
    5757#include <mm/frame.h>
    5858#include <ddi/ddi.h>
     59#include <arch/cycle.h>
    5960
    6061/* Pointer to variable with uptime */
     
    125126}
    126127
     128static void cpu_update_accounting(void)
     129{
     130        irq_spinlock_lock(&CPU->lock, false);
     131        uint64_t now = get_cycle();
     132        CPU->busy_cycles += now - CPU->last_cycle;
     133        CPU->last_cycle = now;
     134        irq_spinlock_unlock(&CPU->lock, false);
     135}
     136
    127137/** Clock routine
    128138 *
     
    136146        size_t missed_clock_ticks = CPU->missed_clock_ticks;
    137147       
    138         /* Account lost ticks to CPU usage */
    139         if (CPU->idle)
    140                 CPU->idle_ticks += missed_clock_ticks + 1;
    141         else
    142                 CPU->busy_ticks += missed_clock_ticks + 1;
    143        
    144         CPU->idle = false;
     148        /* Account CPU usage */
     149        cpu_update_accounting();
    145150       
    146151        /*
     
    151156        size_t i;
    152157        for (i = 0; i <= missed_clock_ticks; i++) {
     158                /* Update counters and accounting */
    153159                clock_update_counters();
     160                cpu_update_accounting();
     161               
    154162                irq_spinlock_lock(&CPU->timeoutlock, false);
    155163               
  • uspace/app/tasks/tasks.c

    r5954241 rd0c82c5  
    165165        for (i = 0; i < count; i++) {
    166166                if (cpus[i].active) {
    167                         printf("cpu%u: %" PRIu16 " MHz, busy ticks: "
    168                             "%" PRIu64 ", idle ticks: %" PRIu64 "\n",
    169                             cpus[i].id, cpus[i].frequency_mhz, cpus[i].busy_ticks,
    170                             cpus[i].idle_ticks);
     167                        printf("cpu%u: %" PRIu16 " MHz, busy cycles: "
     168                            "%" PRIu64 ", idle cycles: %" PRIu64 "\n",
     169                            cpus[i].id, cpus[i].frequency_mhz, cpus[i].busy_cycles,
     170                            cpus[i].idle_cycles);
    171171                } else {
    172172                        printf("cpu%u: inactive\n", cpus[i].id);
  • uspace/app/top/screen.c

    r5954241 rd0c82c5  
    222222        for (i = 0; i < data->cpus_count; i++) {
    223223                if (data->cpus[i].active) {
    224                         printf("cpu%u (%4" PRIu16 " MHz): busy ticks: "
    225                             "%" PRIu64 ", idle ticks: %" PRIu64,
     224                        uint64_t busy;
     225                        uint64_t idle;
     226                        char busy_suffix;
     227                        char idle_suffix;
     228                       
     229                        order_suffix(data->cpus[i].busy_cycles, &busy, &busy_suffix);
     230                        order_suffix(data->cpus[i].idle_cycles, &idle, &idle_suffix);
     231                       
     232                        printf("cpu%u (%4" PRIu16 " MHz): busy cycles: "
     233                            "%" PRIu64 "%c, idle cycles: %" PRIu64 "%c",
    226234                            data->cpus[i].id, data->cpus[i].frequency_mhz,
    227                             data->cpus[i].busy_ticks, data->cpus[i].idle_ticks);
     235                            busy, busy_suffix, idle, idle_suffix);
    228236                        puts(", idle: ");
    229237                        print_percent(data->cpus_perc[i].idle, 2);
  • uspace/app/top/top.c

    r5954241 rd0c82c5  
    175175        }
    176176       
    177         /* For each CPU: Compute total ticks and divide it between
     177        /* For each CPU: Compute total cycles and divide it between
    178178           user and kernel */
    179179       
     
    181181        for (i = 0; i < new_data->cpus_count; i++) {
    182182                uint64_t idle =
    183                     new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
     183                    new_data->cpus[i].idle_cycles - old_data->cpus[i].idle_cycles;
    184184                uint64_t busy =
    185                     new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
     185                    new_data->cpus[i].busy_cycles - old_data->cpus[i].busy_cycles;
    186186                uint64_t sum = idle + busy;
    187187               
Note: See TracChangeset for help on using the changeset viewer.