VirtualBox

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

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

PerfAPI: Handling of trailing colon in filter patterns

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1/* $Id: PerformanceDarwin.cpp 12678 2008-09-24 07:28:21Z vboxsync $ */
2
3/** @file
4 *
5 * VBox Darwin-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#include <iprt/stdint.h>
25#include <mach/mach_error.h>
26#include <mach/mach_host.h>
27#include <mach/mach_init.h>
28#include <mach/mach_time.h>
29#include <mach/vm_statistics.h>
30#include <sys/sysctl.h>
31#include <sys/errno.h>
32#include <iprt/err.h>
33#include <iprt/log.h>
34#include <iprt/param.h>
35#include "Performance.h"
36
37/* The following declarations are missing in 10.4.x SDK */
38/* @todo Replace them with libproc.h and sys/proc_info.h when 10.4 is no longer supported */
39extern "C" int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize);
40struct proc_taskinfo {
41 uint64_t pti_virtual_size; /* virtual memory size (bytes) */
42 uint64_t pti_resident_size; /* resident memory size (bytes) */
43 uint64_t pti_total_user; /* total time */
44 uint64_t pti_total_system;
45 uint64_t pti_threads_user; /* existing threads only */
46 uint64_t pti_threads_system;
47 int32_t pti_policy; /* default policy for new threads */
48 int32_t pti_faults; /* number of page faults */
49 int32_t pti_pageins; /* number of actual pageins */
50 int32_t pti_cow_faults; /* number of copy-on-write faults */
51 int32_t pti_messages_sent; /* number of messages sent */
52 int32_t pti_messages_received; /* number of messages received */
53 int32_t pti_syscalls_mach; /* number of mach system calls */
54 int32_t pti_syscalls_unix; /* number of unix system calls */
55 int32_t pti_csw; /* number of context switches */
56 int32_t pti_threadnum; /* number of threads in the task */
57 int32_t pti_numrunning; /* number of running threads */
58 int32_t pti_priority; /* task priority*/
59};
60#define PROC_PIDTASKINFO 4
61
62namespace pm {
63
64class CollectorDarwin : public CollectorHAL
65{
66public:
67 CollectorDarwin();
68 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
69 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
70 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
71 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
72private:
73 ULONG totalRAM;
74};
75
76CollectorHAL *createHAL()
77{
78 return new CollectorDarwin();
79}
80
81CollectorDarwin::CollectorDarwin()
82{
83 uint64_t hostMemory;
84 int mib[2];
85 size_t size;
86
87 mib[0] = CTL_HW;
88 mib[1] = HW_MEMSIZE;
89
90 size = sizeof(hostMemory);
91 if (sysctl(mib, 2, &hostMemory, &size, NULL, 0) == -1) {
92 Log(("sysctl() -> %s", strerror(errno)));
93 hostMemory = 0;
94 }
95 totalRAM = (ULONG)(hostMemory / 1024);
96}
97
98int CollectorDarwin::getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle)
99{
100 kern_return_t krc;
101 mach_msg_type_number_t count;
102 host_cpu_load_info_data_t info;
103
104 count = HOST_CPU_LOAD_INFO_COUNT;
105
106 krc = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&info, &count);
107 if (krc != KERN_SUCCESS)
108 {
109 Log(("host_statistics() -> %s", mach_error_string(krc)));
110 return RTErrConvertFromDarwinKern(krc);
111 }
112
113 *user = (uint64_t)info.cpu_ticks[CPU_STATE_USER]
114 + info.cpu_ticks[CPU_STATE_NICE];
115 *kernel = (uint64_t)info.cpu_ticks[CPU_STATE_SYSTEM];
116 *idle = (uint64_t)info.cpu_ticks[CPU_STATE_IDLE];
117 return VINF_SUCCESS;
118}
119
120int CollectorDarwin::getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available)
121{
122 kern_return_t krc;
123 mach_msg_type_number_t count;
124 vm_statistics_data_t info;
125
126 count = HOST_VM_INFO_COUNT;
127
128 krc = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&info, &count);
129 if (krc != KERN_SUCCESS)
130 {
131 Log(("host_statistics() -> %s", mach_error_string(krc)));
132 return RTErrConvertFromDarwinKern(krc);
133 }
134
135 *total = totalRAM;
136 *available = info.free_count * (PAGE_SIZE / 1024);
137 *used = *total - *available;
138 return VINF_SUCCESS;
139}
140
141static int getProcessInfo(RTPROCESS process, struct proc_taskinfo *tinfo)
142{
143 LogAleksey(("getProcessInfo() getting info for %d", process));
144 int nb = proc_pidinfo(process, PROC_PIDTASKINFO, 0, tinfo, sizeof(*tinfo));
145 if (nb <= 0)
146 {
147 int rc = errno;
148 Log(("proc_pidinfo() -> %s", strerror(rc)));
149 return RTErrConvertFromDarwin(rc);
150 }
151 else if ((unsigned int)nb < sizeof(*tinfo))
152 {
153 Log(("proc_pidinfo() -> too few bytes %d", nb));
154 return VERR_INTERNAL_ERROR;
155 }
156 return VINF_SUCCESS;
157}
158
159int CollectorDarwin::getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total)
160{
161 struct proc_taskinfo tinfo;
162
163 int rc = getProcessInfo(process, &tinfo);
164 if (RT_SUCCESS(rc))
165 {
166 *user = tinfo.pti_total_user;
167 *kernel = tinfo.pti_total_system;
168 *total = mach_absolute_time();
169 }
170 return rc;
171}
172
173int CollectorDarwin::getProcessMemoryUsage(RTPROCESS process, ULONG *used)
174{
175 struct proc_taskinfo tinfo;
176
177 int rc = getProcessInfo(process, &tinfo);
178 if (RT_SUCCESS(rc))
179 {
180 *used = tinfo.pti_resident_size / 1024;
181 }
182 return rc;
183}
184
185}
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