1
2
3
4
5 package oshi.driver.mac;
6
7 import static oshi.software.os.OSProcess.State.OTHER;
8 import static oshi.software.os.OSProcess.State.RUNNING;
9 import static oshi.software.os.OSProcess.State.SLEEPING;
10 import static oshi.software.os.OSProcess.State.STOPPED;
11 import static oshi.software.os.OSProcess.State.WAITING;
12 import static oshi.software.os.OSProcess.State.ZOMBIE;
13
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18 import java.util.stream.Collectors;
19
20 import oshi.annotation.concurrent.Immutable;
21 import oshi.annotation.concurrent.ThreadSafe;
22 import oshi.software.os.OSProcess.State;
23 import oshi.util.ExecutingCommand;
24 import oshi.util.ParseUtil;
25
26
27
28
29 @ThreadSafe
30 public final class ThreadInfo {
31
32 private static final Pattern PS_M = Pattern.compile(
33 "\\D+(\\d+).+(\\d+\\.\\d)\\s+(\\w)\\s+(\\d+)\\D+(\\d+:\\d{2}\\.\\d{2})\\s+(\\d+:\\d{2}\\.\\d{2}).+");
34
35 private ThreadInfo() {
36 }
37
38 public static List<ThreadStats> queryTaskThreads(int pid) {
39 String pidStr = " " + pid + " ";
40 List<ThreadStats> taskThreads = new ArrayList<>();
41
42
43 List<String> psThread = ExecutingCommand.runNative("ps -awwxM").stream().filter(s -> s.contains(pidStr))
44 .collect(Collectors.toList());
45 int tid = 0;
46 for (String thread : psThread) {
47 Matcher m = PS_M.matcher(thread);
48 if (m.matches() && pid == ParseUtil.parseIntOrDefault(m.group(1), -1)) {
49 double cpu = ParseUtil.parseDoubleOrDefault(m.group(2), 0d);
50 char state = m.group(3).charAt(0);
51 int pri = ParseUtil.parseIntOrDefault(m.group(4), 0);
52 long sTime = ParseUtil.parseDHMSOrDefault(m.group(5), 0L);
53 long uTime = ParseUtil.parseDHMSOrDefault(m.group(6), 0L);
54 taskThreads.add(new ThreadStats(tid++, cpu, state, sTime, uTime, pri));
55 }
56 }
57 return taskThreads;
58 }
59
60
61
62
63 @Immutable
64 public static class ThreadStats {
65 private final int threadId;
66 private final long userTime;
67 private final long systemTime;
68 private final long upTime;
69 private final State state;
70 private final int priority;
71
72 public ThreadStats(int tid, double cpu, char state, long sTime, long uTime, int pri) {
73 this.threadId = tid;
74 this.userTime = uTime;
75 this.systemTime = sTime;
76
77
78 this.upTime = (long) ((uTime + sTime) / (cpu / 100d + 0.0005));
79 switch (state) {
80 case 'I':
81 case 'S':
82 this.state = SLEEPING;
83 break;
84 case 'U':
85 this.state = WAITING;
86 break;
87 case 'R':
88 this.state = RUNNING;
89 break;
90 case 'Z':
91 this.state = ZOMBIE;
92 break;
93 case 'T':
94 this.state = STOPPED;
95 break;
96 default:
97 this.state = OTHER;
98 break;
99 }
100 this.priority = pri;
101 }
102
103
104
105
106 public int getThreadId() {
107 return threadId;
108 }
109
110
111
112
113 public long getUserTime() {
114 return userTime;
115 }
116
117
118
119
120 public long getSystemTime() {
121 return systemTime;
122 }
123
124
125
126
127 public long getUpTime() {
128 return upTime;
129 }
130
131
132
133
134 public State getState() {
135 return state;
136 }
137
138
139
140
141 public int getPriority() {
142 return priority;
143 }
144 }
145 }