1
2
3
4
5 package oshi.software.os.unix.freebsd;
6
7 import static oshi.software.os.OSProcess.State.INVALID;
8 import static oshi.software.os.OSProcess.State.OTHER;
9 import static oshi.software.os.OSProcess.State.RUNNING;
10 import static oshi.software.os.OSProcess.State.SLEEPING;
11 import static oshi.software.os.OSProcess.State.STOPPED;
12 import static oshi.software.os.OSProcess.State.WAITING;
13 import static oshi.software.os.OSProcess.State.ZOMBIE;
14
15 import java.util.List;
16 import java.util.Map;
17
18 import oshi.annotation.concurrent.ThreadSafe;
19 import oshi.software.common.AbstractOSThread;
20 import oshi.software.os.OSProcess;
21 import oshi.software.os.unix.freebsd.FreeBsdOSProcess.PsThreadColumns;
22 import oshi.util.ExecutingCommand;
23 import oshi.util.ParseUtil;
24
25
26
27
28 @ThreadSafe
29 public class FreeBsdOSThread extends AbstractOSThread {
30
31 private int threadId;
32 private String name = "";
33 private OSProcess.State state = INVALID;
34 private long minorFaults;
35 private long majorFaults;
36 private long startMemoryAddress;
37 private long contextSwitches;
38 private long kernelTime;
39 private long userTime;
40 private long startTime;
41 private long upTime;
42 private int priority;
43
44 public FreeBsdOSThread(int processId, Map<PsThreadColumns, String> threadMap) {
45 super(processId);
46 updateAttributes(threadMap);
47 }
48
49 public FreeBsdOSThread(int processId, int threadId) {
50 super(processId);
51 this.threadId = threadId;
52 updateAttributes();
53 }
54
55 @Override
56 public int getThreadId() {
57 return this.threadId;
58 }
59
60 @Override
61 public String getName() {
62 return this.name;
63 }
64
65 @Override
66 public OSProcess.State getState() {
67 return this.state;
68 }
69
70 @Override
71 public long getStartMemoryAddress() {
72 return this.startMemoryAddress;
73 }
74
75 @Override
76 public long getContextSwitches() {
77 return this.contextSwitches;
78 }
79
80 @Override
81 public long getMinorFaults() {
82 return this.minorFaults;
83 }
84
85 @Override
86 public long getMajorFaults() {
87 return this.majorFaults;
88 }
89
90 @Override
91 public long getKernelTime() {
92 return this.kernelTime;
93 }
94
95 @Override
96 public long getUserTime() {
97 return this.userTime;
98 }
99
100 @Override
101 public long getUpTime() {
102 return this.upTime;
103 }
104
105 @Override
106 public long getStartTime() {
107 return this.startTime;
108 }
109
110 @Override
111 public int getPriority() {
112 return this.priority;
113 }
114
115 @Override
116 public boolean updateAttributes() {
117 List<String> threadList = ExecutingCommand
118 .runNative("ps -awwxo " + FreeBsdOSProcess.PS_THREAD_COLUMNS + " -H -p " + getOwningProcessId());
119
120 String lwpStr = Integer.toString(this.threadId);
121 for (String psOutput : threadList) {
122 Map<PsThreadColumns, String> threadMap = ParseUtil.stringToEnumMap(PsThreadColumns.class, psOutput.trim(),
123 ' ');
124 if (threadMap.containsKey(PsThreadColumns.PRI) && lwpStr.equals(threadMap.get(PsThreadColumns.LWP))) {
125 return updateAttributes(threadMap);
126 }
127 }
128 this.state = INVALID;
129 return false;
130 }
131
132 private boolean updateAttributes(Map<PsThreadColumns, String> threadMap) {
133 this.name = threadMap.get(PsThreadColumns.TDNAME);
134 this.threadId = ParseUtil.parseIntOrDefault(threadMap.get(PsThreadColumns.LWP), 0);
135 switch (threadMap.get(PsThreadColumns.STATE).charAt(0)) {
136 case 'R':
137 this.state = RUNNING;
138 break;
139 case 'I':
140 case 'S':
141 this.state = SLEEPING;
142 break;
143 case 'D':
144 case 'L':
145 case 'U':
146 this.state = WAITING;
147 break;
148 case 'Z':
149 this.state = ZOMBIE;
150 break;
151 case 'T':
152 this.state = STOPPED;
153 break;
154 default:
155 this.state = OTHER;
156 break;
157 }
158 long elapsedTime = ParseUtil.parseDHMSOrDefault(threadMap.get(PsThreadColumns.ETIMES), 0L);
159
160 this.upTime = elapsedTime < 1L ? 1L : elapsedTime;
161 long now = System.currentTimeMillis();
162 this.startTime = now - this.upTime;
163 this.kernelTime = ParseUtil.parseDHMSOrDefault(threadMap.get(PsThreadColumns.SYSTIME), 0L);
164 this.userTime = ParseUtil.parseDHMSOrDefault(threadMap.get(PsThreadColumns.TIME), 0L) - this.kernelTime;
165 this.startMemoryAddress = ParseUtil.hexStringToLong(threadMap.get(PsThreadColumns.TDADDR), 0L);
166 long nonVoluntaryContextSwitches = ParseUtil.parseLongOrDefault(threadMap.get(PsThreadColumns.NIVCSW), 0L);
167 long voluntaryContextSwitches = ParseUtil.parseLongOrDefault(threadMap.get(PsThreadColumns.NVCSW), 0L);
168 this.contextSwitches = voluntaryContextSwitches + nonVoluntaryContextSwitches;
169 this.majorFaults = ParseUtil.parseLongOrDefault(threadMap.get(PsThreadColumns.MAJFLT), 0L);
170 this.minorFaults = ParseUtil.parseLongOrDefault(threadMap.get(PsThreadColumns.MINFLT), 0L);
171 this.priority = ParseUtil.parseIntOrDefault(threadMap.get(PsThreadColumns.PRI), 0);
172 return true;
173 }
174 }