@@ -26,6 +26,10 @@ For reference, here's the git history with original implementations:
26
26
#include <sys/sysctl.h>
27
27
#include <sys/vmmeter.h>
28
28
#include <mach/mach.h>
29
+ #if defined(__arm64__ ) || defined(__aarch64__ )
30
+ #include <CoreFoundation/CoreFoundation.h>
31
+ #include <IOKit/IOKitLib.h>
32
+ #endif
29
33
30
34
#include "../../_psutil_common.h"
31
35
#include "../../_psutil_posix.h"
@@ -109,7 +113,122 @@ psutil_cpu_stats(PyObject *self, PyObject *args) {
109
113
);
110
114
}
111
115
116
+ #if defined(__arm64__ ) || defined(__aarch64__ )
117
+ PyObject *
118
+ psutil_cpu_freq (PyObject * self , PyObject * args ) {
119
+ uint32_t min ;
120
+ uint32_t curr ;
121
+ uint32_t pMin ;
122
+ uint32_t eMin ;
123
+ uint32_t max ;
124
+ kern_return_t status ;
125
+ CFDictionaryRef matching = NULL ;
126
+ CFTypeRef pCoreRef = NULL ;
127
+ CFTypeRef eCoreRef = NULL ;
128
+ io_iterator_t iter = 0 ;
129
+ io_registry_entry_t entry = 0 ;
130
+ io_name_t name ;
131
+
132
+ matching = IOServiceMatching ("AppleARMIODevice" );
133
+ if (matching == 0 ) {
134
+ return PyErr_Format (
135
+ PyExc_RuntimeError ,
136
+ "IOServiceMatching call failed, 'AppleARMIODevice' not found"
137
+ );
138
+ }
139
+
140
+ status = IOServiceGetMatchingServices (kIOMainPortDefault , matching , & iter );
141
+ if (status != KERN_SUCCESS ) {
142
+ PyErr_Format (
143
+ PyExc_RuntimeError , "IOServiceGetMatchingServices call failed"
144
+ );
145
+ goto error ;
146
+ }
147
+
148
+ while ((entry = IOIteratorNext (iter )) != 0 ) {
149
+ status = IORegistryEntryGetName (entry , name );
150
+ if (status != KERN_SUCCESS ) {
151
+ IOObjectRelease (entry );
152
+ continue ;
153
+ }
154
+ if (strcmp (name , "pmgr" ) == 0 ) {
155
+ break ;
156
+ }
157
+ IOObjectRelease (entry );
158
+ }
112
159
160
+ if (entry == 0 ) {
161
+ PyErr_Format (
162
+ PyExc_RuntimeError ,
163
+ "'pmgr' entry was not found in AppleARMIODevice service"
164
+ );
165
+ goto error ;
166
+ }
167
+
168
+ pCoreRef = IORegistryEntryCreateCFProperty (
169
+ entry , CFSTR ("voltage-states5-sram" ), kCFAllocatorDefault , 0 );
170
+ if (pCoreRef == NULL ) {
171
+ PyErr_Format (
172
+ PyExc_RuntimeError , "'voltage-states5-sram' property not found" );
173
+ goto error ;
174
+ }
175
+
176
+ eCoreRef = IORegistryEntryCreateCFProperty (
177
+ entry , CFSTR ("voltage-states1-sram" ), kCFAllocatorDefault , 0 );
178
+ if (eCoreRef == NULL ) {
179
+ PyErr_Format (
180
+ PyExc_RuntimeError , "'voltage-states1-sram' property not found" );
181
+ goto error ;
182
+ }
183
+
184
+ size_t pCoreLength = CFDataGetLength (pCoreRef );
185
+ size_t eCoreLength = CFDataGetLength (eCoreRef );
186
+ if (pCoreLength < 8 ) {
187
+ PyErr_Format (
188
+ PyExc_RuntimeError ,
189
+ "expected 'voltage-states5-sram' buffer to have at least size 8"
190
+ );
191
+ goto error ;
192
+ }
193
+ if (eCoreLength < 4 ) {
194
+ PyErr_Format (
195
+ PyExc_RuntimeError ,
196
+ "expected 'voltage-states1-sram' buffer to have at least size 4"
197
+ );
198
+ goto error ;
199
+ }
200
+
201
+ CFDataGetBytes (pCoreRef , CFRangeMake (0 , 4 ), (UInt8 * ) & pMin );
202
+ CFDataGetBytes (eCoreRef , CFRangeMake (0 , 4 ), (UInt8 * ) & eMin );
203
+ CFDataGetBytes (pCoreRef , CFRangeMake (pCoreLength - 8 , 4 ), (UInt8 * ) & max );
204
+
205
+ min = pMin < eMin ? pMin : eMin ;
206
+ curr = max ;
207
+
208
+ CFRelease (pCoreRef );
209
+ CFRelease (eCoreRef );
210
+ IOObjectRelease (iter );
211
+ IOObjectRelease (entry );
212
+
213
+ return Py_BuildValue (
214
+ "IKK" ,
215
+ curr / 1000 / 1000 ,
216
+ min / 1000 / 1000 ,
217
+ max / 1000 / 1000
218
+ );
219
+
220
+ error :
221
+ if (pCoreRef != NULL )
222
+ CFRelease (pCoreRef );
223
+ if (eCoreRef != NULL )
224
+ CFRelease (eCoreRef );
225
+ if (iter != 0 )
226
+ IOObjectRelease (iter );
227
+ if (entry != 0 )
228
+ IOObjectRelease (entry );
229
+ return NULL ;
230
+ }
231
+ #else
113
232
PyObject *
114
233
psutil_cpu_freq (PyObject * self , PyObject * args ) {
115
234
unsigned int curr ;
@@ -138,7 +257,7 @@ psutil_cpu_freq(PyObject *self, PyObject *args) {
138
257
min / 1000 / 1000 ,
139
258
max / 1000 / 1000 );
140
259
}
141
-
260
+ #endif
142
261
143
262
PyObject *
144
263
psutil_per_cpu_times (PyObject * self , PyObject * args ) {
0 commit comments