VirtualBox

source: vbox/trunk/src/VBox/Main/Performance.cpp@ 10645

Last change on this file since 10645 was 10641, checked in by vboxsync, 17 years ago

Performance API files exported to OSE.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/* $Id: Performance.cpp 10641 2008-07-15 11:06:50Z vboxsync $ */
2
3/** @file
4 *
5 * VBox Performance Classes implementation.
6 */
7
8/*
9 * Copyright (C) 2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24#include <VBox/com/ptr.h>
25#include <VBox/err.h>
26#include <iprt/string.h>
27#include <iprt/mem.h>
28
29#include "Performance.h"
30
31using namespace pm;
32
33// Default factory
34
35BaseMetric *MetricFactory::createHostCpuLoad(IUnknown *object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
36{
37 Assert(mHAL);
38 return new HostCpuLoad(mHAL, object, user, kernel, idle);
39}
40BaseMetric *MetricFactory::createHostCpuMHz(IUnknown *object, SubMetric *mhz)
41{
42 Assert(mHAL);
43 return new HostCpuMhz(mHAL, object, mhz);
44}
45BaseMetric *MetricFactory::createHostRamUsage(IUnknown *object, SubMetric *total, SubMetric *used, SubMetric *available)
46{
47 Assert(mHAL);
48 return new HostRamUsage(mHAL, object, total, used, available);
49}
50BaseMetric *MetricFactory::createMachineCpuLoad(IUnknown *object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
51{
52 Assert(mHAL);
53 return new MachineCpuLoad(mHAL, object, process, user, kernel);
54}
55BaseMetric *MetricFactory::createMachineRamUsage(IUnknown *object, RTPROCESS process, SubMetric *used)
56{
57 Assert(mHAL);
58 return new MachineRamUsage(mHAL, object, process, used);
59}
60
61// Linux factory
62
63MetricFactoryLinux::MetricFactoryLinux()
64{
65 mHAL = new CollectorLinux();
66 Assert(mHAL);
67}
68
69BaseMetric *MetricFactoryLinux::createHostCpuLoad(IUnknown *object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
70{
71 Assert(mHAL);
72 return new HostCpuLoadRaw(mHAL, object, user, kernel, idle);
73}
74
75BaseMetric *MetricFactoryLinux::createMachineCpuLoad(IUnknown *object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
76{
77 Assert(mHAL);
78 return new MachineCpuLoadRaw(mHAL, object, process, user, kernel);
79}
80
81
82// Stubs for non-pure virtual methods
83
84int CollectorHAL::getHostCpuLoad(unsigned long *user, unsigned long *kernel, unsigned long *idle)
85{
86 return E_NOTIMPL;
87}
88
89int CollectorHAL::getProcessCpuLoad(RTPROCESS process, unsigned long *user, unsigned long *kernel)
90{
91 return E_NOTIMPL;
92}
93
94int CollectorHAL::getRawHostCpuLoad(unsigned long *user, unsigned long *kernel, unsigned long *idle)
95{
96 return E_NOTIMPL;
97}
98
99int CollectorHAL::getRawProcessCpuLoad(RTPROCESS process, unsigned long *user, unsigned long *kernel)
100{
101 return E_NOTIMPL;
102}
103
104// Collector HAL for Linux
105#include <stdio.h>
106
107int CollectorLinux::getRawHostCpuLoad(unsigned long *user, unsigned long *kernel, unsigned long *idle)
108{
109#ifdef RT_OS_LINUX
110 int rc = VINF_SUCCESS;
111 unsigned long nice;
112 FILE *f = fopen("/proc/stat", "r");
113
114 if (f)
115 {
116 if (fscanf(f, "cpu %lu %lu %lu %lu", user, &nice, kernel, idle) == 4)
117 *user += nice;
118 else
119 rc = VERR_FILE_IO_ERROR;
120 fclose(f);
121 }
122 else
123 rc = VERR_ACCESS_DENIED;
124
125 return rc;
126#else
127 return E_NOTIMPL;
128#endif
129}
130
131int CollectorLinux::getRawProcessCpuLoad(RTPROCESS process, unsigned long *user, unsigned long *kernel)
132{
133#ifdef RT_OS_LINUX
134 int rc = VINF_SUCCESS;
135 char *pszName;
136 pid_t pid2;
137 char c;
138 int iTmp;
139 unsigned uTmp;
140 unsigned long ulTmp;
141 char buf[80]; /* @todo: this should be tied to max allowed proc name. */
142
143 RTStrAPrintf(&pszName, "/proc/%d/stat", process);
144 //printf("Opening %s...\n", pszName);
145 FILE *f = fopen(pszName, "r");
146 RTMemFree(pszName);
147
148 if (f)
149 {
150 if (fscanf(f, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu",
151 &pid2, buf, &c, &iTmp, &iTmp, &iTmp, &iTmp, &iTmp, &uTmp,
152 &ulTmp, &ulTmp, &ulTmp, &ulTmp, user, kernel) == 15)
153 {
154 Assert((pid_t)process == pid2);
155 }
156 else
157 rc = VERR_FILE_IO_ERROR;
158 fclose(f);
159 }
160 else
161 rc = VERR_ACCESS_DENIED;
162
163 return rc;
164#else
165 return E_NOTIMPL;
166#endif
167}
168
169int CollectorLinux::getHostCpuMHz(unsigned long *mhz)
170{
171 return E_NOTIMPL;
172}
173int CollectorLinux::getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available)
174{
175 return E_NOTIMPL;
176}
177int CollectorLinux::getProcessMemoryUsage(RTPROCESS process, unsigned long *used)
178{
179 return E_NOTIMPL;
180}
181
182void HostCpuLoad::init(unsigned long period, unsigned long length)
183{
184 mPeriod = period;
185 mLength = length;
186 mUser->init(mLength);
187 mKernel->init(mLength);
188 mIdle->init(mLength);
189}
190
191void HostCpuLoad::collect()
192{
193 unsigned long user, kernel, idle;
194 mHAL->getHostCpuLoad(&user, &kernel, &idle);
195 mUser->put(user);
196 mKernel->put(kernel);
197 mIdle->put(idle);
198}
199
200void HostCpuLoadRaw::collect()
201{
202 unsigned long user, kernel, idle;
203 unsigned long userDiff, kernelDiff, idleDiff, totalDiff;
204
205 mHAL->getRawHostCpuLoad(&user, &kernel, &idle);
206
207 userDiff = user - mUserPrev;
208 kernelDiff = kernel - mKernelPrev;
209 idleDiff = idle - mIdlePrev;
210 totalDiff = userDiff + kernelDiff + idleDiff;
211
212 mUser->put(PM_CPU_LOAD_MULTIPLIER * userDiff / totalDiff);
213 mKernel->put(PM_CPU_LOAD_MULTIPLIER * kernelDiff / totalDiff);
214 mIdle->put(PM_CPU_LOAD_MULTIPLIER * idleDiff / totalDiff);
215
216 mUserPrev = user;
217 mKernelPrev = kernel;
218 mIdlePrev = idle;
219}
220
221void HostCpuMhz::collect()
222{
223 unsigned long mhz;
224 mHAL->getHostCpuMHz(&mhz);
225 mMHz->put(mhz);
226}
227
228void HostRamUsage::collect()
229{
230 unsigned long total, used, available;
231 mHAL->getHostMemoryUsage(&total, &used, &available);
232 mTotal->put(total);
233 mUsed->put(used);
234 mAvailable->put(available);
235}
236
237
238void MachineCpuLoad::collect()
239{
240 unsigned long user, kernel;
241 mHAL->getProcessCpuLoad(mProcess, &user, &kernel);
242 mUser->put(user);
243 mKernel->put(kernel);
244}
245
246void MachineCpuLoadRaw::collect()
247{
248 unsigned long hostUser, hostKernel, hostIdle, hostTotal;
249 unsigned long processUser, processKernel;
250
251 mHAL->getRawHostCpuLoad(&hostUser, &hostKernel, &hostIdle);
252 hostTotal = hostUser + hostKernel + hostIdle;
253
254 mHAL->getRawProcessCpuLoad(mProcess, &processUser, &processKernel);
255 mUser->put(PM_CPU_LOAD_MULTIPLIER * (processUser - mProcessUserPrev) / (hostTotal - mHostTotalPrev));
256 mUser->put(PM_CPU_LOAD_MULTIPLIER * (processKernel - mProcessKernelPrev ) / (hostTotal - mHostTotalPrev));
257
258 mHostTotalPrev = hostTotal;
259 mProcessUserPrev = processUser;
260 mProcessKernelPrev = processKernel;
261}
262
263void MachineRamUsage::collect()
264{
265 unsigned long used;
266 mHAL->getProcessMemoryUsage(mProcess, &used);
267 mUsed->put(used);
268}
269
270void CircularBuffer::init(unsigned long length)
271{
272 if (mData)
273 RTMemFree(mData);
274 mLength = length;
275 mData = (unsigned long *)RTMemAllocZ(length * sizeof(unsigned long));
276 mPosition = 0;
277}
278
279unsigned long CircularBuffer::length()
280{
281 return mLength;
282}
283
284void CircularBuffer::put(unsigned long value)
285{
286 mData[mPosition++] = value;
287 if (mPosition >= mLength)
288 mPosition = 0;
289}
290
291void CircularBuffer::copyTo(unsigned long *data, unsigned long length)
292{
293 memcpy(data, mData + mPosition, (length - mPosition) * sizeof(unsigned long));
294 // Copy the wrapped part
295 if (mPosition)
296 memcpy(data + mPosition, mData, mPosition * sizeof(unsigned long));
297}
298
299void SubMetric::query(unsigned long *data, unsigned long count)
300{
301 copyTo(data, count);
302}
303
304void Metric::query(unsigned long **data, unsigned long *count)
305{
306 unsigned long length;
307 unsigned long *tmpData;
308
309 length = mSubMetric->length();
310 if (length)
311 {
312 tmpData = (unsigned long*)RTMemAlloc(sizeof(*tmpData)*length);
313 mSubMetric->query(tmpData, length);
314 if (mAggregate)
315 {
316 *count = 1;
317 *data = (unsigned long*)RTMemAlloc(sizeof(**data));
318 **data = mAggregate->compute(tmpData, length);
319 }
320 else
321 {
322 *count = length;
323 *data = tmpData;
324 }
325 }
326 else
327 {
328 *count = 0;
329 *data = 0;
330 }
331}
332
333unsigned long AggregateAvg::compute(unsigned long *data, unsigned long length)
334{
335 return 0;
336}
337
338const char * AggregateAvg::getName()
339{
340 return "avg";
341}
342
343unsigned long AggregateMin::compute(unsigned long *data, unsigned long length)
344{
345 return 0;
346}
347
348const char * AggregateMin::getName()
349{
350 return "min";
351}
352
353unsigned long AggregateMax::compute(unsigned long *data, unsigned long length)
354{
355 return 0;
356}
357
358const char * AggregateMax::getName()
359{
360 return "max";
361}
362
Note: See TracBrowser for help on using the repository browser.

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