View Javadoc
1   /*
2    * Copyright 2020-2022 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     private ProcessorInformation() {
137     }
138 
139     /**
140      * Returns processor performance counters.
141      *
142      * @return Performance Counters for processors.
143      */
144     public static Pair<List<String>, Map<ProcessorTickCountProperty, List<Long>>> queryProcessorCounters() {
145         if (PerfmonDisabled.PERF_OS_DISABLED) {
146             return new Pair<>(Collections.emptyList(), Collections.emptyMap());
147         }
148         return IS_WIN7_OR_GREATER ? PerfCounterWildcardQuery.queryInstancesAndValues(ProcessorTickCountProperty.class,
149                 PROCESSOR_INFORMATION, WIN32_PERF_RAW_DATA_COUNTERS_PROCESSOR_INFORMATION_WHERE_NOT_NAME_LIKE_TOTAL)
150                 : PerfCounterWildcardQuery.queryInstancesAndValues(ProcessorTickCountProperty.class, PROCESSOR,
151                         WIN32_PERF_RAW_DATA_PERF_OS_PROCESSOR_WHERE_NAME_NOT_TOTAL);
152     }
153 
154     /**
155      * Returns processor capacity performance counters.
156      *
157      * @return Performance Counters for processor capacity.
158      */
159     public static Pair<List<String>, Map<ProcessorUtilityTickCountProperty, List<Long>>> queryProcessorCapacityCounters() {
160         if (PerfmonDisabled.PERF_OS_DISABLED) {
161             return new Pair<>(Collections.emptyList(), Collections.emptyMap());
162         }
163         return PerfCounterWildcardQuery.queryInstancesAndValues(ProcessorUtilityTickCountProperty.class,
164                 PROCESSOR_INFORMATION, WIN32_PERF_RAW_DATA_COUNTERS_PROCESSOR_INFORMATION_WHERE_NOT_NAME_LIKE_TOTAL);
165     }
166 
167     /**
168      * Returns system interrupts counters.
169      *
170      * @return Interrupts counter for the total of all processors.
171      */
172     public static Map<InterruptsProperty, Long> queryInterruptCounters() {
173         if (PerfmonDisabled.PERF_OS_DISABLED) {
174             return Collections.emptyMap();
175         }
176         return PerfCounterQuery.queryValues(InterruptsProperty.class, PROCESSOR,
177                 WIN32_PERF_RAW_DATA_PERF_OS_PROCESSOR_WHERE_NAME_TOTAL);
178     }
179 
180     /**
181      * Returns processor frequency counters.
182      *
183      * @return Processor frequency counter for each processor.
184      */
185     public static Pair<List<String>, Map<ProcessorFrequencyProperty, List<Long>>> queryFrequencyCounters() {
186         if (PerfmonDisabled.PERF_OS_DISABLED) {
187             return new Pair<>(Collections.emptyList(), Collections.emptyMap());
188         }
189         return PerfCounterWildcardQuery.queryInstancesAndValues(ProcessorFrequencyProperty.class, PROCESSOR_INFORMATION,
190                 WIN32_PERF_RAW_DATA_COUNTERS_PROCESSOR_INFORMATION_WHERE_NOT_NAME_LIKE_TOTAL);
191     }
192 }