VirtualBox

source: vbox/trunk/src/VBox/Main/darwin/PerformanceDarwin.cpp@ 25275

Last change on this file since 25275 was 21701, checked in by vboxsync, 15 years ago

drop/change some iprt/stdint.h usage.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.9 KB
Line 
1/* $Id: PerformanceDarwin.cpp 21701 2009-07-17 14:44:43Z vboxsync $ */
2/** @file
3 * VBox Darwin-specific Performance Classes implementation.
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#include <mach/mach_error.h>
23#include <mach/mach_host.h>
24#include <mach/mach_init.h>
25#include <mach/mach_time.h>
26#include <mach/vm_statistics.h>
27#include <sys/sysctl.h>
28#include <sys/errno.h>
29#include <iprt/err.h>
30#include <iprt/log.h>
31#include <iprt/param.h>
32#include "Performance.h"
33
34/* The following declarations are missing in 10.4.x SDK */
35/* @todo Replace them with libproc.h and sys/proc_info.h when 10.4 is no longer supported */
36extern "C" int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize);
37struct proc_taskinfo {
38 uint64_t pti_virtual_size; /* virtual memory size (bytes) */
39 uint64_t pti_resident_size; /* resident memory size (bytes) */
40 uint64_t pti_total_user; /* total time */
41 uint64_t pti_total_system;
42 uint64_t pti_threads_user; /* existing threads only */
43 uint64_t pti_threads_system;
44 int32_t pti_policy; /* default policy for new threads */
45 int32_t pti_faults; /* number of page faults */
46 int32_t pti_pageins; /* number of actual pageins */
47 int32_t pti_cow_faults; /* number of copy-on-write faults */
48 int32_t pti_messages_sent; /* number of messages sent */
49 int32_t pti_messages_received; /* number of messages received */
50 int32_t pti_syscalls_mach; /* number of mach system calls */
51 int32_t pti_syscalls_unix; /* number of unix system calls */
52 int32_t pti_csw; /* number of context switches */
53 int32_t pti_threadnum; /* number of threads in the task */
54 int32_t pti_numrunning; /* number of running threads */
55 int32_t pti_priority; /* task priority*/
56};
57#define PROC_PIDTASKINFO 4
58
59namespace pm {
60
61class CollectorDarwin : public CollectorHAL
62{
63public:
64 CollectorDarwin();
65 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
66 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
67 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
68 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
69private:
70 ULONG totalRAM;
71};
72
73CollectorHAL *createHAL()
74{
75 return new CollectorDarwin();
76}
77
78CollectorDarwin::CollectorDarwin()
79{
80 uint64_t hostMemory;
81 int mib[2];
82 size_t size;
83
84 mib[0] = CTL_HW;
85 mib[1] = HW_MEMSIZE;
86
87 size = sizeof(hostMemory);
88 if (sysctl(mib, 2, &hostMemory, &size, NULL, 0) == -1) {
89 Log(("sysctl() -> %s", strerror(errno)));
90 hostMemory = 0;
91 }
92 totalRAM = (ULONG)(hostMemory / 1024);
93}
94
95int CollectorDarwin::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
96{
97 kern_return_t krc;
98 mach_msg_type_number_t count;
99 host_cpu_load_info_data_t info;
100
101 count = HOST_CPU_LOAD_INFO_COUNT;
102
103 krc = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&info, &count);
104 if (krc != KERN_SUCCESS)
105 {
106 Log(("host_statistics() -> %s", mach_error_string(krc)));
107 return RTErrConvertFromDarwinKern(krc);
108 }
109
110 *user = (uint64_t)info.cpu_ticks[CPU_STATE_USER]
111 + info.cpu_ticks[CPU_STATE_NICE];
112 *kernel = (uint64_t)info.cpu_ticks[CPU_STATE_SYSTEM];
113 *idle = (uint64_t)info.cpu_ticks[CPU_STATE_IDLE];
114 return VINF_SUCCESS;
115}
116
117int CollectorDarwin::getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available)
118{
119 kern_return_t krc;
120 mach_msg_type_number_t count;
121 vm_statistics_data_t info;
122
123 count = HOST_VM_INFO_COUNT;
124
125 krc = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&info, &count);
126 if (krc != KERN_SUCCESS)
127 {
128 Log(("host_statistics() -> %s", mach_error_string(krc)));
129 return RTErrConvertFromDarwinKern(krc);
130 }
131
132 *total = totalRAM;
133 *available = info.free_count * (PAGE_SIZE / 1024);
134 *used = *total - *available;
135 return VINF_SUCCESS;
136}
137
138static int getProcessInfo(RTPROCESS process, struct proc_taskinfo *tinfo)
139{
140 LogAleksey(("getProcessInfo() getting info for %d", process));
141 int nb = proc_pidinfo(process, PROC_PIDTASKINFO, 0, tinfo, sizeof(*tinfo));
142 if (nb <= 0)
143 {
144 int rc = errno;
145 Log(("proc_pidinfo() -> %s", strerror(rc)));
146 return RTErrConvertFromDarwin(rc);
147 }
148 else if ((unsigned int)nb < sizeof(*tinfo))
149 {
150 Log(("proc_pidinfo() -> too few bytes %d", nb));
151 return VERR_INTERNAL_ERROR;
152 }
153 return VINF_SUCCESS;
154}
155
156int CollectorDarwin::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total)
157{
158 struct proc_taskinfo tinfo;
159
160 int rc = getProcessInfo(process, &tinfo);
161 if (RT_SUCCESS(rc))
162 {
163 *user = tinfo.pti_total_user;
164 *kernel = tinfo.pti_total_system;
165 *total = mach_absolute_time();
166 }
167 return rc;
168}
169
170int CollectorDarwin::getProcessMemoryUsage(RTPROCESS process, ULONG *used)
171{
172 struct proc_taskinfo tinfo;
173
174 int rc = getProcessInfo(process, &tinfo);
175 if (RT_SUCCESS(rc))
176 {
177 *used = tinfo.pti_resident_size / 1024;
178 }
179 return rc;
180}
181
182}
183
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use