2 * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
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.
27 #ifndef __DISPATCH_SHIMS_HW_CONFIG__
28 #define __DISPATCH_SHIMS_HW_CONFIG__
30 #ifdef __SIZEOF_POINTER__
31 #define DISPATCH_SIZEOF_PTR __SIZEOF_POINTER__
33 #define DISPATCH_SIZEOF_PTR 8
35 #define DISPATCH_SIZEOF_PTR 4
36 #elif defined(_MSC_VER)
37 #error "could not determine pointer size as a constant int for MSVC"
38 #elif defined(__LP64__) || defined(__LLP64__)
39 #define DISPATCH_SIZEOF_PTR 8
40 #elif defined(__ILP32__)
41 #define DISPATCH_SIZEOF_PTR 4
43 #error "could not determine pointer size as a constant int"
44 #endif // __SIZEOF_POINTER__
49 _dispatch_hw_config_logical_cpus
,
50 _dispatch_hw_config_physical_cpus
,
51 _dispatch_hw_config_active_cpus
,
52 } _dispatch_hw_config_t
;
54 #if !defined(DISPATCH_HAVE_HW_CONFIG_COMMPAGE) && \
55 defined(_COMM_PAGE_LOGICAL_CPUS) && \
56 defined(_COMM_PAGE_PHYSICAL_CPUS) && defined(_COMM_PAGE_ACTIVE_CPUS)
57 #define DISPATCH_HAVE_HW_CONFIG_COMMPAGE 1
60 #if DISPATCH_HAVE_HW_CONFIG_COMMPAGE
62 DISPATCH_ALWAYS_INLINE
63 static inline uint32_t
64 _dispatch_hw_get_config(_dispatch_hw_config_t c
)
68 case _dispatch_hw_config_logical_cpus
:
69 p
= _COMM_PAGE_LOGICAL_CPUS
; break;
70 case _dispatch_hw_config_physical_cpus
:
71 p
= _COMM_PAGE_PHYSICAL_CPUS
; break;
72 case _dispatch_hw_config_active_cpus
:
73 p
= _COMM_PAGE_ACTIVE_CPUS
; break;
78 #define dispatch_hw_config(c) \
79 _dispatch_hw_get_config(_dispatch_hw_config_##c)
81 #define DISPATCH_HW_CONFIG()
82 #define _dispatch_hw_config_init()
84 #else // DISPATCH_HAVE_HW_CONFIG_COMMPAGE
86 extern struct _dispatch_hw_configs_s
{
87 uint32_t logical_cpus
;
88 uint32_t physical_cpus
;
90 } _dispatch_hw_config
;
92 #define DISPATCH_HW_CONFIG() struct _dispatch_hw_configs_s _dispatch_hw_config
93 #define dispatch_hw_config(c) (_dispatch_hw_config.c)
95 DISPATCH_ALWAYS_INLINE
96 static inline uint32_t
97 _dispatch_hw_get_config(_dispatch_hw_config_t c
)
100 #if defined(__linux__) && HAVE_SYSCONF
102 case _dispatch_hw_config_logical_cpus
:
103 case _dispatch_hw_config_physical_cpus
:
104 return (uint32_t)sysconf(_SC_NPROCESSORS_CONF
);
105 case _dispatch_hw_config_active_cpus
:
108 // Prefer pthread_getaffinity_np because it considers
109 // scheduler cpu affinity. This matters if the program
110 // is restricted to a subset of the online cpus (eg via numactl).
112 if (pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t
), &cpuset
) == 0)
113 return (uint32_t)CPU_COUNT(&cpuset
);
115 return (uint32_t)sysconf(_SC_NPROCESSORS_ONLN
);
119 const char *name
= NULL
;
121 #if defined(__APPLE__)
123 case _dispatch_hw_config_logical_cpus
:
124 name
= "hw.logicalcpu_max"; break;
125 case _dispatch_hw_config_physical_cpus
:
126 name
= "hw.physicalcpu_max"; break;
127 case _dispatch_hw_config_active_cpus
:
128 name
= "hw.activecpu"; break;
130 #elif defined(__FreeBSD__)
131 (void)c
; name
= "kern.smp.cpus";
134 size_t valsz
= sizeof(val
);
135 r
= sysctlbyname(name
, &val
, &valsz
, NULL
, 0);
136 (void)dispatch_assume_zero(r
);
137 dispatch_assert(valsz
== sizeof(uint32_t));
139 #if HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
140 r
= (int)sysconf(_SC_NPROCESSORS_ONLN
);
141 if (r
> 0) val
= (uint32_t)r
;
148 #define dispatch_hw_config_init(c) \
149 _dispatch_hw_get_config(_dispatch_hw_config_##c)
152 _dispatch_hw_config_init(void)
154 dispatch_hw_config(logical_cpus
) = dispatch_hw_config_init(logical_cpus
);
155 dispatch_hw_config(physical_cpus
) = dispatch_hw_config_init(physical_cpus
);
156 dispatch_hw_config(active_cpus
) = dispatch_hw_config_init(active_cpus
);
159 #undef dispatch_hw_config_init
161 #endif // DISPATCH_HAVE_HW_CONFIG_COMMPAGE
163 #else // TARGET_OS_WIN32
166 _dispatch_count_bits(unsigned long value
)
176 static inline uint32_t
177 _dispatch_get_ncpus(void)
180 DWORD_PTR procmask
, sysmask
;
181 if (GetProcessAffinityMask(GetCurrentProcess(), &procmask
, &sysmask
)) {
182 val
= _dispatch_count_bits(procmask
);
188 #endif // TARGET_OS_WIN32
190 #endif /* __DISPATCH_SHIMS_HW_CONFIG__ */