View Javadoc
1   /*
2    * Copyright 2020-2024 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.driver.windows.perfmon;
6   
7   import static oshi.driver.windows.perfmon.PerfmonConstants.PROCESSOR;
8   import static oshi.driver.windows.perfmon.PerfmonConstants.PROCESSOR_INFORMATION;
9   import static oshi.driver.windows.perfmon.PerfmonConstants.WIN32_PERF_RAW_DATA_COUNTERS_PROCESSOR_INFORMATION_WHERE_NOT_NAME_LIKE_TOTAL;
10  import static oshi.driver.windows.perfmon.PerfmonConstants.WIN32_PERF_RAW_DATA_PERF_OS_PROCESSOR_WHERE_NAME_NOT_TOTAL;
11  import static oshi.driver.windows.perfmon.PerfmonConstants.WIN32_PERF_RAW_DATA_PERF_OS_PROCESSOR_WHERE_NAME_TOTAL;
12  
13  import java.util.Collections;
14  import java.util.List;
15  import java.util.Map;
16  
17  import com.sun.jna.platform.win32.VersionHelpers;
18  
19  import oshi.annotation.concurrent.ThreadSafe;
20  import oshi.util.platform.windows.PerfCounterQuery;
21  import oshi.util.platform.windows.PerfCounterQuery.PdhCounterProperty;
22  import oshi.util.platform.windows.PerfCounterWildcardQuery;
23  import oshi.util.platform.windows.PerfCounterWildcardQuery.PdhCounterWildcardProperty;
24  import oshi.util.tuples.Pair;
25  
26  /**
27   * Utility to query Processor performance counter
28   */
29  @ThreadSafe
30  public final class ProcessorInformation {
31  
32      private static final boolean IS_WIN7_OR_GREATER = VersionHelpers.IsWindows7OrGreater();
33  
34      /**
35       * Processor performance counters
36       */
37      public enum ProcessorTickCountProperty implements PdhCounterWildcardProperty {
38          // First element defines WMI instance name field and PDH instance filter
39          NAME(PerfCounterQuery.NOT_TOTAL_INSTANCES),
40          // Remaining elements define counters
41          PERCENTDPCTIME("% DPC Time"), //
42          PERCENTINTERRUPTTIME("% Interrupt Time"), //
43          PERCENTPRIVILEGEDTIME("% Privileged Time"), //
44          PERCENTPROCESSORTIME("% Processor Time"), //
45          PERCENTUSERTIME("% User Time");
46  
47          private final String counter;
48  
49          ProcessorTickCountProperty(String counter) {
50              this.counter = counter;
51          }
52  
53          @Override
54          public String getCounter() {
55              return counter;
56          }
57      }
58  
59      /**
60       * Processor performance counters including utility counters
61       */
62      public enum ProcessorUtilityTickCountProperty implements PdhCounterWildcardProperty {
63          // First element defines WMI instance name field and PDH instance filter
64          NAME(PerfCounterQuery.NOT_TOTAL_INSTANCES),
65          // Remaining elements define counters
66          PERCENTDPCTIME("% DPC Time"), //
67          PERCENTINTERRUPTTIME("% Interrupt Time"), //
68          PERCENTPRIVILEGEDTIME("% Privileged Time"), //
69          PERCENTPROCESSORTIME("% Processor Time"), //
70          // The above 3 counters are 100ns base type
71          // For PDH accessible as secondary counter in any of them
72          TIMESTAMP_SYS100NS("% Processor Time_Base"), //
73          PERCENTPRIVILEGEDUTILITY("% Privileged Utility"), //
74          PERCENTPROCESSORUTILITY("% Processor Utility"), //
75          PERCENTPROCESSORUTILITY_BASE("% Processor Utility_Base"), //
76          PERCENTUSERTIME("% User Time");
77  
78          private final String counter;
79  
80          ProcessorUtilityTickCountProperty(String counter) {
81              this.counter = counter;
82          }
83  
84          @Override
85          public String getCounter() {
86              return counter;
87          }
88      }
89  
90      /**
91       * System interrupts counters
92       */
93      public enum InterruptsProperty implements PdhCounterProperty {
94          INTERRUPTSPERSEC(PerfCounterQuery.TOTAL_INSTANCE, "Interrupts/sec");
95  
96          private final String instance;
97          private final String counter;
98  
99          InterruptsProperty(String instance, String counter) {
100             this.instance = instance;
101             this.counter = counter;
102         }
103 
104         @Override
105         public String getInstance() {
106             return instance;
107         }
108 
109         @Override
110         public String getCounter() {
111             return counter;
112         }
113     }
114 
115     /**
116      * Processor Frequency counters. Requires Win7 or greater
117      */
118     public enum ProcessorFrequencyProperty implements PdhCounterWildcardProperty {
119         // First element defines WMI instance name field and PDH instance filter
120         NAME(PerfCounterQuery.NOT_TOTAL_INSTANCES),
121         // Remaining elements define counters
122         PERCENTOFMAXIMUMFREQUENCY("% of Maximum Frequency");
123 
124         private final String counter;
125 
126         ProcessorFrequencyProperty(String counter) {
127             this.counter = counter;
128         }
129 
130         @Override
131         public String getCounter() {
132             return counter;
133         }
134     }
135 
136     /**
137      * System performance counters
138      */
139     public enum SystemTickCountProperty implements PdhCounterProperty {
140         PERCENTDPCTIME(PerfCounterQuery.TOTAL_INSTANCE, "% DPC Time"), //
141         PERCENTINTERRUPTTIME(PerfCounterQuery.TOTAL_INSTANCE, "% Interrupt Time");
142 
143         private final String instance;
144         private final String counter;
145 
146         SystemTickCountProperty(String instance, String counter) {
147             this.instance = instance;
148             this.counter = counter;
149         }
150 
151         @Override
152         public String getInstance() {
153             return instance;
154         }
155 
156         @Override
157         public String getCounter() {
158             return counter;
159         }
160     }
161 
162     private ProcessorInformation() {
163     }
164 
165     /**
166      * Returns processor performance counters.
167      *
168      * @return Performance Counters for processors.
169      */
170     public static Pair<List<String>, Map<ProcessorTickCountProperty, List<Long>>> queryProcessorCounters() {
171         if (PerfmonDisabled.PERF_OS_DISABLED) {
172             return new Pair<>(Collections.emptyList(), Collections.emptyMap());
173         }
174         return IS_WIN7_OR_GREATER ? PerfCounterWildcardQuery.queryInstancesAndValues(ProcessorTickCountProperty.class,
175                 PROCESSOR_INFORMATION, WIN32_PERF_RAW_DATA_COUNTERS_PROCESSOR_INFORMATION_WHERE_NOT_NAME_LIKE_TOTAL)
176                 : PerfCounterWildcardQuery.queryInstancesAndValues(ProcessorTickCountProperty.class, PROCESSOR,
177                         WIN32_PERF_RAW_DATA_PERF_OS_PROCESSOR_WHERE_NAME_NOT_TOTAL);
178     }
179 
180     /**
181      * Returns system performance counters.
182      *
183      * @return Performance Counters for the total of all processors.
184      */
185     public static Map<SystemTickCountProperty, Long> querySystemCounters() {
186         return PerfCounterQuery.queryValues(SystemTickCountProperty.class, PROCESSOR,
187                 WIN32_PERF_RAW_DATA_PERF_OS_PROCESSOR_WHERE_NAME_TOTAL);
188     }
189 
190     /**
191      * Returns processor capacity performance counters.
192      *
193      * @return Performance Counters for processor capacity.
194      */
195     public static Pair<List<String>, Map<ProcessorUtilityTickCountProperty, List<Long>>> queryProcessorCapacityCounters() {
196         if (PerfmonDisabled.PERF_OS_DISABLED) {
197             return new Pair<>(Collections.emptyList(), Collections.emptyMap());
198         }
199         return PerfCounterWildcardQuery.queryInstancesAndValues(ProcessorUtilityTickCountProperty.class,
200                 PROCESSOR_INFORMATION, WIN32_PERF_RAW_DATA_COUNTERS_PROCESSOR_INFORMATION_WHERE_NOT_NAME_LIKE_TOTAL);
201     }
202 
203     /**
204      * Returns system interrupts counters.
205      *
206      * @return Interrupts counter for the total of all processors.
207      */
208     public static Map<InterruptsProperty, Long> queryInterruptCounters() {
209         if (PerfmonDisabled.PERF_OS_DISABLED) {
210             return Collections.emptyMap();
211         }
212         return PerfCounterQuery.queryValues(InterruptsProperty.class, PROCESSOR,
213                 WIN32_PERF_RAW_DATA_PERF_OS_PROCESSOR_WHERE_NAME_TOTAL);
214     }
215 
216     /**
217      * Returns processor frequency counters.
218      *
219      * @return Processor frequency counter for each processor.
220      */
221     public static Pair<List<String>, Map<ProcessorFrequencyProperty, List<Long>>> queryFrequencyCounters() {
222         if (PerfmonDisabled.PERF_OS_DISABLED) {
223             return new Pair<>(Collections.emptyList(), Collections.emptyMap());
224         }
225         return PerfCounterWildcardQuery.queryInstancesAndValues(ProcessorFrequencyProperty.class, PROCESSOR_INFORMATION,
226                 WIN32_PERF_RAW_DATA_COUNTERS_PROCESSOR_INFORMATION_WHERE_NOT_NAME_LIKE_TOTAL);
227     }
228 }