1/* 2 * Copyright (c) 2011-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20 21/* 22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch 23 * which are subject to change in future releases of Mac OS X. Any applications 24 * relying on these interfaces WILL break. 25 */ 26 27#ifndef __DISPATCH_SHIMS_HW_CONFIG__ 28#define __DISPATCH_SHIMS_HW_CONFIG__ 29 30#if !TARGET_OS_WIN32 31 32typedef enum { 33 _dispatch_hw_config_logical_cpus, 34 _dispatch_hw_config_physical_cpus, 35 _dispatch_hw_config_active_cpus, 36} _dispatch_hw_config_t; 37 38#if !defined(DISPATCH_HAVE_HW_CONFIG_COMMPAGE) && \ 39 defined(_COMM_PAGE_LOGICAL_CPUS) && \ 40 defined(_COMM_PAGE_PHYSICAL_CPUS) && defined(_COMM_PAGE_ACTIVE_CPUS) 41#define DISPATCH_HAVE_HW_CONFIG_COMMPAGE 1 42#endif 43 44#if DISPATCH_HAVE_HW_CONFIG_COMMPAGE 45 46DISPATCH_ALWAYS_INLINE 47static inline uint32_t 48_dispatch_hw_get_config(_dispatch_hw_config_t c) 49{ 50 uintptr_t p; 51 switch (c) { 52 case _dispatch_hw_config_logical_cpus: 53 p = _COMM_PAGE_LOGICAL_CPUS; break; 54 case _dispatch_hw_config_physical_cpus: 55 p = _COMM_PAGE_PHYSICAL_CPUS; break; 56 case _dispatch_hw_config_active_cpus: 57 p = _COMM_PAGE_ACTIVE_CPUS; break; 58 } 59 return *(uint8_t*)p; 60} 61 62#define dispatch_hw_config(c) \ 63 _dispatch_hw_get_config(_dispatch_hw_config_##c) 64 65#define DISPATCH_HW_CONFIG() 66#define _dispatch_hw_config_init() 67 68#else // DISPATCH_HAVE_HW_CONFIG_COMMPAGE 69 70extern struct _dispatch_hw_configs_s { 71 uint32_t logical_cpus; 72 uint32_t physical_cpus; 73 uint32_t active_cpus; 74} _dispatch_hw_config; 75 76#define DISPATCH_HW_CONFIG() struct _dispatch_hw_configs_s _dispatch_hw_config 77#define dispatch_hw_config(c) (_dispatch_hw_config.c) 78 79DISPATCH_ALWAYS_INLINE 80static inline uint32_t 81_dispatch_hw_get_config(_dispatch_hw_config_t c) 82{ 83 uint32_t val = 1; 84 const char *name = NULL; 85 int r; 86#if defined(__APPLE__) 87 switch (c) { 88 case _dispatch_hw_config_logical_cpus: 89 name = "hw.logicalcpu_max"; break; 90 case _dispatch_hw_config_physical_cpus: 91 name = "hw.physicalcpu_max"; break; 92 case _dispatch_hw_config_active_cpus: 93 name = "hw.activecpu"; break; 94 } 95#elif defined(__FreeBSD__) 96 (void)c; name = "kern.smp.cpus"; 97#endif 98 if (name) { 99 size_t valsz = sizeof(val); 100 r = sysctlbyname(name, &val, &valsz, NULL, 0); 101 (void)dispatch_assume_zero(r); 102 dispatch_assert(valsz == sizeof(uint32_t)); 103 } else { 104#if HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN) 105 r = (int)sysconf(_SC_NPROCESSORS_ONLN); 106 if (r > 0) val = (uint32_t)r; 107#endif 108 } 109 return val; 110} 111 112#define dispatch_hw_config_init(c) \ 113 _dispatch_hw_get_config(_dispatch_hw_config_##c) 114 115static inline void 116_dispatch_hw_config_init(void) 117{ 118 dispatch_hw_config(logical_cpus) = dispatch_hw_config_init(logical_cpus); 119 dispatch_hw_config(physical_cpus) = dispatch_hw_config_init(physical_cpus); 120 dispatch_hw_config(active_cpus) = dispatch_hw_config_init(active_cpus); 121} 122 123#undef dispatch_hw_config_init 124 125#endif // DISPATCH_HAVE_HW_CONFIG_COMMPAGE 126 127#else // TARGET_OS_WIN32 128 129static inline long 130_dispatch_count_bits(unsigned long value) 131{ 132 long bits = 0; 133 while (value) { 134 bits += (value & 1); 135 value = value >> 1; 136 } 137 return bits; 138} 139 140static inline uint32_t 141_dispatch_get_ncpus(void) 142{ 143 uint32_t val; 144 DWORD_PTR procmask, sysmask; 145 if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, &sysmask)) { 146 val = _dispatch_count_bits(procmask); 147 } else { 148 val = 1; 149 } 150 return val; 151} 152#endif // TARGET_OS_WIN32 153 154#endif /* __DISPATCH_SHIMS_HW_CONFIG__ */ 155