From 3300502231b58227d8d3e7c16c762224757da48d Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 8 Nov 2022 12:40:17 -0500 Subject: [PATCH] darwin: use hw.cpufrequency again for frequency info (#3679) This reverts commit 87f076515937345fda1a1dbc598f34e65e1b81c7 and implements a work-around instead. This has been reported to be unnecessary, and also returns the wrong answer (off by exactly 100x), so it is not particularly useful. This also reverts the bugfixes to the original PR: Revert "darwin: fix iOS compilation and functionality" This reverts commit 1addf9b88a17bc32d009d377a14d540ccddd06db. Revert "macos: fix the cfdata length in uv__get_cpu_speed (#3356)" This reverts commit 1e7074913e1d2a1be72b62ba807325c14b0b317a. Revert "darwin: fix -Wsometimes-uninitialized warning" This reverts commit 6085bcef8dea1eaa21a92e2b6e6f03a0476b6c54. Revert "macos: fix memleaks in uv__get_cpu_speed" This reverts commit d2482ae121e0ae5d0cf0934b2e93cee81a4ac5ed. The expected behavior on failure to read this info is to report 0 (for example https://github.com/libuv/libuv/blob/8975c05d199558b0cc2e98f26ce33c6090d1 d7a1/src/unix/linux.c#L834), which is which was not the case before this PR for macos. However hw.cpufrequency sysctl seems to be missing on darwin/arm64 (Apple Silicon), so we instead hardcode a plausible value. This value matches what the mach kernel will report when running Rosetta apps. Fixes: https://github.com/libuv/libuv/issues/3642 Fixes: https://github.com/libuv/libuv/issues/2911 Refs: https://github.com/libuv/libuv/pull/2912 --- src/unix/darwin-stub.h | 16 ----- src/unix/darwin.c | 157 +++-------------------------------------- 2 files changed, 8 insertions(+), 165 deletions(-) diff --git a/src/unix/darwin-stub.h b/src/unix/darwin-stub.h index 433e3efa..b93cf67c 100644 --- a/src/unix/darwin-stub.h +++ b/src/unix/darwin-stub.h @@ -27,7 +27,6 @@ struct CFArrayCallBacks; struct CFRunLoopSourceContext; struct FSEventStreamContext; -struct CFRange; typedef double CFAbsoluteTime; typedef double CFTimeInterval; @@ -43,23 +42,13 @@ typedef unsigned CFStringEncoding; typedef void* CFAllocatorRef; typedef void* CFArrayRef; typedef void* CFBundleRef; -typedef void* CFDataRef; typedef void* CFDictionaryRef; -typedef void* CFMutableDictionaryRef; -typedef struct CFRange CFRange; typedef void* CFRunLoopRef; typedef void* CFRunLoopSourceRef; typedef void* CFStringRef; typedef void* CFTypeRef; typedef void* FSEventStreamRef; -typedef uint32_t IOOptionBits; -typedef unsigned int io_iterator_t; -typedef unsigned int io_object_t; -typedef unsigned int io_service_t; -typedef unsigned int io_registry_entry_t; - - typedef void (*FSEventStreamCallback)(const FSEventStreamRef, void*, size_t, @@ -80,11 +69,6 @@ struct FSEventStreamContext { void* pad[3]; }; -struct CFRange { - CFIndex location; - CFIndex length; -}; - static const CFStringEncoding kCFStringEncodingUTF8 = 0x8000100; static const OSStatus noErr = 0; diff --git a/src/unix/darwin.c b/src/unix/darwin.c index 62f04d31..7d2cacb6 100644 --- a/src/unix/darwin.c +++ b/src/unix/darwin.c @@ -33,13 +33,10 @@ #include #include /* sysconf */ -#include "darwin-stub.h" - static uv_once_t once = UV_ONCE_INIT; static uint64_t (*time_func)(void); static mach_timebase_info_data_t timebase; -typedef unsigned char UInt8; int uv__platform_loop_init(uv_loop_t* loop) { loop->cf_state = NULL; @@ -183,159 +180,17 @@ int uv_uptime(double* uptime) { return 0; } -static int uv__get_cpu_speed(uint64_t* speed) { - /* IOKit */ - void (*pIOObjectRelease)(io_object_t); - kern_return_t (*pIOMasterPort)(mach_port_t, mach_port_t*); - CFMutableDictionaryRef (*pIOServiceMatching)(const char*); - kern_return_t (*pIOServiceGetMatchingServices)(mach_port_t, - CFMutableDictionaryRef, - io_iterator_t*); - io_service_t (*pIOIteratorNext)(io_iterator_t); - CFTypeRef (*pIORegistryEntryCreateCFProperty)(io_registry_entry_t, - CFStringRef, - CFAllocatorRef, - IOOptionBits); - - /* CoreFoundation */ - CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, - const char*, - CFStringEncoding); - CFStringEncoding (*pCFStringGetSystemEncoding)(void); - UInt8 *(*pCFDataGetBytePtr)(CFDataRef); - CFIndex (*pCFDataGetLength)(CFDataRef); - void (*pCFDataGetBytes)(CFDataRef, CFRange, UInt8*); - void (*pCFRelease)(CFTypeRef); - - void* core_foundation_handle; - void* iokit_handle; - int err; - - kern_return_t kr; - mach_port_t mach_port; - io_iterator_t it; - io_object_t service; - - mach_port = 0; - - err = UV_ENOENT; - core_foundation_handle = dlopen("/System/Library/Frameworks/" - "CoreFoundation.framework/" - "CoreFoundation", - RTLD_LAZY | RTLD_LOCAL); - iokit_handle = dlopen("/System/Library/Frameworks/IOKit.framework/" - "IOKit", - RTLD_LAZY | RTLD_LOCAL); - - if (core_foundation_handle == NULL || iokit_handle == NULL) - goto out; - -#define V(handle, symbol) \ - do { \ - *(void **)(&p ## symbol) = dlsym((handle), #symbol); \ - if (p ## symbol == NULL) \ - goto out; \ - } \ - while (0) - V(iokit_handle, IOMasterPort); - V(iokit_handle, IOServiceMatching); - V(iokit_handle, IOServiceGetMatchingServices); - V(iokit_handle, IOIteratorNext); - V(iokit_handle, IOObjectRelease); - V(iokit_handle, IORegistryEntryCreateCFProperty); - V(core_foundation_handle, CFStringCreateWithCString); - V(core_foundation_handle, CFStringGetSystemEncoding); - V(core_foundation_handle, CFDataGetBytePtr); - V(core_foundation_handle, CFDataGetLength); - V(core_foundation_handle, CFDataGetBytes); - V(core_foundation_handle, CFRelease); -#undef V - -#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) - - kr = pIOMasterPort(MACH_PORT_NULL, &mach_port); - assert(kr == KERN_SUCCESS); - CFMutableDictionaryRef classes_to_match - = pIOServiceMatching("IOPlatformDevice"); - kr = pIOServiceGetMatchingServices(mach_port, classes_to_match, &it); - assert(kr == KERN_SUCCESS); - service = pIOIteratorNext(it); - - CFStringRef device_type_str = S("device_type"); - CFStringRef clock_frequency_str = S("clock-frequency"); - - while (service != 0) { - CFDataRef data; - data = pIORegistryEntryCreateCFProperty(service, - device_type_str, - NULL, - 0); - if (data) { - const UInt8* raw = pCFDataGetBytePtr(data); - if (strncmp((char*)raw, "cpu", 3) == 0 || - strncmp((char*)raw, "processor", 9) == 0) { - CFDataRef freq_ref; - freq_ref = pIORegistryEntryCreateCFProperty(service, - clock_frequency_str, - NULL, - 0); - if (freq_ref) { - const UInt8* freq_ref_ptr = pCFDataGetBytePtr(freq_ref); - CFIndex len = pCFDataGetLength(freq_ref); - if (len == 8) - memcpy(speed, freq_ref_ptr, 8); - else if (len == 4) { - uint32_t v; - memcpy(&v, freq_ref_ptr, 4); - *speed = v; - } else { - *speed = 0; - } - - pCFRelease(freq_ref); - pCFRelease(data); - break; - } - } - pCFRelease(data); - } - - service = pIOIteratorNext(it); - } - - pIOObjectRelease(it); - - err = 0; - - if (device_type_str != NULL) - pCFRelease(device_type_str); - if (clock_frequency_str != NULL) - pCFRelease(clock_frequency_str); - -out: - if (core_foundation_handle != NULL) - dlclose(core_foundation_handle); - - if (iokit_handle != NULL) - dlclose(iokit_handle); - - mach_port_deallocate(mach_task_self(), mach_port); - - return err; -} - int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), multiplier = ((uint64_t)1000L / ticks); char model[512]; + uint64_t cpuspeed; size_t size; unsigned int i; natural_t numcpus; mach_msg_type_number_t msg_type; processor_cpu_load_info_data_t *info; uv_cpu_info_t* cpu_info; - uint64_t cpuspeed; - int err; size = sizeof(model); if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) && @@ -343,9 +198,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { return UV__ERR(errno); } - err = uv__get_cpu_speed(&cpuspeed); - if (err < 0) - return err; + cpuspeed = 0; + size = sizeof(cpuspeed); + sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0); + if (cpuspeed == 0) + /* If sysctl hw.cputype == CPU_TYPE_ARM64, the correct value is unavailable + * from Apple, but we can hard-code it here to a plausible value. */ + cpuspeed = 2400000000; if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus, (processor_info_array_t*)&info,