OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

misc.h
1 /*
2 * Copyright © 2009 CNRS
3 * Copyright © 2009-2010 inria. All rights reserved.
4 * Copyright © 2009-2011 Université Bordeaux 1
5 * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
6 * See COPYING in top-level directory.
7 */
8
9 /* Misc internals routines. */
10
11 #ifndef HWLOC_PRIVATE_MISC_H
12 #define HWLOC_PRIVATE_MISC_H
13
14 #include <hwloc/autogen/config.h>
15 #include <private/autogen/config.h>
16 #include <private/private.h>
17
18
19 /* On some systems, snprintf returns the size of written data, not the actually
20 * required size. hwloc_snprintf always report the actually required size. */
21 int hwloc_snprintf(char *str, size_t size, const char *format, ...) __hwloc_attribute_format(printf, 3, 4);
22
23 /* Check whether needle matches the beginning of haystack, at least n, and up
24 * to a colon or \0 */
25 HWLOC_DECLSPEC
26 int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n);
27
28 /* Compile-time assertion */
29 #define HWLOC_BUILD_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)]))
30
31
32
33 #define HWLOC_BITS_PER_LONG (HWLOC_SIZEOF_UNSIGNED_LONG * 8)
34 #define HWLOC_BITS_PER_INT (HWLOC_SIZEOF_UNSIGNED_INT * 8)
35
36 #if (HWLOC_BITS_PER_LONG != 32) && (HWLOC_BITS_PER_LONG != 64)
37 #error "unknown size for unsigned long."
38 #endif
39
40 #if (HWLOC_BITS_PER_INT != 16) && (HWLOC_BITS_PER_INT != 32) && (HWLOC_BITS_PER_INT != 64)
41 #error "unknown size for unsigned int."
42 #endif
43
44
45 /**
46 * ffsl helpers.
47 */
48
49 #if defined(HWLOC_HAVE_BROKEN_FFS)
50
51 /* System has a broken ffs().
52 * We must check the before __GNUC__ or HWLOC_HAVE_FFSL
53 */
54 # define HWLOC_NO_FFS
55
56 #elif defined(__GNUC__)
57
58 # if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
59 /* Starting from 3.4, gcc has a long variant. */
60 # define hwloc_ffsl(x) __builtin_ffsl(x)
61 # else
62 # define hwloc_ffs(x) __builtin_ffs(x)
63 # define HWLOC_NEED_FFSL
64 # endif
65
66 #elif defined(HWLOC_HAVE_FFSL)
67
68 # ifndef HWLOC_HAVE_DECL_FFSL
69 extern int ffsl(long) __hwloc_attribute_const;
70 # endif
71
72 # define hwloc_ffsl(x) ffsl(x)
73
74 #elif defined(HWLOC_HAVE_FFS)
75
76 # ifndef HWLOC_HAVE_DECL_FFS
77 extern int ffs(int) __hwloc_attribute_const;
78 # endif
79
80 # define hwloc_ffs(x) ffs(x)
81 # define HWLOC_NEED_FFSL
82
83 #else /* no ffs implementation */
84
85 # define HWLOC_NO_FFS
86
87 #endif
88
89 #ifdef HWLOC_NO_FFS
90
91 /* no ffs or it is known to be broken */
92 static __hwloc_inline int __hwloc_attribute_const
93 hwloc_ffsl(unsigned long x)
94 {
95 int i;
96
97 if (!x)
98 return 0;
99
100 i = 1;
101 #if HWLOC_BITS_PER_LONG >= 64
102 if (!(x & 0xfffffffful)) {
103 x >>= 32;
104 i += 32;
105 }
106 #endif
107 if (!(x & 0xffffu)) {
108 x >>= 16;
109 i += 16;
110 }
111 if (!(x & 0xff)) {
112 x >>= 8;
113 i += 8;
114 }
115 if (!(x & 0xf)) {
116 x >>= 4;
117 i += 4;
118 }
119 if (!(x & 0x3)) {
120 x >>= 2;
121 i += 2;
122 }
123 if (!(x & 0x1)) {
124 x >>= 1;
125 i += 1;
126 }
127
128 return i;
129 }
130
131 #elif defined(HWLOC_NEED_FFSL)
132
133 /* We only have an int ffs(int) implementation, build a long one. */
134
135 /* First make it 32 bits if it was only 16. */
136 static __hwloc_inline int __hwloc_attribute_const
137 hwloc_ffs32(unsigned long x)
138 {
139 #if HWLOC_BITS_PER_INT == 16
140 int low_ffs, hi_ffs;
141
142 low_ffs = hwloc_ffs(x & 0xfffful);
143 if (low_ffs)
144 return low_ffs;
145
146 hi_ffs = hwloc_ffs(x >> 16);
147 if (hi_ffs)
148 return hi_ffs + 16;
149
150 return 0;
151 #else
152 return hwloc_ffs(x);
153 #endif
154 }
155
156 /* Then make it 64 bit if longs are. */
157 static __hwloc_inline int __hwloc_attribute_const
158 hwloc_ffsl(unsigned long x)
159 {
160 #if HWLOC_BITS_PER_LONG == 64
161 int low_ffs, hi_ffs;
162
163 low_ffs = hwloc_ffs32(x & 0xfffffffful);
164 if (low_ffs)
165 return low_ffs;
166
167 hi_ffs = hwloc_ffs32(x >> 32);
168 if (hi_ffs)
169 return hi_ffs + 32;
170
171 return 0;
172 #else
173 return hwloc_ffs32(x);
174 #endif
175 }
176 #endif
177
178 /**
179 * flsl helpers.
180 */
181 #ifdef __GNUC_____
182
183 # if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
184 # define hwloc_flsl(x) (x ? 8*sizeof(long) - __builtin_clzl(x) : 0)
185 # else
186 # define hwloc_fls(x) (x ? 8*sizeof(int) - __builtin_clz(x) : 0)
187 # define HWLOC_NEED_FLSL
188 # endif
189
190 #elif defined(HWLOC_HAVE_FLSL)
191
192 # ifndef HWLOC_HAVE_DECL_FLSL
193 extern int flsl(long) __hwloc_attribute_const;
194 # endif
195
196 # define hwloc_flsl(x) flsl(x)
197
198 #elif defined(HWLOC_HAVE_CLZL)
199
200 # ifndef HWLOC_HAVE_DECL_CLZL
201 extern int clzl(long) __hwloc_attribute_const;
202 # endif
203
204 # define hwloc_flsl(x) (x ? 8*sizeof(long) - clzl(x) : 0)
205
206 #elif defined(HWLOC_HAVE_FLS)
207
208 # ifndef HWLOC_HAVE_DECL_FLS
209 extern int fls(int) __hwloc_attribute_const;
210 # endif
211
212 # define hwloc_fls(x) fls(x)
213 # define HWLOC_NEED_FLSL
214
215 #elif defined(HWLOC_HAVE_CLZ)
216
217 # ifndef HWLOC_HAVE_DECL_CLZ
218 extern int clz(int) __hwloc_attribute_const;
219 # endif
220
221 # define hwloc_fls(x) (x ? 8*sizeof(int) - clz(x) : 0)
222 # define HWLOC_NEED_FLSL
223
224 #else /* no fls implementation */
225
226 static __hwloc_inline int __hwloc_attribute_const
227 hwloc_flsl(unsigned long x)
228 {
229 int i = 0;
230
231 if (!x)
232 return 0;
233
234 i = 1;
235 #if HWLOC_BITS_PER_LONG >= 64
236 if ((x & 0xffffffff00000000ul)) {
237 x >>= 32;
238 i += 32;
239 }
240 #endif
241 if ((x & 0xffff0000u)) {
242 x >>= 16;
243 i += 16;
244 }
245 if ((x & 0xff00)) {
246 x >>= 8;
247 i += 8;
248 }
249 if ((x & 0xf0)) {
250 x >>= 4;
251 i += 4;
252 }
253 if ((x & 0xc)) {
254 x >>= 2;
255 i += 2;
256 }
257 if ((x & 0x2)) {
258 x >>= 1;
259 i += 1;
260 }
261
262 return i;
263 }
264
265 #endif
266
267 #ifdef HWLOC_NEED_FLSL
268
269 /* We only have an int fls(int) implementation, build a long one. */
270
271 /* First make it 32 bits if it was only 16. */
272 static __hwloc_inline int __hwloc_attribute_const
273 hwloc_fls32(unsigned long x)
274 {
275 #if HWLOC_BITS_PER_INT == 16
276 int low_fls, hi_fls;
277
278 hi_fls = hwloc_fls(x >> 16);
279 if (hi_fls)
280 return hi_fls + 16;
281
282 low_fls = hwloc_fls(x & 0xfffful);
283 if (low_fls)
284 return low_fls;
285
286 return 0;
287 #else
288 return hwloc_fls(x);
289 #endif
290 }
291
292 /* Then make it 64 bit if longs are. */
293 static __hwloc_inline int __hwloc_attribute_const
294 hwloc_flsl(unsigned long x)
295 {
296 #if HWLOC_BITS_PER_LONG == 64
297 int low_fls, hi_fls;
298
299 hi_fls = hwloc_fls32(x >> 32);
300 if (hi_fls)
301 return hi_fls + 32;
302
303 low_fls = hwloc_fls32(x & 0xfffffffful);
304 if (low_fls)
305 return low_fls;
306
307 return 0;
308 #else
309 return hwloc_fls32(x);
310 #endif
311 }
312 #endif
313
314 static __hwloc_inline int __hwloc_attribute_const
315 hwloc_weight_long(unsigned long w)
316 {
317 #if HWLOC_BITS_PER_LONG == 32
318 #if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
319 return __builtin_popcount(w);
320 #else
321 unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
322 res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
323 res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
324 res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
325 return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
326 #endif
327 #else /* HWLOC_BITS_PER_LONG == 32 */
328 #if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
329 return __builtin_popcountll(w);
330 #else
331 unsigned long res;
332 res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
333 res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
334 res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
335 res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
336 res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
337 return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
338 #endif
339 #endif /* HWLOC_BITS_PER_LONG == 64 */
340 }
341
342
343 #endif /* HWLOC_PRIVATE_MISC_H */