VirtualBox

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

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

Fixed small memory leak in the Windows implementation.
Fixed lack of destructor call for the host specific Collector classes. (virtual destructor; caused
crash at exit in VBoxSVC.exe)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* $Id: PerformanceSolaris.cpp 12457 2008-09-15 11:14:35Z 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 virtual ~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
57CollectorHAL *createHAL()
58{
59 return new CollectorSolaris();
60}
61
62// Collector HAL for Solaris
63
64
65CollectorSolaris::CollectorSolaris() : mKC(0), mSysPages(0)
66{
67 if ((mKC = kstat_open()) == 0)
68 {
69 Log(("kstat_open() -> %d\n", errno));
70 return;
71 }
72
73 if ((mSysPages = kstat_lookup(mKC, "unix", 0, "system_pages")) == 0)
74 {
75 Log(("kstat_lookup(system_pages) -> %d\n", errno));
76 return;
77 }
78}
79
80CollectorSolaris::~CollectorSolaris()
81{
82 kstat_close(mKC);
83}
84
85int CollectorSolaris::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
86{
87 int rc = VINF_SUCCESS;
88 kstat_t *ksp;
89 uint64_t tmpUser, tmpKernel, tmpIdle;
90 int cpus;
91 cpu_stat_t cpu_stats;
92
93 if (mKC == 0)
94 return VERR_INTERNAL_ERROR;
95
96 tmpUser = tmpKernel = tmpIdle = cpus = 0;
97 for (ksp = mKC->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
98 if (strcmp(ksp->ks_module, "cpu_stat") == 0) {
99 if (kstat_read(mKC, ksp, &cpu_stats) == -1)
100 {
101 Log(("kstat_read() -> %d\n", errno));
102 return VERR_INTERNAL_ERROR;
103 }
104 ++cpus;
105 tmpUser += cpu_stats.cpu_sysinfo.cpu[CPU_USER];
106 tmpKernel += cpu_stats.cpu_sysinfo.cpu[CPU_KERNEL];
107 tmpIdle += cpu_stats.cpu_sysinfo.cpu[CPU_IDLE];
108 }
109 }
110
111 if (cpus == 0)
112 {
113 Log(("no cpu stats found!\n"));
114 return VERR_INTERNAL_ERROR;
115 }
116
117 if (user) *user = tmpUser;
118 if (kernel) *kernel = tmpKernel;
119 if (idle) *idle = tmpIdle;
120
121 return rc;
122}
123
124int CollectorSolaris::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total)
125{
126 int rc = VINF_SUCCESS;
127 char *pszName;
128 prusage_t prusage;
129
130 RTStrAPrintf(&pszName, "/proc/%d/usage", process);
131 Log(("Opening %s...\n", pszName));
132 int h = open(pszName, O_RDONLY);
133 RTMemFree(pszName);
134
135 if (h != -1)
136 {
137 if (read(h, &prusage, sizeof(prusage)) == sizeof(prusage))
138 {
139 //Assert((pid_t)process == pstatus.pr_pid);
140 //Log(("user=%u kernel=%u total=%u\n", prusage.pr_utime.tv_sec, prusage.pr_stime.tv_sec, prusage.pr_tstamp.tv_sec));
141 *user = (uint64_t)prusage.pr_utime.tv_sec * 1000000000 + prusage.pr_utime.tv_nsec;
142 *kernel = (uint64_t)prusage.pr_stime.tv_sec * 1000000000 + prusage.pr_stime.tv_nsec;
143 *total = (uint64_t)prusage.pr_tstamp.tv_sec * 1000000000 + prusage.pr_tstamp.tv_nsec;
144 //Log(("user=%llu kernel=%llu total=%llu\n", *user, *kernel, *total));
145 }
146 else
147 {
148 Log(("read() -> %d\n", errno));
149 rc = VERR_FILE_IO_ERROR;
150 }
151 close(h);
152 }
153 else
154 {
155 Log(("open() -> %d\n", errno));
156 rc = VERR_ACCESS_DENIED;
157 }
158
159 return rc;
160}
161
162int CollectorSolaris::getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available)
163{
164 int rc = VINF_SUCCESS;
165
166 kstat_named_t *kn;
167
168 if (mKC == 0 || mSysPages == 0)
169 return VERR_INTERNAL_ERROR;
170
171 if (kstat_read(mKC, mSysPages, 0) == -1)
172 {
173 Log(("kstat_read(sys_pages) -> %d\n", errno));
174 return VERR_INTERNAL_ERROR;
175 }
176 if ((kn = (kstat_named_t *)kstat_data_lookup(mSysPages, "freemem")) == 0)
177 {
178 Log(("kstat_data_lookup(freemem) -> %d\n", errno));
179 return VERR_INTERNAL_ERROR;
180 }
181 *available = kn->value.ul * (PAGE_SIZE/1024);
182 if ((kn = (kstat_named_t *)kstat_data_lookup(mSysPages, "physmem")) == 0)
183 {
184 Log(("kstat_data_lookup(physmem) -> %d\n", errno));
185 return VERR_INTERNAL_ERROR;
186 }
187 *total = kn->value.ul * (PAGE_SIZE/1024);
188 *used = *total - *available;
189
190 return rc;
191}
192int CollectorSolaris::getProcessMemoryUsage(RTPROCESS process, ULONG *used)
193{
194 int rc = VINF_SUCCESS;
195 char *pszName;
196 pid_t pid2;
197 char buf[80]; /* @todo: this should be tied to max allowed proc name. */
198 psinfo_t psinfo;
199
200 RTStrAPrintf(&pszName, "/proc/%d/psinfo", process);
201 Log(("Opening %s...\n", pszName));
202 int h = open(pszName, O_RDONLY);
203 RTMemFree(pszName);
204
205 if (h != -1)
206 {
207 if (read(h, &psinfo, sizeof(psinfo)) == sizeof(psinfo))
208 {
209 Assert((pid_t)process == psinfo.pr_pid);
210 *used = psinfo.pr_rssize;
211 }
212 else
213 {
214 Log(("read() -> %d\n", errno));
215 rc = VERR_FILE_IO_ERROR;
216 }
217 close(h);
218 }
219 else
220 {
221 Log(("open() -> %d\n", errno));
222 rc = VERR_ACCESS_DENIED;
223 }
224
225 return rc;
226}
227
228}
229
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