1
2
3
4
5 package oshi.software.os.windows;
6
7 import static oshi.software.os.OSProcess.State.INVALID;
8 import static oshi.software.os.OSProcess.State.NEW;
9 import static oshi.software.os.OSProcess.State.OTHER;
10 import static oshi.software.os.OSProcess.State.RUNNING;
11 import static oshi.software.os.OSProcess.State.SLEEPING;
12 import static oshi.software.os.OSProcess.State.STOPPED;
13 import static oshi.software.os.OSProcess.State.SUSPENDED;
14 import static oshi.software.os.OSProcess.State.WAITING;
15
16 import java.util.Collections;
17 import java.util.Map;
18 import java.util.Set;
19
20 import oshi.annotation.concurrent.ThreadSafe;
21 import oshi.driver.windows.registry.ThreadPerformanceData;
22 import oshi.driver.windows.registry.ThreadPerformanceData.PerfCounterBlock;
23 import oshi.software.common.AbstractOSThread;
24 import oshi.software.os.OSProcess.State;
25
26
27
28
29 @ThreadSafe
30 public class WindowsOSThread extends AbstractOSThread {
31
32 private final int threadId;
33 private String name;
34 private State state;
35 private long startMemoryAddress;
36 private long contextSwitches;
37 private long kernelTime;
38 private long userTime;
39 private long startTime;
40 private long upTime;
41 private int priority;
42
43 public WindowsOSThread(int pid, int tid, String procName, PerfCounterBlock pcb) {
44 super(pid);
45 this.threadId = tid;
46 updateAttributes(procName, pcb);
47 }
48
49 @Override
50 public int getThreadId() {
51 return threadId;
52 }
53
54 @Override
55 public String getName() {
56 return name;
57 }
58
59 @Override
60 public State getState() {
61 return state;
62 }
63
64 @Override
65 public long getStartMemoryAddress() {
66 return startMemoryAddress;
67 }
68
69 @Override
70 public long getContextSwitches() {
71 return contextSwitches;
72 }
73
74 @Override
75 public long getKernelTime() {
76 return kernelTime;
77 }
78
79 @Override
80 public long getUserTime() {
81 return userTime;
82 }
83
84 @Override
85 public long getStartTime() {
86 return startTime;
87 }
88
89 @Override
90 public long getUpTime() {
91 return upTime;
92 }
93
94 @Override
95 public int getPriority() {
96 return this.priority;
97 }
98
99 @Override
100 public boolean updateAttributes() {
101 Set<Integer> pids = Collections.singleton(getOwningProcessId());
102 String procName = this.name.split("/")[0];
103 Map<Integer, ThreadPerformanceData.PerfCounterBlock> threads = ThreadPerformanceData
104 .buildThreadMapFromPerfCounters(pids, procName, getThreadId());
105 return updateAttributes(procName, threads.get(getThreadId()));
106 }
107
108 private boolean updateAttributes(String procName, PerfCounterBlock pcb) {
109 if (pcb == null) {
110 this.state = INVALID;
111 return false;
112 } else if (pcb.getName().contains("/") || procName.isEmpty()) {
113 name = pcb.getName();
114 } else {
115 this.name = procName + "/" + pcb.getName();
116 }
117 if (pcb.getThreadWaitReason() == 5) {
118 state = SUSPENDED;
119 } else {
120 switch (pcb.getThreadState()) {
121 case 0:
122 state = NEW;
123 break;
124 case 2:
125 case 3:
126 state = RUNNING;
127 break;
128 case 4:
129 state = STOPPED;
130 break;
131 case 5:
132 state = SLEEPING;
133 break;
134 case 1:
135 case 6:
136 state = WAITING;
137 break;
138 case 7:
139 default:
140 state = OTHER;
141 }
142 }
143 startMemoryAddress = pcb.getStartAddress();
144 contextSwitches = pcb.getContextSwitches();
145 kernelTime = pcb.getKernelTime();
146 userTime = pcb.getUserTime();
147 startTime = pcb.getStartTime();
148 upTime = System.currentTimeMillis() - pcb.getStartTime();
149 priority = pcb.getPriority();
150 return true;
151 }
152 }