VirtualBox

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

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

PerfAPI: RTCPUID usage fix

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