11cb0ef41Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 21cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 31cb0ef41Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 41cb0ef41Sopenharmony_ci * deal in the Software without restriction, including without limitation the 51cb0ef41Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 61cb0ef41Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 71cb0ef41Sopenharmony_ci * furnished to do so, subject to the following conditions: 81cb0ef41Sopenharmony_ci * 91cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 101cb0ef41Sopenharmony_ci * all copies or substantial portions of the Software. 111cb0ef41Sopenharmony_ci * 121cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 131cb0ef41Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 141cb0ef41Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 151cb0ef41Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 161cb0ef41Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 171cb0ef41Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 181cb0ef41Sopenharmony_ci * IN THE SOFTWARE. 191cb0ef41Sopenharmony_ci */ 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci#include "uv.h" 221cb0ef41Sopenharmony_ci#include "internal.h" 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci#include <assert.h> 251cb0ef41Sopenharmony_ci#include <stdint.h> 261cb0ef41Sopenharmony_ci#include <errno.h> 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci#include <dlfcn.h> 291cb0ef41Sopenharmony_ci#include <mach/mach.h> 301cb0ef41Sopenharmony_ci#include <mach/mach_time.h> 311cb0ef41Sopenharmony_ci#include <mach-o/dyld.h> /* _NSGetExecutablePath */ 321cb0ef41Sopenharmony_ci#include <sys/resource.h> 331cb0ef41Sopenharmony_ci#include <sys/sysctl.h> 341cb0ef41Sopenharmony_ci#include <unistd.h> /* sysconf */ 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci#include "darwin-stub.h" 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_cistatic uv_once_t once = UV_ONCE_INIT; 391cb0ef41Sopenharmony_cistatic uint64_t (*time_func)(void); 401cb0ef41Sopenharmony_cistatic mach_timebase_info_data_t timebase; 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_citypedef unsigned char UInt8; 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ciint uv__platform_loop_init(uv_loop_t* loop) { 451cb0ef41Sopenharmony_ci loop->cf_state = NULL; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci if (uv__kqueue_init(loop)) 481cb0ef41Sopenharmony_ci return UV__ERR(errno); 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci return 0; 511cb0ef41Sopenharmony_ci} 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_civoid uv__platform_loop_delete(uv_loop_t* loop) { 551cb0ef41Sopenharmony_ci uv__fsevents_loop_delete(loop); 561cb0ef41Sopenharmony_ci} 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_cistatic void uv__hrtime_init_once(void) { 601cb0ef41Sopenharmony_ci if (KERN_SUCCESS != mach_timebase_info(&timebase)) 611cb0ef41Sopenharmony_ci abort(); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci time_func = (uint64_t (*)(void)) dlsym(RTLD_DEFAULT, "mach_continuous_time"); 641cb0ef41Sopenharmony_ci if (time_func == NULL) 651cb0ef41Sopenharmony_ci time_func = mach_absolute_time; 661cb0ef41Sopenharmony_ci} 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ciuint64_t uv__hrtime(uv_clocktype_t type) { 701cb0ef41Sopenharmony_ci uv_once(&once, uv__hrtime_init_once); 711cb0ef41Sopenharmony_ci return time_func() * timebase.numer / timebase.denom; 721cb0ef41Sopenharmony_ci} 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ciint uv_exepath(char* buffer, size_t* size) { 761cb0ef41Sopenharmony_ci /* realpath(exepath) may be > PATH_MAX so double it to be on the safe side. */ 771cb0ef41Sopenharmony_ci char abspath[PATH_MAX * 2 + 1]; 781cb0ef41Sopenharmony_ci char exepath[PATH_MAX + 1]; 791cb0ef41Sopenharmony_ci uint32_t exepath_size; 801cb0ef41Sopenharmony_ci size_t abspath_size; 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci if (buffer == NULL || size == NULL || *size == 0) 831cb0ef41Sopenharmony_ci return UV_EINVAL; 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci exepath_size = sizeof(exepath); 861cb0ef41Sopenharmony_ci if (_NSGetExecutablePath(exepath, &exepath_size)) 871cb0ef41Sopenharmony_ci return UV_EIO; 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci if (realpath(exepath, abspath) != abspath) 901cb0ef41Sopenharmony_ci return UV__ERR(errno); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci abspath_size = strlen(abspath); 931cb0ef41Sopenharmony_ci if (abspath_size == 0) 941cb0ef41Sopenharmony_ci return UV_EIO; 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci *size -= 1; 971cb0ef41Sopenharmony_ci if (*size > abspath_size) 981cb0ef41Sopenharmony_ci *size = abspath_size; 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci memcpy(buffer, abspath, *size); 1011cb0ef41Sopenharmony_ci buffer[*size] = '\0'; 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci return 0; 1041cb0ef41Sopenharmony_ci} 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ciuint64_t uv_get_free_memory(void) { 1081cb0ef41Sopenharmony_ci vm_statistics_data_t info; 1091cb0ef41Sopenharmony_ci mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci if (host_statistics(mach_host_self(), HOST_VM_INFO, 1121cb0ef41Sopenharmony_ci (host_info_t)&info, &count) != KERN_SUCCESS) { 1131cb0ef41Sopenharmony_ci return UV_EINVAL; /* FIXME(bnoordhuis) Translate error. */ 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci return (uint64_t) info.free_count * sysconf(_SC_PAGESIZE); 1171cb0ef41Sopenharmony_ci} 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ciuint64_t uv_get_total_memory(void) { 1211cb0ef41Sopenharmony_ci uint64_t info; 1221cb0ef41Sopenharmony_ci int which[] = {CTL_HW, HW_MEMSIZE}; 1231cb0ef41Sopenharmony_ci size_t size = sizeof(info); 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) 1261cb0ef41Sopenharmony_ci return UV__ERR(errno); 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci return (uint64_t) info; 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ciuint64_t uv_get_constrained_memory(void) { 1331cb0ef41Sopenharmony_ci return 0; /* Memory constraints are unknown. */ 1341cb0ef41Sopenharmony_ci} 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_civoid uv_loadavg(double avg[3]) { 1381cb0ef41Sopenharmony_ci struct loadavg info; 1391cb0ef41Sopenharmony_ci size_t size = sizeof(info); 1401cb0ef41Sopenharmony_ci int which[] = {CTL_VM, VM_LOADAVG}; 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return; 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci avg[0] = (double) info.ldavg[0] / info.fscale; 1451cb0ef41Sopenharmony_ci avg[1] = (double) info.ldavg[1] / info.fscale; 1461cb0ef41Sopenharmony_ci avg[2] = (double) info.ldavg[2] / info.fscale; 1471cb0ef41Sopenharmony_ci} 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ciint uv_resident_set_memory(size_t* rss) { 1511cb0ef41Sopenharmony_ci mach_msg_type_number_t count; 1521cb0ef41Sopenharmony_ci task_basic_info_data_t info; 1531cb0ef41Sopenharmony_ci kern_return_t err; 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci count = TASK_BASIC_INFO_COUNT; 1561cb0ef41Sopenharmony_ci err = task_info(mach_task_self(), 1571cb0ef41Sopenharmony_ci TASK_BASIC_INFO, 1581cb0ef41Sopenharmony_ci (task_info_t) &info, 1591cb0ef41Sopenharmony_ci &count); 1601cb0ef41Sopenharmony_ci (void) &err; 1611cb0ef41Sopenharmony_ci /* task_info(TASK_BASIC_INFO) cannot really fail. Anything other than 1621cb0ef41Sopenharmony_ci * KERN_SUCCESS implies a libuv bug. 1631cb0ef41Sopenharmony_ci */ 1641cb0ef41Sopenharmony_ci assert(err == KERN_SUCCESS); 1651cb0ef41Sopenharmony_ci *rss = info.resident_size; 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci return 0; 1681cb0ef41Sopenharmony_ci} 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ciint uv_uptime(double* uptime) { 1721cb0ef41Sopenharmony_ci time_t now; 1731cb0ef41Sopenharmony_ci struct timeval info; 1741cb0ef41Sopenharmony_ci size_t size = sizeof(info); 1751cb0ef41Sopenharmony_ci static int which[] = {CTL_KERN, KERN_BOOTTIME}; 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) 1781cb0ef41Sopenharmony_ci return UV__ERR(errno); 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci now = time(NULL); 1811cb0ef41Sopenharmony_ci *uptime = now - info.tv_sec; 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci return 0; 1841cb0ef41Sopenharmony_ci} 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_cistatic int uv__get_cpu_speed(uint64_t* speed) { 1871cb0ef41Sopenharmony_ci /* IOKit */ 1881cb0ef41Sopenharmony_ci void (*pIOObjectRelease)(io_object_t); 1891cb0ef41Sopenharmony_ci kern_return_t (*pIOMasterPort)(mach_port_t, mach_port_t*); 1901cb0ef41Sopenharmony_ci CFMutableDictionaryRef (*pIOServiceMatching)(const char*); 1911cb0ef41Sopenharmony_ci kern_return_t (*pIOServiceGetMatchingServices)(mach_port_t, 1921cb0ef41Sopenharmony_ci CFMutableDictionaryRef, 1931cb0ef41Sopenharmony_ci io_iterator_t*); 1941cb0ef41Sopenharmony_ci io_service_t (*pIOIteratorNext)(io_iterator_t); 1951cb0ef41Sopenharmony_ci CFTypeRef (*pIORegistryEntryCreateCFProperty)(io_registry_entry_t, 1961cb0ef41Sopenharmony_ci CFStringRef, 1971cb0ef41Sopenharmony_ci CFAllocatorRef, 1981cb0ef41Sopenharmony_ci IOOptionBits); 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci /* CoreFoundation */ 2011cb0ef41Sopenharmony_ci CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, 2021cb0ef41Sopenharmony_ci const char*, 2031cb0ef41Sopenharmony_ci CFStringEncoding); 2041cb0ef41Sopenharmony_ci CFStringEncoding (*pCFStringGetSystemEncoding)(void); 2051cb0ef41Sopenharmony_ci UInt8 *(*pCFDataGetBytePtr)(CFDataRef); 2061cb0ef41Sopenharmony_ci CFIndex (*pCFDataGetLength)(CFDataRef); 2071cb0ef41Sopenharmony_ci void (*pCFDataGetBytes)(CFDataRef, CFRange, UInt8*); 2081cb0ef41Sopenharmony_ci void (*pCFRelease)(CFTypeRef); 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci void* core_foundation_handle; 2111cb0ef41Sopenharmony_ci void* iokit_handle; 2121cb0ef41Sopenharmony_ci int err; 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci kern_return_t kr; 2151cb0ef41Sopenharmony_ci mach_port_t mach_port; 2161cb0ef41Sopenharmony_ci io_iterator_t it; 2171cb0ef41Sopenharmony_ci io_object_t service; 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci mach_port = 0; 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci err = UV_ENOENT; 2221cb0ef41Sopenharmony_ci core_foundation_handle = dlopen("/System/Library/Frameworks/" 2231cb0ef41Sopenharmony_ci "CoreFoundation.framework/" 2241cb0ef41Sopenharmony_ci "CoreFoundation", 2251cb0ef41Sopenharmony_ci RTLD_LAZY | RTLD_LOCAL); 2261cb0ef41Sopenharmony_ci iokit_handle = dlopen("/System/Library/Frameworks/IOKit.framework/" 2271cb0ef41Sopenharmony_ci "IOKit", 2281cb0ef41Sopenharmony_ci RTLD_LAZY | RTLD_LOCAL); 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci if (core_foundation_handle == NULL || iokit_handle == NULL) 2311cb0ef41Sopenharmony_ci goto out; 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci#define V(handle, symbol) \ 2341cb0ef41Sopenharmony_ci do { \ 2351cb0ef41Sopenharmony_ci *(void **)(&p ## symbol) = dlsym((handle), #symbol); \ 2361cb0ef41Sopenharmony_ci if (p ## symbol == NULL) \ 2371cb0ef41Sopenharmony_ci goto out; \ 2381cb0ef41Sopenharmony_ci } \ 2391cb0ef41Sopenharmony_ci while (0) 2401cb0ef41Sopenharmony_ci V(iokit_handle, IOMasterPort); 2411cb0ef41Sopenharmony_ci V(iokit_handle, IOServiceMatching); 2421cb0ef41Sopenharmony_ci V(iokit_handle, IOServiceGetMatchingServices); 2431cb0ef41Sopenharmony_ci V(iokit_handle, IOIteratorNext); 2441cb0ef41Sopenharmony_ci V(iokit_handle, IOObjectRelease); 2451cb0ef41Sopenharmony_ci V(iokit_handle, IORegistryEntryCreateCFProperty); 2461cb0ef41Sopenharmony_ci V(core_foundation_handle, CFStringCreateWithCString); 2471cb0ef41Sopenharmony_ci V(core_foundation_handle, CFStringGetSystemEncoding); 2481cb0ef41Sopenharmony_ci V(core_foundation_handle, CFDataGetBytePtr); 2491cb0ef41Sopenharmony_ci V(core_foundation_handle, CFDataGetLength); 2501cb0ef41Sopenharmony_ci V(core_foundation_handle, CFDataGetBytes); 2511cb0ef41Sopenharmony_ci V(core_foundation_handle, CFRelease); 2521cb0ef41Sopenharmony_ci#undef V 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci kr = pIOMasterPort(MACH_PORT_NULL, &mach_port); 2571cb0ef41Sopenharmony_ci assert(kr == KERN_SUCCESS); 2581cb0ef41Sopenharmony_ci CFMutableDictionaryRef classes_to_match 2591cb0ef41Sopenharmony_ci = pIOServiceMatching("IOPlatformDevice"); 2601cb0ef41Sopenharmony_ci kr = pIOServiceGetMatchingServices(mach_port, classes_to_match, &it); 2611cb0ef41Sopenharmony_ci assert(kr == KERN_SUCCESS); 2621cb0ef41Sopenharmony_ci service = pIOIteratorNext(it); 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci CFStringRef device_type_str = S("device_type"); 2651cb0ef41Sopenharmony_ci CFStringRef clock_frequency_str = S("clock-frequency"); 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci while (service != 0) { 2681cb0ef41Sopenharmony_ci CFDataRef data; 2691cb0ef41Sopenharmony_ci data = pIORegistryEntryCreateCFProperty(service, 2701cb0ef41Sopenharmony_ci device_type_str, 2711cb0ef41Sopenharmony_ci NULL, 2721cb0ef41Sopenharmony_ci 0); 2731cb0ef41Sopenharmony_ci if (data) { 2741cb0ef41Sopenharmony_ci const UInt8* raw = pCFDataGetBytePtr(data); 2751cb0ef41Sopenharmony_ci if (strncmp((char*)raw, "cpu", 3) == 0 || 2761cb0ef41Sopenharmony_ci strncmp((char*)raw, "processor", 9) == 0) { 2771cb0ef41Sopenharmony_ci CFDataRef freq_ref; 2781cb0ef41Sopenharmony_ci freq_ref = pIORegistryEntryCreateCFProperty(service, 2791cb0ef41Sopenharmony_ci clock_frequency_str, 2801cb0ef41Sopenharmony_ci NULL, 2811cb0ef41Sopenharmony_ci 0); 2821cb0ef41Sopenharmony_ci if (freq_ref) { 2831cb0ef41Sopenharmony_ci const UInt8* freq_ref_ptr = pCFDataGetBytePtr(freq_ref); 2841cb0ef41Sopenharmony_ci CFIndex len = pCFDataGetLength(freq_ref); 2851cb0ef41Sopenharmony_ci if (len == 8) 2861cb0ef41Sopenharmony_ci memcpy(speed, freq_ref_ptr, 8); 2871cb0ef41Sopenharmony_ci else if (len == 4) { 2881cb0ef41Sopenharmony_ci uint32_t v; 2891cb0ef41Sopenharmony_ci memcpy(&v, freq_ref_ptr, 4); 2901cb0ef41Sopenharmony_ci *speed = v; 2911cb0ef41Sopenharmony_ci } else { 2921cb0ef41Sopenharmony_ci *speed = 0; 2931cb0ef41Sopenharmony_ci } 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci pCFRelease(freq_ref); 2961cb0ef41Sopenharmony_ci pCFRelease(data); 2971cb0ef41Sopenharmony_ci break; 2981cb0ef41Sopenharmony_ci } 2991cb0ef41Sopenharmony_ci } 3001cb0ef41Sopenharmony_ci pCFRelease(data); 3011cb0ef41Sopenharmony_ci } 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci service = pIOIteratorNext(it); 3041cb0ef41Sopenharmony_ci } 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci pIOObjectRelease(it); 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci err = 0; 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci if (device_type_str != NULL) 3111cb0ef41Sopenharmony_ci pCFRelease(device_type_str); 3121cb0ef41Sopenharmony_ci if (clock_frequency_str != NULL) 3131cb0ef41Sopenharmony_ci pCFRelease(clock_frequency_str); 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ciout: 3161cb0ef41Sopenharmony_ci if (core_foundation_handle != NULL) 3171cb0ef41Sopenharmony_ci dlclose(core_foundation_handle); 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ci if (iokit_handle != NULL) 3201cb0ef41Sopenharmony_ci dlclose(iokit_handle); 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ci mach_port_deallocate(mach_task_self(), mach_port); 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci return err; 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ciint uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { 3281cb0ef41Sopenharmony_ci unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), 3291cb0ef41Sopenharmony_ci multiplier = ((uint64_t)1000L / ticks); 3301cb0ef41Sopenharmony_ci char model[512]; 3311cb0ef41Sopenharmony_ci size_t size; 3321cb0ef41Sopenharmony_ci unsigned int i; 3331cb0ef41Sopenharmony_ci natural_t numcpus; 3341cb0ef41Sopenharmony_ci mach_msg_type_number_t msg_type; 3351cb0ef41Sopenharmony_ci processor_cpu_load_info_data_t *info; 3361cb0ef41Sopenharmony_ci uv_cpu_info_t* cpu_info; 3371cb0ef41Sopenharmony_ci uint64_t cpuspeed; 3381cb0ef41Sopenharmony_ci int err; 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ci size = sizeof(model); 3411cb0ef41Sopenharmony_ci if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) && 3421cb0ef41Sopenharmony_ci sysctlbyname("hw.model", &model, &size, NULL, 0)) { 3431cb0ef41Sopenharmony_ci return UV__ERR(errno); 3441cb0ef41Sopenharmony_ci } 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_ci err = uv__get_cpu_speed(&cpuspeed); 3471cb0ef41Sopenharmony_ci if (err < 0) 3481cb0ef41Sopenharmony_ci return err; 3491cb0ef41Sopenharmony_ci 3501cb0ef41Sopenharmony_ci if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus, 3511cb0ef41Sopenharmony_ci (processor_info_array_t*)&info, 3521cb0ef41Sopenharmony_ci &msg_type) != KERN_SUCCESS) { 3531cb0ef41Sopenharmony_ci return UV_EINVAL; /* FIXME(bnoordhuis) Translate error. */ 3541cb0ef41Sopenharmony_ci } 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); 3571cb0ef41Sopenharmony_ci if (!(*cpu_infos)) { 3581cb0ef41Sopenharmony_ci vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); 3591cb0ef41Sopenharmony_ci return UV_ENOMEM; 3601cb0ef41Sopenharmony_ci } 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci *count = numcpus; 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ci for (i = 0; i < numcpus; i++) { 3651cb0ef41Sopenharmony_ci cpu_info = &(*cpu_infos)[i]; 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci cpu_info->cpu_times.user = (uint64_t)(info[i].cpu_ticks[0]) * multiplier; 3681cb0ef41Sopenharmony_ci cpu_info->cpu_times.nice = (uint64_t)(info[i].cpu_ticks[3]) * multiplier; 3691cb0ef41Sopenharmony_ci cpu_info->cpu_times.sys = (uint64_t)(info[i].cpu_ticks[1]) * multiplier; 3701cb0ef41Sopenharmony_ci cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier; 3711cb0ef41Sopenharmony_ci cpu_info->cpu_times.irq = 0; 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci cpu_info->model = uv__strdup(model); 3741cb0ef41Sopenharmony_ci cpu_info->speed = cpuspeed/1000000; 3751cb0ef41Sopenharmony_ci } 3761cb0ef41Sopenharmony_ci vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci return 0; 3791cb0ef41Sopenharmony_ci} 380