VirtualBox

source: vbox/trunk/src/VBox/Main/solaris/PerformanceSolaris.cpp@ 11501

Last change on this file since 11501 was 11501, checked in by vboxsync, 16 years ago

PerfAPI: no more solaris-specific stub for CPU/MHz; additional logging at level4

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.2 KB
Line 
1/* $Id: PerformanceSolaris.cpp 11501 2008-08-19 19:57:03Z vboxsync $ */
2
3/** @file
4 *
5 * VBox Solaris-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.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#undef _FILE_OFFSET_BITS
25#include <procfs.h>
26#include <stdio.h>
27#include <errno.h>
28#include <fcntl.h>
29#include <kstat.h>
30#include <sys/sysinfo.h>
31#include <sys/time.h>
32
33#include <iprt/err.h>
34#include <iprt/string.h>
35#include <iprt/alloc.h>
36#include <iprt/param.h>
37#include <VBox/log.h>
38#include "Performance.h"
39
40namespace pm {
41
42class CollectorSolaris : public CollectorHAL
43{
44public:
45 CollectorSolaris();
46 ~CollectorSolaris();
47 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
48 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
49
50 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
51 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
52private:
53 kstat_ctl_t *mKC;
54 kstat_t *mSysPages;
55};
56
57// Solaris Metric factory
58
59MetricFactorySolaris::MetricFactorySolaris()
60{
61 mHAL = new CollectorSolaris();
62 Assert(mHAL);
63}
64
65// Collector HAL for Solaris
66
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
88int CollectorSolaris::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
89{
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\n", 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 }
149 else
150 {
151 Log(("read() -> %d\n", errno));
152 rc = VERR_FILE_IO_ERROR;
153 }
154 close(h);
155 }
156 else
157 {
158 Log(("open() -> %d\n", errno));
159 rc = VERR_ACCESS_DENIED;
160 }
161
162 return rc;
163}
164
165int CollectorSolaris::getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available)
166{
167 int rc = VINF_SUCCESS;
168
169 kstat_named_t *kn;
170
171 if (mKC == 0 || mSysPages == 0)
172 return VERR_INTERNAL_ERROR;
173
174 if (kstat_read(mKC, mSysPages, 0) == -1)
175 {
176 Log(("kstat_read(sys_pages) -> %d\n", errno));
177 return VERR_INTERNAL_ERROR;
178 }
179 if ((kn = (kstat_named_t *)kstat_data_lookup(mSysPages, "freemem")) == 0)
180 {
181 Log(("kstat_data_lookup(freemem) -> %d\n", errno));
182 return VERR_INTERNAL_ERROR;
183 }
184 *available = kn->value.ul * (PAGE_SIZE/1024);
185 if ((kn = (kstat_named_t *)kstat_data_lookup(mSysPages, "physmem")) == 0)
186 {
187 Log(("kstat_data_lookup(physmem) -> %d\n", errno));
188 return VERR_INTERNAL_ERROR;
189 }
190 *total = kn->value.ul * (PAGE_SIZE/1024);
191 *used = *total - *available;
192
193 return rc;
194}
195int CollectorSolaris::getProcessMemoryUsage(RTPROCESS process, ULONG *used)
196{
197 int rc = VINF_SUCCESS;
198 char *pszName;
199 pid_t pid2;
200 char buf[80]; /* @todo: this should be tied to max allowed proc name. */
201 psinfo_t psinfo;
202
203 RTStrAPrintf(&pszName, "/proc/%d/psinfo", process);
204 Log(("Opening %s...\n", pszName));
205 int h = open(pszName, O_RDONLY);
206 RTMemFree(pszName);
207
208 if (h != -1)
209 {
210 if (read(h, &psinfo, sizeof(psinfo)) == sizeof(psinfo))
211 {
212 Assert((pid_t)process == psinfo.pr_pid);
213 *used = psinfo.pr_rssize;
214 }
215 else
216 {
217 Log(("read() -> %d\n", errno));
218 rc = VERR_FILE_IO_ERROR;
219 }
220 close(h);
221 }
222 else
223 {
224 Log(("open() -> %d\n", errno));
225 rc = VERR_ACCESS_DENIED;
226 }
227
228 return rc;
229}
230
231}
232
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