VirtualBox

source: vbox/trunk/src/VBox/Main/linux/PerformanceLinux.cpp@ 10880

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

Fix for missing _SC_PAGESIZE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.1 KB
Line 
1/* $Id: PerformanceLinux.cpp 10880 2008-07-25 08:30:15Z vboxsync $ */
2
3/** @file
4 *
5 * VBox Linux-specific 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.215389.xyz. 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 <stdio.h>
25#include <iprt/alloc.h>
26#include <iprt/err.h>
27#include <iprt/string.h>
28#include "Performance.h"
29
30#ifndef PAGESIZE
31#define PAGESIZE _SC_PAGESIZE
32#endif
33
34namespace pm {
35
36class CollectorLinux : public CollectorHAL
37{
38public:
39 virtual int getHostCpuMHz(unsigned long *mhz);
40 virtual int getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available);
41 virtual int getProcessMemoryUsage(RTPROCESS process, unsigned long *used);
42
43 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
44 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
45private:
46 int getRawProcessStats(RTPROCESS process, uint64_t *cpuUser, uint64_t *cpuKernel, unsigned long *memPagesUsed);
47 long getPageSize() { return sysconf(PAGESIZE); };
48};
49
50// Linux Metric factory
51
52MetricFactoryLinux::MetricFactoryLinux()
53{
54 mHAL = new CollectorLinux();
55 Assert(mHAL);
56}
57
58// Collector HAL for Linux
59
60int CollectorLinux::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
61{
62 int rc = VINF_SUCCESS;
63 unsigned long u32user, u32nice, u32kernel, u32idle;
64 FILE *f = fopen("/proc/stat", "r");
65
66 if (f)
67 {
68 if (fscanf(f, "cpu %lu %lu %lu %lu", &u32user, &u32nice, &u32kernel, &u32idle) == 4)
69 {
70 *user = (uint64_t)u32user + u32nice;
71 *kernel = u32kernel;
72 *idle = u32idle;
73 }
74 else
75 rc = VERR_FILE_IO_ERROR;
76 fclose(f);
77 }
78 else
79 rc = VERR_ACCESS_DENIED;
80
81 return rc;
82}
83
84int CollectorLinux::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total)
85{
86 int rc = VINF_SUCCESS;
87 uint64_t uHostUser, uHostKernel, uHostIdle;
88
89 rc = getRawHostCpuLoad(&uHostUser, &uHostKernel, &uHostIdle);
90 if (RT_SUCCESS(rc))
91 {
92 unsigned long ulTmp;
93 *total = (uint64_t)uHostUser + uHostKernel + uHostIdle;
94 rc = getRawProcessStats(process, user, kernel, &ulTmp);
95 }
96
97 return rc;
98}
99
100int CollectorLinux::getHostCpuMHz(unsigned long *mhz)
101{
102 return E_NOTIMPL;
103}
104
105int CollectorLinux::getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available)
106{
107 int rc = VINF_SUCCESS;
108 unsigned long buffers, cached;
109 FILE *f = fopen("/proc/meminfo", "r");
110
111 if (f)
112 {
113 int processed = fscanf(f, "MemTotal: %lu kB", total);
114 processed += fscanf(f, "MemFree: %lu kB", available);
115 processed += fscanf(f, "Buffers: %lu kB", &buffers);
116 processed += fscanf(f, "Cached: %lu kB", &cached);
117 if (processed == 4)
118 *available += buffers + cached;
119 else
120 rc = VERR_FILE_IO_ERROR;
121 fclose(f);
122 }
123 else
124 rc = VERR_ACCESS_DENIED;
125
126 return rc;
127}
128
129int CollectorLinux::getProcessMemoryUsage(RTPROCESS process, unsigned long *used)
130{
131 uint64_t u64Tmp;
132 unsigned long nPagesUsed;
133 int rc = getRawProcessStats(process, &u64Tmp, &u64Tmp, &nPagesUsed);
134 if (RT_SUCCESS(rc))
135 {
136 Assert(getPageSize() >= 1024);
137 *used = nPagesUsed * (getPageSize() / 1024);
138 }
139 return rc;
140}
141
142int CollectorLinux::getRawProcessStats(RTPROCESS process, uint64_t *cpuUser, uint64_t *cpuKernel, unsigned long *memPagesUsed)
143{
144 int rc = VINF_SUCCESS;
145 char *pszName;
146 pid_t pid2;
147 char c;
148 int iTmp;
149 uint64_t u64Tmp;
150 unsigned uTmp;
151 unsigned long ulTmp, u32user, u32kernel;
152 char buf[80]; /* @todo: this should be tied to max allowed proc name. */
153
154 RTStrAPrintf(&pszName, "/proc/%d/stat", process);
155 //printf("Opening %s...\n", pszName);
156 FILE *f = fopen(pszName, "r");
157 RTMemFree(pszName);
158
159 if (f)
160 {
161 if (fscanf(f, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu "
162 "%ld %ld %ld %ld %ld %ld %llu %lu %ld",
163 &pid2, buf, &c, &iTmp, &iTmp, &iTmp, &iTmp, &iTmp, &uTmp,
164 &ulTmp, &ulTmp, &ulTmp, &ulTmp, &u32user, &u32kernel,
165 &ulTmp, &ulTmp, &ulTmp, &ulTmp, &ulTmp, &ulTmp, &u64Tmp,
166 &ulTmp, memPagesUsed) == 24)
167 {
168 Assert((pid_t)process == pid2);
169 *cpuUser = u32user;
170 *cpuKernel = u32kernel;
171 }
172 else
173 rc = VERR_FILE_IO_ERROR;
174 fclose(f);
175 }
176 else
177 rc = VERR_ACCESS_DENIED;
178
179 return rc;
180}
181
182}
183
Note: See TracBrowser for help on using the repository browser.

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