Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/sysinfo/stats.c

    r9efff92 r6e121b8  
    3838#include <sysinfo/stats.h>
    3939#include <sysinfo/sysinfo.h>
     40#include <synch/spinlock.h>
     41#include <synch/mutex.h>
    4042#include <time/clock.h>
    4143#include <mm/frame.h>
     
    6870static load_t avenrdy[LOAD_STEPS] = {0, 0, 0};
    6971
    70 /** Load calculation spinlock */
    71 SPINLOCK_STATIC_INITIALIZE_NAME(load_lock, "load_lock");
     72/** Load calculation lock */
     73static mutex_t load_lock;
    7274
    7375/** Get system uptime
     
    156158static size_t get_task_virtmem(as_t *as)
    157159{
    158         mutex_lock(&as->lock);
    159        
    160160        size_t result = 0;
     161
     162        /*
     163         * We are holding some spinlocks here and therefore are not allowed to
     164         * block. Only attempt to lock the address space and address space area
     165         * mutexes conditionally. If it is not possible to lock either object,
     166         * allow the statistics to be inexact by skipping the respective object.
     167         *
     168         * Note that it may be infinitely better to let the address space
     169         * management code compute these statistics as it proceeds instead of
     170         * having them calculated here over and over again here.
     171         */
     172
     173        if (SYNCH_FAILED(mutex_trylock(&as->lock)))
     174                return result * PAGE_SIZE;
    161175       
    162176        /* Walk the B+ tree and count pages */
     
    171185                        as_area_t *area = node->value[i];
    172186                       
    173                         mutex_lock(&area->lock);
     187                        if (SYNCH_FAILED(mutex_trylock(&area->lock)))
     188                                continue;
    174189                        result += area->pages;
    175190                        mutex_unlock(&area->lock);
     
    331346       
    332347        /* Interrupts are already disabled */
    333         spinlock_lock(&(thread->lock));
     348        spinlock_lock(&thread->lock);
    334349       
    335350        /* Record the statistics and increment the iterator */
     
    337352        (*iterator)++;
    338353       
    339         spinlock_unlock(&(thread->lock));
     354        spinlock_unlock(&thread->lock);
    340355       
    341356        return true;
     
    602617        }
    603618       
    604         /* To always get consistent values acquire the spinlock */
    605         ipl_t ipl = interrupts_disable();
    606         spinlock_lock(&load_lock);
     619        /* To always get consistent values acquire the mutex */
     620        mutex_lock(&load_lock);
    607621       
    608622        unsigned int i;
     
    610624                stats_load[i] = avenrdy[i] << LOAD_FIXED_SHIFT;
    611625       
    612         spinlock_unlock(&load_lock);
    613         interrupts_restore(ipl);
     626        mutex_unlock(&load_lock);
    614627       
    615628        return ((void *) stats_load);
     
    642655               
    643656                /* Mutually exclude with get_stats_load() */
    644                 ipl_t ipl = interrupts_disable();
    645                 spinlock_lock(&load_lock);
     657                mutex_lock(&load_lock);
    646658               
    647659                unsigned int i;
     
    649661                        avenrdy[i] = load_calc(avenrdy[i], load_exp[i], ready);
    650662               
    651                 spinlock_unlock(&load_lock);
    652                 interrupts_restore(ipl);
     663                mutex_unlock(&load_lock);
    653664               
    654665                thread_sleep(LOAD_INTERVAL);
     
    661672void stats_init(void)
    662673{
     674        mutex_initialize(&load_lock, MUTEX_PASSIVE);
     675
    663676        sysinfo_set_item_fn_val("system.uptime", NULL, get_stats_uptime);
    664677        sysinfo_set_item_fn_data("system.cpus", NULL, get_stats_cpus);
Note: See TracChangeset for help on using the changeset viewer.