]> git.saurik.com Git - apple/libdispatch.git/blob - src/shims/hw_config.h
libdispatch-703.1.4.tar.gz
[apple/libdispatch.git] / src / shims / hw_config.h
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
32 typedef 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
46 DISPATCH_ALWAYS_INLINE
47 static 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
70 extern 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
79 DISPATCH_ALWAYS_INLINE
80 static inline uint32_t
81 _dispatch_hw_get_config(_dispatch_hw_config_t c)
82 {
83 uint32_t val = 1;
84 #if defined(__linux__) && HAVE_SYSCONF
85 switch (c) {
86 case _dispatch_hw_config_logical_cpus:
87 case _dispatch_hw_config_physical_cpus:
88 return sysconf(_SC_NPROCESSORS_CONF);
89 case _dispatch_hw_config_active_cpus:
90 return sysconf(_SC_NPROCESSORS_ONLN);
91 }
92 #else
93 const char *name = NULL;
94 int r;
95 #if defined(__APPLE__)
96 switch (c) {
97 case _dispatch_hw_config_logical_cpus:
98 name = "hw.logicalcpu_max"; break;
99 case _dispatch_hw_config_physical_cpus:
100 name = "hw.physicalcpu_max"; break;
101 case _dispatch_hw_config_active_cpus:
102 name = "hw.activecpu"; break;
103 }
104 #elif defined(__FreeBSD__)
105 (void)c; name = "kern.smp.cpus";
106 #endif
107 if (name) {
108 size_t valsz = sizeof(val);
109 r = sysctlbyname(name, &val, &valsz, NULL, 0);
110 (void)dispatch_assume_zero(r);
111 dispatch_assert(valsz == sizeof(uint32_t));
112 } else {
113 #if HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
114 r = (int)sysconf(_SC_NPROCESSORS_ONLN);
115 if (r > 0) val = (uint32_t)r;
116 #endif
117 }
118 #endif
119 return val;
120 }
121
122 #define dispatch_hw_config_init(c) \
123 _dispatch_hw_get_config(_dispatch_hw_config_##c)
124
125 static inline void
126 _dispatch_hw_config_init(void)
127 {
128 dispatch_hw_config(logical_cpus) = dispatch_hw_config_init(logical_cpus);
129 dispatch_hw_config(physical_cpus) = dispatch_hw_config_init(physical_cpus);
130 dispatch_hw_config(active_cpus) = dispatch_hw_config_init(active_cpus);
131 }
132
133 #undef dispatch_hw_config_init
134
135 #endif // DISPATCH_HAVE_HW_CONFIG_COMMPAGE
136
137 #else // TARGET_OS_WIN32
138
139 static inline long
140 _dispatch_count_bits(unsigned long value)
141 {
142 long bits = 0;
143 while (value) {
144 bits += (value & 1);
145 value = value >> 1;
146 }
147 return bits;
148 }
149
150 static inline uint32_t
151 _dispatch_get_ncpus(void)
152 {
153 uint32_t val;
154 DWORD_PTR procmask, sysmask;
155 if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, &sysmask)) {
156 val = _dispatch_count_bits(procmask);
157 } else {
158 val = 1;
159 }
160 return val;
161 }
162 #endif // TARGET_OS_WIN32
163
164 #endif /* __DISPATCH_SHIMS_HW_CONFIG__ */