View Javadoc
1   /*
2    * Copyright 2020-2023 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
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   * OSThread implementation
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 }