1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package oshi.software.os.linux.proc;
18
19 import java.io.IOException;
20 import java.lang.management.ManagementFactory;
21 import java.util.List;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
24
25 import oshi.hardware.Processor;
26 import oshi.util.FileUtil;
27 import oshi.util.ParseUtil;
28
29
30
31
32
33
34
35
36 @SuppressWarnings("restriction")
37 public class CentralProcessor implements Processor {
38
39 private static final java.lang.management.OperatingSystemMXBean OS_MXBEAN = ManagementFactory
40 .getOperatingSystemMXBean();;
41 private static boolean sunMXBean;
42 static {
43 try {
44 Class.forName("com.sun.management.OperatingSystemMXBean");
45
46 ((com.sun.management.OperatingSystemMXBean) OS_MXBEAN)
47 .getSystemCpuLoad();
48 sunMXBean = true;
49 } catch (ClassNotFoundException e) {
50 sunMXBean = false;
51 }
52 }
53
54
55
56 private static long tickTime = System.currentTimeMillis();
57 private static long[] prevTicks = new long[4];
58 private static long[] curTicks = new long[4];
59 static {
60 updateSystemTicks();
61 System.arraycopy(curTicks, 0, prevTicks, 0, curTicks.length);
62 }
63
64
65 private long procTickTime = System.currentTimeMillis();
66 private long[] prevProcTicks = new long[4];
67 private long[] curProcTicks = new long[4];
68
69
70 private static int numCPU = 0;
71 static {
72 try {
73 List<String> procCpu = FileUtil.readFile("/proc/cpuinfo");
74 for (String cpu : procCpu) {
75 if (cpu.startsWith("core id")) {
76 numCPU++;
77 }
78 }
79 } catch (IOException e) {
80 System.err.println("Problem with: /proc/cpuinfo");
81 System.err.println(e.getMessage());
82 }
83 }
84
85
86
87 private static long[][] allProcessorTicks = new long[numCPU][4];
88 private static long allProcTickTime = 0;
89
90 private int processorNumber;
91 private String cpuVendor;
92 private String cpuName;
93 private String cpuIdentifier = null;
94 private String cpuStepping;
95 private String cpuModel;
96 private String cpuFamily;
97 private Long cpuVendorFreq = null;
98 private Boolean cpu64;
99
100
101
102
103
104
105 public CentralProcessor(int procNo) {
106 if (procNo >= numCPU)
107 throw new IllegalArgumentException("Processor number (" + procNo
108 + ") must be less than the number of CPUs: " + numCPU);
109 this.processorNumber = procNo;
110 updateProcessorTicks();
111 System.arraycopy(allProcessorTicks[processorNumber], 0, curProcTicks,
112 0, curProcTicks.length);
113 }
114
115
116
117
118 @Override
119 public int getProcessorNumber() {
120 return processorNumber;
121 }
122
123
124
125
126
127
128 @Override
129 public String getVendor() {
130 return this.cpuVendor;
131 }
132
133
134
135
136
137
138
139 @Override
140 public void setVendor(String vendor) {
141 this.cpuVendor = vendor;
142 }
143
144
145
146
147
148
149 @Override
150 public String getName() {
151 return this.cpuName;
152 }
153
154
155
156
157
158
159
160 @Override
161 public void setName(String name) {
162 this.cpuName = name;
163 }
164
165
166
167
168
169
170
171 @Override
172 public long getVendorFreq() {
173 if (this.cpuVendorFreq == null) {
174 Pattern pattern = Pattern.compile("@ (.*)$");
175 Matcher matcher = pattern.matcher(getName());
176
177 if (matcher.find()) {
178 String unit = matcher.group(1);
179 this.cpuVendorFreq = Long.valueOf(ParseUtil.parseHertz(unit));
180 } else {
181 this.cpuVendorFreq = Long.valueOf(-1L);
182 }
183 }
184
185 return this.cpuVendorFreq.longValue();
186 }
187
188
189
190
191
192
193
194 @Override
195 public void setVendorFreq(long freq) {
196 this.cpuVendorFreq = Long.valueOf(freq);
197 }
198
199
200
201
202
203
204 @Override
205 public String getIdentifier() {
206 if (this.cpuIdentifier == null) {
207 StringBuilder sb = new StringBuilder();
208 if (getVendor().contentEquals("GenuineIntel"))
209 sb.append(isCpu64bit() ? "Intel64" : "x86");
210 else
211 sb.append(getVendor());
212 sb.append(" Family ");
213 sb.append(getFamily());
214 sb.append(" Model ");
215 sb.append(getModel());
216 sb.append(" Stepping ");
217 sb.append(getStepping());
218 this.cpuIdentifier = sb.toString();
219 }
220 return this.cpuIdentifier;
221 }
222
223
224
225
226
227
228
229 @Override
230 public void setIdentifier(String identifier) {
231 this.cpuIdentifier = identifier;
232 }
233
234
235
236
237
238
239 @Override
240 public boolean isCpu64bit() {
241 return this.cpu64.booleanValue();
242 }
243
244
245
246
247
248
249
250 @Override
251 public void setCpu64(boolean cpu64) {
252 this.cpu64 = Boolean.valueOf(cpu64);
253 }
254
255
256
257
258 @Override
259 public String getStepping() {
260 return this.cpuStepping;
261 }
262
263
264
265
266
267 @Override
268 public void setStepping(String stepping) {
269 this.cpuStepping = stepping;
270 }
271
272
273
274
275 @Override
276 public String getModel() {
277 return this.cpuModel;
278 }
279
280
281
282
283
284 @Override
285 public void setModel(String model) {
286 this.cpuModel = model;
287 }
288
289
290
291
292 @Override
293 public String getFamily() {
294 return this.cpuFamily;
295 }
296
297
298
299
300
301 @Override
302 public void setFamily(String family) {
303 this.cpuFamily = family;
304 }
305
306
307
308
309 @Override
310 @Deprecated
311 public float getLoad() {
312
313 return (float) getSystemCpuLoadBetweenTicks() * 100;
314 }
315
316
317
318
319 @Override
320 public double getSystemCpuLoadBetweenTicks() {
321
322 long now = System.currentTimeMillis();
323 boolean update = (now - tickTime > 950);
324 if (update) {
325
326
327 updateSystemTicks();
328 tickTime = now;
329 }
330
331 long total = 0;
332 for (int i = 0; i < curTicks.length; i++) {
333 total += (curTicks[i] - prevTicks[i]);
334 }
335
336 long idle = curTicks[3] - prevTicks[3];
337
338
339 if (update) {
340 System.arraycopy(curTicks, 0, prevTicks, 0, curTicks.length);
341 }
342
343
344 if (total > 0 && idle >= 0) {
345 return (double) (total - idle) / total;
346 }
347 return 0d;
348 }
349
350
351
352
353 @Override
354 public long[] getSystemCpuLoadTicks() {
355 updateSystemTicks();
356
357 long[] ticks = new long[curTicks.length];
358 System.arraycopy(curTicks, 0, ticks, 0, curTicks.length);
359 return ticks;
360 }
361
362
363
364
365
366
367
368
369
370
371
372 private static void updateSystemTicks() {
373
374
375
376 String tickStr = "";
377 try {
378 List<String> procStat = FileUtil.readFile("/proc/stat");
379 if (!procStat.isEmpty())
380 tickStr = procStat.get(0);
381 } catch (IOException e) {
382 System.err.println("Problem with: /proc/stat");
383 System.err.println(e.getMessage());
384 return;
385 }
386 String[] tickArr = tickStr.split("\\s+");
387 if (tickArr.length < 5)
388 return;
389 for (int i = 0; i < 4; i++) {
390 curTicks[i] = Long.parseLong(tickArr[i + 1]);
391 }
392 }
393
394
395
396
397 @Override
398 public double getSystemCpuLoad() {
399 if (sunMXBean) {
400 return ((com.sun.management.OperatingSystemMXBean) OS_MXBEAN)
401 .getSystemCpuLoad();
402 }
403 return getSystemCpuLoadBetweenTicks();
404 }
405
406
407
408
409 @Override
410 public double getSystemLoadAverage() {
411 return OS_MXBEAN.getSystemLoadAverage();
412 }
413
414
415
416
417 @Override
418 public double getProcessorCpuLoadBetweenTicks() {
419
420 long now = System.currentTimeMillis();
421 if (now - procTickTime > 950) {
422
423 updateProcessorTicks();
424
425 System.arraycopy(curProcTicks, 0, prevProcTicks, 0,
426 curProcTicks.length);
427 System.arraycopy(allProcessorTicks[processorNumber], 0,
428 curProcTicks, 0, curProcTicks.length);
429 procTickTime = now;
430 }
431 long total = 0;
432 for (int i = 0; i < curProcTicks.length; i++) {
433 total += (curProcTicks[i] - prevProcTicks[i]);
434 }
435
436 long idle = curProcTicks[3] - prevProcTicks[3];
437
438 return (total > 0 && idle >= 0) ? (double) (total - idle) / total : 0d;
439 }
440
441
442
443
444 public long[] getProcessorCpuLoadTicks() {
445 updateProcessorTicks();
446 return allProcessorTicks[processorNumber];
447 }
448
449
450
451
452
453
454
455 private static void updateProcessorTicks() {
456
457
458 long now = System.currentTimeMillis();
459 if (now - allProcTickTime < 100)
460 return;
461
462
463
464
465
466 try {
467 int cpu = 0;
468 List<String> procStat = FileUtil.readFile("/proc/stat");
469 for (String stat : procStat) {
470 if (stat.startsWith("cpu") && !stat.startsWith("cpu ")) {
471 String[] tickArr = stat.split("\\s+");
472 if (tickArr.length < 5)
473 break;
474 for (int i = 0; i < 4; i++) {
475 allProcessorTicks[cpu][i] = Long
476 .parseLong(tickArr[i + 1]);
477 }
478 if (++cpu >= numCPU)
479 break;
480 }
481 }
482 } catch (IOException e) {
483 System.err.println("Problem with: /proc/stat");
484 System.err.println(e.getMessage());
485 }
486 allProcTickTime = now;
487 }
488
489 @Override
490 public String toString() {
491 return getName();
492 }
493 }