forked from BOINC/boinc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocinfo_mac.cpp
More file actions
181 lines (158 loc) · 5.98 KB
/
Copy pathprocinfo_mac.cpp
File metadata and controls
181 lines (158 loc) · 5.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
#define SHOW_TIMING 0
#include "config.h"
#include <cstdio>
#include <ctype.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#if SHOW_TIMING
#include <Carbon/Carbon.h>
#include "client_msgs.h"
#endif
#include "error_numbers.h"
#include "procinfo.h"
using std::vector;
// Possible values of iBrandId:
#define BOINC_BRAND_ID 0
#define GRIDREPUBLIC_BRAND_ID 1
#define PROGRESSTHRUPROCESSORS_BRAND_ID 2
#define CHARITYENGINE_BRAND_ID 3
// build table of all processes in system
//
int procinfo_setup(PROC_MAP& pm) {
int pid = getpid();
FILE* fd;
PROCINFO p;
int c, real_mem, virtual_mem, hours;
char* lf;
static long iBrandID = -1;
if (iBrandID < 0) {
iBrandID = BOINC_BRAND_ID;
// For GridRepublic or ProgressThruProcessors, the Mac
// installer put a branding file in our data directory
FILE *f = fopen("/Library/Application Support/BOINC Data/Branding", "r");
if (f) {
fscanf(f, "BrandId=%ld\n", &iBrandID);
fclose(f);
}
}
#if SHOW_TIMING
UnsignedWide start, end, elapsed;
start = UpTime();
#endif
// Some values of possible interest available from 'ps' command:
// %cpu percentage cpu usage (alias pcpu)
// %mem percentage memory usage (alias pmem)
// command command (executable name)
// majflt total page faults
// minflt total page reclaims
// nswap total swaps in/out
// pagein pageins (same as majflt)
// pid process ID
// ppid parent process ID
// poip pageouts in progress
// pri scheduling priority
// rss resident set size in Kbytes
// time accumulated cpu time, user + system
// vsz virtual size in Kbytes
//
// Unfortunately, the selectors majflt, minflt, pagein do not work on OS X,
// and ps does not return kernel time separately from user time.
//
// Earlier versions of procinf_mac.C launched a small helper application
// AppStats using a bi-directional pipe. AppStats used mach ports to get
// all the information, including page fault counts, kernel and user times.
// In order to use mach ports, AppStats must run setuid root.
//
// But these three items are not actually used (page fault counts aren't
// available from Windows either) so we have reverted to using the ps
// utility, even though it takes more cpu time than AppStats did.
// This eliminates the need to install our own application which runs setuid
// root; this was perceived by some users as a security risk.
// Under OS 10.8.x (only) ps writes a spurious warning to stderr if called
// from a process that has the DYLD_LIBRARY_PATH environment variable set.
// "env -i command" prevents the command from inheriting the caller's
// environment, which avoids the spurious warning.
fd = popen("env -i ps -axcopid,ppid,rss,vsz,pagein,time,command", "r");
if (!fd) return ERR_FOPEN;
// Skip over the header line
do {
c = fgetc(fd);
if (c == EOF) {
pclose(fd);
return ERR_GETS;
}
} while (c != '\n');
while (1) {
p.clear();
c = fscanf(fd, "%d%d%d%d%lu%d:%lf ",
&p.id,
&p.parentid,
&real_mem,
&virtual_mem,
&p.page_fault_count,
&hours,
&p.user_time
);
if (c < 7) break;
if (fgets(p.command, sizeof(p.command) , fd) == NULL) break;
lf = strchr(p.command, '\n');
if (lf) *lf = '\0'; // Strip trailing linefeed
p.working_set_size = (double)real_mem * 1024.;
p.swap_size = (double)virtual_mem * 1024.;
p.user_time += 60. * (float)hours;
p.is_boinc_app = (p.id == pid || strcasestr(p.command, "boinc"));
// Ideally, we should count ScreenSaverEngine.app as a BOINC process
// only if BOINC is set as the screensaver. We could set a flag in
// the client when the get_screensaver_tasks rpc is called, but that
// would not be 100% reliable for several reasons.
if (strcasestr(p.command, "screensaverengine")) p.is_boinc_app = true;
// We do not mark Mac processes as low priority because some processes
// (e.g., Finder) change priority frequently, which would cause
// procinfo_non_boinc() and ACTIVE_TASK_SET::get_memory_usage() to get
// incorrect results for the % CPU used.
p.is_low_priority = false;
switch (iBrandID) {
case GRIDREPUBLIC_BRAND_ID:
if (!strcasestr(p.command, "GridRepublic")) {
p.is_boinc_app = true;
}
break;
case PROGRESSTHRUPROCESSORS_BRAND_ID:
if (!strcasestr(p.command, "Progress Thru Processors")) {
p.is_boinc_app = true;
}
break;
case CHARITYENGINE_BRAND_ID:
if (!strcasestr(p.command, "Charity Engine")) {
p.is_boinc_app = true;
}
break;
}
pm.insert(std::pair<int, PROCINFO>(p.id, p));
}
pclose(fd);
#if SHOW_TIMING
end = UpTime();
elapsed = AbsoluteToNanoseconds(SubAbsoluteFromAbsolute(end, start));
msg_printf(NULL, MSG_INFO, "elapsed time = %llu, m_swap = %lf\n", elapsed, gstate.host_info.m_swap);
#endif
find_children(pm);
return 0;
}