VirtualBox

Changeset 11086 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Aug 4, 2008 8:19:50 AM (16 years ago)
Author:
vboxsync
Message:

PerfAPI: Solaris implementation

Location:
trunk/src/VBox/Main
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/Makefile.kmk

    r10898 r11086  
    275275VBoxSVC_SOURCES.solaris += solaris/PerformanceSolaris.cpp
    276276VBoxSVC_SOURCES.win     +=     win/PerformanceWin.cpp
     277VBoxSVC_LDFLAGS.solaris += -lkstat
    277278VBoxSVC_LDFLAGS.win     += wbemuuid.lib
    278279endif
  • trunk/src/VBox/Main/solaris/PerformanceSolaris.cpp

    r10993 r11086  
    2323
    2424#include <stdio.h>
     25#include <errno.h>
     26#include <fcntl.h>
     27#include <kstat.h>
     28#include <sys/sysinfo.h>
     29#include <sys/time.h>
     30#include <procfs.h>
     31
     32#include <iprt/err.h>
     33#include <iprt/string.h>
     34#include <iprt/alloc.h>
     35#include <iprt/param.h>
     36#include <VBox/log.h>
    2537#include "Performance.h"
    2638
     
    3042{
    3143public:
     44    CollectorSolaris();
     45    ~CollectorSolaris();
    3246    virtual int getHostCpuMHz(unsigned long *mhz);
    3347    virtual int getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available);
     
    3650    virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
    3751    virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
     52private:
     53    kstat_ctl_t *mKC;
     54    kstat_t     *mSysPages;
    3855};
    3956
     
    4663}
    4764
    48 BaseMetric *MetricFactorySolaris::createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
    49 {
    50     Assert(mHAL);
    51     return new HostCpuLoadRaw(mHAL, object, user, kernel, idle);
    52 }
    53 
    54 BaseMetric *MetricFactorySolaris::createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
    55 {
    56     Assert(mHAL);
    57     return new MachineCpuLoadRaw(mHAL, object, process, user, kernel);
    58 }
    59 
    6065// Collector HAL for Solaris
    6166
     67
     68CollectorSolaris::CollectorSolaris() : mKC(0), mSysPages(0)
     69{
     70    if ((mKC = kstat_open()) == 0)
     71    {
     72        Log(("kstat_open() -> %d\n", errno));
     73        return;
     74    }
     75
     76    if ((mSysPages = kstat_lookup(mKC, "unix", 0, "system_pages")) == 0)
     77    {
     78        Log(("kstat_lookup(system_pages) -> %d\n", errno));
     79        return;
     80    }
     81}
     82
     83CollectorSolaris::~CollectorSolaris()
     84{
     85    kstat_close(mKC);
     86}
     87
    6288int CollectorSolaris::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
    6389{
    64 #ifdef RT_OS_LINUX
    65     int rc = VINF_SUCCESS;
    66     unsigned long nice;
    67     FILE *f = fopen("/proc/stat", "r");
    68 
    69     if (f)
    70     {
    71         if (fscanf(f, "cpu %lu %lu %lu %lu", user, &nice, kernel, idle) == 4)
    72             *user += nice;
     90    int rc = VINF_SUCCESS;
     91    kstat_t *ksp;
     92    uint64_t tmpUser, tmpKernel, tmpIdle;
     93    int cpus;
     94    cpu_stat_t cpu_stats;
     95   
     96    if (mKC == 0)
     97        return VERR_INTERNAL_ERROR;
     98   
     99    tmpUser = tmpKernel = tmpIdle = cpus = 0;
     100    for (ksp = mKC->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
     101        if (strcmp(ksp->ks_module, "cpu_stat") == 0) {
     102            if (kstat_read(mKC, ksp, &cpu_stats) == -1)
     103            {
     104                Log(("kstat_read() -> %d", errno));
     105                return VERR_INTERNAL_ERROR;
     106            }
     107            ++cpus;
     108            tmpUser   += cpu_stats.cpu_sysinfo.cpu[CPU_USER];
     109            tmpKernel += cpu_stats.cpu_sysinfo.cpu[CPU_KERNEL];
     110            tmpIdle   += cpu_stats.cpu_sysinfo.cpu[CPU_IDLE];
     111        }         
     112    }
     113   
     114    if (cpus == 0)
     115    {
     116        Log(("no cpu stats found!\n"));
     117        return VERR_INTERNAL_ERROR;
     118    }
     119
     120    if (user)   *user   = tmpUser;
     121    if (kernel) *kernel = tmpKernel;
     122    if (idle)   *idle   = tmpIdle;
     123
     124    return rc;
     125}
     126
     127int CollectorSolaris::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total)
     128{
     129    int rc = VINF_SUCCESS;
     130    char *pszName;
     131    prusage_t prusage;
     132
     133    RTStrAPrintf(&pszName, "/proc/%d/usage", process);
     134    Log(("Opening %s...\n", pszName));
     135    int h = open(pszName, O_RDONLY);
     136    RTMemFree(pszName);
     137
     138    if (h != -1)
     139    {
     140        if (read(h, &prusage, sizeof(prusage)) == sizeof(prusage))
     141        {
     142            //Assert((pid_t)process == pstatus.pr_pid);
     143            //Log(("user=%u kernel=%u total=%u\n", prusage.pr_utime.tv_sec, prusage.pr_stime.tv_sec, prusage.pr_tstamp.tv_sec));
     144            *user = (uint64_t)prusage.pr_utime.tv_sec * 1000000000 + prusage.pr_utime.tv_nsec;
     145            *kernel = (uint64_t)prusage.pr_stime.tv_sec * 1000000000 + prusage.pr_stime.tv_nsec;
     146            *total = (uint64_t)prusage.pr_tstamp.tv_sec * 1000000000 + prusage.pr_tstamp.tv_nsec;
     147            //Log(("user=%llu kernel=%llu total=%llu\n", *user, *kernel, *total));
     148        }
    73149        else
     150        {
     151            Log(("read() -> %d", errno));
    74152            rc = VERR_FILE_IO_ERROR;
    75         fclose(f);
     153        }
     154        close(h);
    76155    }
    77156    else
     157    {
     158        Log(("open() -> %d", errno));
    78159        rc = VERR_ACCESS_DENIED;
    79 
    80     return rc;
    81 #else
    82     return E_NOTIMPL;
    83 #endif
    84 }
    85 
    86 int CollectorSolaris::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total)
    87 {
    88 #ifdef RT_OS_LINUX
     160    }
     161
     162    return rc;
     163}
     164
     165int CollectorSolaris::getHostCpuMHz(unsigned long *mhz)
     166{
     167    return VERR_NOT_IMPLEMENTED;
     168}
     169
     170int CollectorSolaris::getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available)
     171{
     172    int rc = VINF_SUCCESS;
     173
     174    kstat_named_t *kn;
     175   
     176    if (mKC == 0 || mSysPages == 0)
     177        return VERR_INTERNAL_ERROR;
     178
     179    if (kstat_read(mKC, mSysPages, 0) == -1)
     180    {
     181        Log(("kstat_read(sys_pages) -> %d", errno));
     182        return VERR_INTERNAL_ERROR;
     183    }
     184    if ((kn = (kstat_named_t *)kstat_data_lookup(mSysPages, "freemem")) == 0)
     185    {
     186        Log(("kstat_data_lookup(freemem) -> %d", errno));
     187        return VERR_INTERNAL_ERROR;
     188    }
     189    *available = kn->value.ul * (PAGE_SIZE/1024);
     190    if ((kn = (kstat_named_t *)kstat_data_lookup(mSysPages, "physmem")) == 0)
     191    {
     192        Log(("kstat_data_lookup(physmem) -> %d", errno));
     193        return VERR_INTERNAL_ERROR;
     194    }
     195    *total = kn->value.ul * (PAGE_SIZE/1024);
     196    *used = *total - *available;
     197
     198    return rc;
     199}
     200int CollectorSolaris::getProcessMemoryUsage(RTPROCESS process, unsigned long *used)
     201{
    89202    int rc = VINF_SUCCESS;
    90203    char *pszName;
    91204    pid_t pid2;
    92     char c;
    93     int iTmp;
    94     unsigned uTmp;
    95     unsigned long ulTmp;
    96205    char buf[80]; /* @todo: this should be tied to max allowed proc name. */
    97 
    98     RTStrAPrintf(&pszName, "/proc/%d/stat", process);
    99     //printf("Opening %s...\n", pszName);
    100     FILE *f = fopen(pszName, "r");
     206    psinfo_t psinfo;
     207
     208    RTStrAPrintf(&pszName, "/proc/%d/psinfo", process);
     209    Log(("Opening %s...\n", pszName));
     210    int h = open(pszName, O_RDONLY);
    101211    RTMemFree(pszName);
    102212
    103     if (f)
    104     {
    105         if (fscanf(f, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu",
    106                    &pid2, buf, &c, &iTmp, &iTmp, &iTmp, &iTmp, &iTmp, &uTmp,
    107                    &ulTmp, &ulTmp, &ulTmp, &ulTmp, user, kernel) == 15)
    108         {
    109             Assert((pid_t)process == pid2);
     213    if (h != -1)
     214    {
     215        if (read(h, &psinfo, sizeof(psinfo)) == sizeof(psinfo))
     216        {
     217            Assert((pid_t)process == psinfo.pr_pid);
     218            *used = psinfo.pr_rssize;
    110219        }
    111220        else
     221        {
     222            Log(("read() -> %d", errno));
    112223            rc = VERR_FILE_IO_ERROR;
    113         fclose(f);
     224        }
     225        close(h);
    114226    }
    115227    else
     228    {
     229        Log(("open() -> %d", errno));
    116230        rc = VERR_ACCESS_DENIED;
    117 
    118     return rc;
    119 #else
    120     return E_NOTIMPL;
    121 #endif
    122 }
    123 
    124 int CollectorSolaris::getHostCpuMHz(unsigned long *mhz)
    125 {
    126     return E_NOTIMPL;
    127 }
    128 
    129 int CollectorSolaris::getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available)
    130 {
    131 #ifdef RT_OS_LINUX
    132     int rc = VINF_SUCCESS;
    133     unsigned long buffers, cached;
    134     FILE *f = fopen("/proc/meminfo", "r");
    135 
    136     if (f)
    137     {
    138         int processed = fscanf(f, "MemTotal: %lu kB", total);
    139         processed    += fscanf(f, "MemFree: %lu kB", available);
    140         processed    += fscanf(f, "Buffers: %lu kB", &buffers);
    141         processed    += fscanf(f, "Cached: %lu kB", &cached);
    142         if (processed == 4)
    143             *available += buffers + cached;
    144         else
    145             rc = VERR_FILE_IO_ERROR;
    146         fclose(f);
    147     }
    148     else
    149         rc = VERR_ACCESS_DENIED;
    150 
    151     return rc;
    152 #else
    153     return E_NOTIMPL;
    154 #endif
    155 }
    156 int CollectorSolaris::getProcessMemoryUsage(RTPROCESS process, unsigned long *used)
    157 {
    158     return E_NOTIMPL;
    159 }
    160 
    161 }
     231    }
     232
     233    return rc;
     234}
     235
     236}
     237
  • trunk/src/VBox/Main/testcase/Makefile.kmk

    r10942 r11086  
    112112        ../Performance.cpp
    113113tstCollector_INCS     = ../include
     114tstCollector_LDFLAGS.solaris += -lkstat
    114115tstCollector_LDFLAGS.win += wbemuuid.lib
    115116
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette