~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Main/src-server/linux/PerformanceLinux.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: PerformanceLinux.cpp 33992 2010-11-11 13:57:03Z vboxsync $ */
 
2
 
 
3
/** @file
 
4
 *
 
5
 * VBox Linux-specific Performance Classes implementation.
 
6
 */
 
7
 
 
8
/*
 
9
 * Copyright (C) 2008 Oracle Corporation
 
10
 *
 
11
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
12
 * available from http://www.virtualbox.org. This file is free software;
 
13
 * you can redistribute it and/or modify it under the terms of the GNU
 
14
 * General Public License (GPL) as published by the Free Software
 
15
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 
16
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 
17
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 
18
 */
 
19
 
 
20
#include <stdio.h>
 
21
#include <iprt/alloc.h>
 
22
#include <iprt/err.h>
 
23
#include <iprt/param.h>
 
24
#include <iprt/string.h>
 
25
 
 
26
#include <map>
 
27
#include <vector>
 
28
 
 
29
#include "Logging.h"
 
30
#include "Performance.h"
 
31
 
 
32
namespace pm {
 
33
 
 
34
class CollectorLinux : public CollectorHAL
 
35
{
 
36
public:
 
37
    virtual int preCollect(const CollectorHints& hints, uint64_t /* iTick */);
 
38
    virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
 
39
    virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
 
40
 
 
41
    virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
 
42
    virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
 
43
private:
 
44
    virtual int _getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
 
45
    int getRawProcessStats(RTPROCESS process, uint64_t *cpuUser, uint64_t *cpuKernel, ULONG *memPagesUsed);
 
46
 
 
47
    struct VMProcessStats
 
48
    {
 
49
        uint64_t cpuUser;
 
50
        uint64_t cpuKernel;
 
51
        ULONG    pagesUsed;
 
52
    };
 
53
 
 
54
    typedef std::map<RTPROCESS, VMProcessStats> VMProcessMap;
 
55
 
 
56
    VMProcessMap mProcessStats;
 
57
    uint64_t     mUser, mKernel, mIdle;
 
58
};
 
59
 
 
60
CollectorHAL *createHAL()
 
61
{
 
62
    return new CollectorLinux();
 
63
}
 
64
 
 
65
// Collector HAL for Linux
 
66
 
 
67
int CollectorLinux::preCollect(const CollectorHints& hints, uint64_t /* iTick */)
 
68
{
 
69
    std::vector<RTPROCESS> processes;
 
70
    hints.getProcesses(processes);
 
71
 
 
72
    std::vector<RTPROCESS>::iterator it;
 
73
    for (it = processes.begin(); it != processes.end(); it++)
 
74
    {
 
75
        VMProcessStats vmStats;
 
76
        int rc = getRawProcessStats(*it, &vmStats.cpuUser, &vmStats.cpuKernel, &vmStats.pagesUsed);
 
77
        if (RT_FAILURE(rc))
 
78
            return rc;
 
79
        mProcessStats[*it] = vmStats;
 
80
    }
 
81
    if (hints.isHostCpuLoadCollected() || mProcessStats.size())
 
82
    {
 
83
        _getRawHostCpuLoad(&mUser, &mKernel, &mIdle);
 
84
    }
 
85
    return VINF_SUCCESS;
 
86
}
 
87
 
 
88
int CollectorLinux::_getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
 
89
{
 
90
    int rc = VINF_SUCCESS;
 
91
    ULONG u32user, u32nice, u32kernel, u32idle;
 
92
    FILE *f = fopen("/proc/stat", "r");
 
93
 
 
94
    if (f)
 
95
    {
 
96
        if (fscanf(f, "cpu %u %u %u %u", &u32user, &u32nice, &u32kernel, &u32idle) == 4)
 
97
        {
 
98
            *user   = (uint64_t)u32user + u32nice;
 
99
            *kernel = u32kernel;
 
100
            *idle   = u32idle;
 
101
        }
 
102
        else
 
103
            rc = VERR_FILE_IO_ERROR;
 
104
        fclose(f);
 
105
    }
 
106
    else
 
107
        rc = VERR_ACCESS_DENIED;
 
108
 
 
109
    return rc;
 
110
}
 
111
 
 
112
int CollectorLinux::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
 
113
{
 
114
    *user   = mUser;
 
115
    *kernel = mKernel;
 
116
    *idle   = mIdle;
 
117
    return VINF_SUCCESS;
 
118
}
 
119
 
 
120
int CollectorLinux::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total)
 
121
{
 
122
    VMProcessMap::const_iterator it = mProcessStats.find(process);
 
123
 
 
124
    if (it == mProcessStats.end())
 
125
    {
 
126
        Log (("No stats pre-collected for process %x\n", process));
 
127
        return VERR_INTERNAL_ERROR;
 
128
    }
 
129
    *user   = it->second.cpuUser;
 
130
    *kernel = it->second.cpuKernel;
 
131
    *total  = mUser + mKernel + mIdle;
 
132
    return VINF_SUCCESS;
 
133
}
 
134
 
 
135
int CollectorLinux::getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available)
 
136
{
 
137
    int rc = VINF_SUCCESS;
 
138
    ULONG buffers, cached;
 
139
    FILE *f = fopen("/proc/meminfo", "r");
 
140
 
 
141
    if (f)
 
142
    {
 
143
        int processed = fscanf(f, "MemTotal: %u kB\n", total);
 
144
        processed    += fscanf(f, "MemFree: %u kB\n", available);
 
145
        processed    += fscanf(f, "Buffers: %u kB\n", &buffers);
 
146
        processed    += fscanf(f, "Cached: %u kB\n", &cached);
 
147
        if (processed == 4)
 
148
        {
 
149
            *available += buffers + cached;
 
150
            *used       = *total - *available;
 
151
        }
 
152
        else
 
153
            rc = VERR_FILE_IO_ERROR;
 
154
        fclose(f);
 
155
    }
 
156
    else
 
157
        rc = VERR_ACCESS_DENIED;
 
158
 
 
159
    return rc;
 
160
}
 
161
 
 
162
int CollectorLinux::getProcessMemoryUsage(RTPROCESS process, ULONG *used)
 
163
{
 
164
    VMProcessMap::const_iterator it = mProcessStats.find(process);
 
165
 
 
166
    if (it == mProcessStats.end())
 
167
    {
 
168
        Log (("No stats pre-collected for process %x\n", process));
 
169
        return VERR_INTERNAL_ERROR;
 
170
    }
 
171
    *used = it->second.pagesUsed * (PAGE_SIZE / 1024);
 
172
    return VINF_SUCCESS;
 
173
}
 
174
 
 
175
int CollectorLinux::getRawProcessStats(RTPROCESS process, uint64_t *cpuUser, uint64_t *cpuKernel, ULONG *memPagesUsed)
 
176
{
 
177
    int rc = VINF_SUCCESS;
 
178
    char *pszName;
 
179
    pid_t pid2;
 
180
    char c;
 
181
    int iTmp;
 
182
    long long unsigned int u64Tmp;
 
183
    unsigned uTmp;
 
184
    unsigned long ulTmp;
 
185
    signed long ilTmp;
 
186
    ULONG u32user, u32kernel;
 
187
    char buf[80]; /* @todo: this should be tied to max allowed proc name. */
 
188
 
 
189
    RTStrAPrintf(&pszName, "/proc/%d/stat", process);
 
190
    //printf("Opening %s...\n", pszName);
 
191
    FILE *f = fopen(pszName, "r");
 
192
    RTMemFree(pszName);
 
193
 
 
194
    if (f)
 
195
    {
 
196
        if (fscanf(f, "%d %79s %c %d %d %d %d %d %u %lu %lu %lu %lu %u %u "
 
197
                      "%ld %ld %ld %ld %ld %ld %llu %lu %u",
 
198
                   &pid2, buf, &c, &iTmp, &iTmp, &iTmp, &iTmp, &iTmp, &uTmp,
 
199
                   &ulTmp, &ulTmp, &ulTmp, &ulTmp, &u32user, &u32kernel,
 
200
                   &ilTmp, &ilTmp, &ilTmp, &ilTmp, &ilTmp, &ilTmp, &u64Tmp,
 
201
                   &ulTmp, memPagesUsed) == 24)
 
202
        {
 
203
            Assert((pid_t)process == pid2);
 
204
            *cpuUser   = u32user;
 
205
            *cpuKernel = u32kernel;
 
206
        }
 
207
        else
 
208
            rc = VERR_FILE_IO_ERROR;
 
209
        fclose(f);
 
210
    }
 
211
    else
 
212
        rc = VERR_ACCESS_DENIED;
 
213
 
 
214
    return rc;
 
215
}
 
216
 
 
217
}
 
218