/root/doris/be/src/gutil/port.h
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // Copyright (C) 1999 and onwards Google, Inc. |
3 | | // |
4 | | // |
5 | | // These are weird things we need to do to get this compiling on |
6 | | // random systems (and on SWIG). |
7 | | |
8 | | #pragma once |
9 | | |
10 | | #include <limits.h> // So we can set the bounds of our types |
11 | | #include <stdlib.h> // for free() |
12 | | #include <string.h> // for memcpy() |
13 | | |
14 | | #if defined(__APPLE__) |
15 | | // for getpagesize() on mac |
16 | | #ifndef _POSIX_C_SOURCE |
17 | | #include <unistd.h> |
18 | | #else |
19 | | #include <mach/vm_page_size.h> |
20 | | #endif |
21 | | |
22 | | #elif defined(OS_CYGWIN) |
23 | | #include <malloc.h> // for memalign() |
24 | | #endif |
25 | | |
26 | | #include "gutil/integral_types.h" |
27 | | |
28 | | // Must happens before inttypes.h inclusion */ |
29 | | #if defined(__APPLE__) |
30 | | /* From MacOSX's inttypes.h: |
31 | | * "C++ implementations should define these macros only when |
32 | | * __STDC_FORMAT_MACROS is defined before <inttypes.h> is included." */ |
33 | | #ifndef __STDC_FORMAT_MACROS |
34 | | #define __STDC_FORMAT_MACROS |
35 | | #endif /* __STDC_FORMAT_MACROS */ |
36 | | #endif /* __APPLE__ */ |
37 | | |
38 | | /* Default for most OSes */ |
39 | | /* We use SIGPWR since that seems unlikely to be used for other reasons. */ |
40 | | #define GOOGLE_OBSCURE_SIGNAL SIGPWR |
41 | | |
42 | | #if defined OS_LINUX || defined OS_CYGWIN |
43 | | |
44 | | // _BIG_ENDIAN |
45 | | #include <endian.h> |
46 | | |
47 | | // The uint mess: |
48 | | // mysql.h sets _GNU_SOURCE which sets __USE_MISC in <features.h> |
49 | | // sys/types.h typedefs uint if __USE_MISC |
50 | | // mysql typedefs uint if HAVE_UINT not set |
51 | | // The following typedef is carefully considered, and should not cause |
52 | | // any clashes |
53 | | #if !defined(__USE_MISC) |
54 | | #if !defined(HAVE_UINT) |
55 | | #define HAVE_UINT 1 |
56 | | typedef unsigned int uint; |
57 | | #endif |
58 | | #if !defined(HAVE_USHORT) |
59 | | #define HAVE_USHORT 1 |
60 | | typedef unsigned short ushort; |
61 | | #endif |
62 | | #if !defined(HAVE_ULONG) |
63 | | #define HAVE_ULONG 1 |
64 | | typedef unsigned long ulong; |
65 | | #endif |
66 | | #endif |
67 | | |
68 | | #if defined(__cplusplus) |
69 | | #include <cstddef> // For _GLIBCXX macros |
70 | | #endif |
71 | | |
72 | | #if !defined(HAVE_TLS) && defined(_GLIBCXX_HAVE_TLS) && defined(__x86_64__) |
73 | | #define HAVE_TLS 1 |
74 | | #endif |
75 | | |
76 | | #elif defined OS_FREEBSD |
77 | | |
78 | | // _BIG_ENDIAN |
79 | | #include <machine/endian.h> |
80 | | |
81 | | #elif defined OS_SOLARIS |
82 | | |
83 | | // _BIG_ENDIAN |
84 | | #include <sys/isa_defs.h> |
85 | | |
86 | | // Solaris doesn't define sig_t (function taking an int, returning void) |
87 | | typedef void (*sig_t)(int); |
88 | | |
89 | | // Solaris only defines strtoll, not strtoq |
90 | | #define strtoq strtoll |
91 | | #define strtouq strtoull |
92 | | |
93 | | // It doesn't define the posix-standard(?) u_int_16 |
94 | | #include <sys/int_types.h> // NOLINT(build/include) |
95 | | typedef uint16_t u_int16_t; |
96 | | |
97 | | #elif defined __APPLE__ |
98 | | |
99 | | // BIG_ENDIAN |
100 | | #include <machine/endian.h> // NOLINT(build/include) |
101 | | /* Let's try and follow the Linux convention */ |
102 | | #define __BYTE_ORDER BYTE_ORDER |
103 | | #define __LITTLE_ENDIAN LITTLE_ENDIAN |
104 | | #define __BIG_ENDIAN BIG_ENDIAN |
105 | | |
106 | | #endif |
107 | | |
108 | | // The following guarenty declaration of the byte swap functions, and |
109 | | // define __BYTE_ORDER for MSVC |
110 | | #ifdef _MSC_VER |
111 | | #include <stdlib.h> // NOLINT(build/include) |
112 | | #define __BYTE_ORDER __LITTLE_ENDIAN |
113 | | #define bswap_16(x) _byteswap_ushort(x) |
114 | | #define bswap_32(x) _byteswap_ulong(x) |
115 | | #define bswap_64(x) _byteswap_uint64(x) |
116 | | |
117 | | #elif defined(__APPLE__) |
118 | | // Mac OS X / Darwin features |
119 | | #include <libkern/OSByteOrder.h> |
120 | | #define bswap_16(x) OSSwapInt16(x) |
121 | | #define bswap_32(x) OSSwapInt32(x) |
122 | | #define bswap_64(x) OSSwapInt64(x) |
123 | | |
124 | | #elif defined(__GLIBC__) |
125 | | #include <byteswap.h> // IWYU pragma: export |
126 | | |
127 | | #else |
128 | | |
129 | | static inline uint16 bswap_16(uint16 x) { |
130 | | return ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8); |
131 | | } |
132 | | #define bswap_16(x) bswap_16(x) |
133 | | static inline uint32 bswap_32(uint32 x) { |
134 | | return (((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | |
135 | | ((x & 0xFF000000) >> 24)); |
136 | | } |
137 | | #define bswap_32(x) bswap_32(x) |
138 | | static inline uint64 bswap_64(uint64 x) { |
139 | | return (((x & GG_ULONGLONG(0xFF)) << 56) | ((x & GG_ULONGLONG(0xFF00)) << 40) | |
140 | | ((x & GG_ULONGLONG(0xFF0000)) << 24) | ((x & GG_ULONGLONG(0xFF000000)) << 8) | |
141 | | ((x & GG_ULONGLONG(0xFF00000000)) >> 8) | ((x & GG_ULONGLONG(0xFF0000000000)) >> 24) | |
142 | | ((x & GG_ULONGLONG(0xFF000000000000)) >> 40) | |
143 | | ((x & GG_ULONGLONG(0xFF00000000000000)) >> 56)); |
144 | | } |
145 | | #define bswap_64(x) bswap_64(x) |
146 | | |
147 | | #endif |
148 | | |
149 | | // define the macros IS_LITTLE_ENDIAN or IS_BIG_ENDIAN |
150 | | // using the above endian definitions from endian.h if |
151 | | // endian.h was included |
152 | | #ifdef __BYTE_ORDER |
153 | | #if __BYTE_ORDER == __LITTLE_ENDIAN |
154 | | #define IS_LITTLE_ENDIAN |
155 | | #endif |
156 | | |
157 | | #if __BYTE_ORDER == __BIG_ENDIAN |
158 | | #define IS_BIG_ENDIAN |
159 | | #endif |
160 | | |
161 | | #else |
162 | | |
163 | | #if defined(__LITTLE_ENDIAN__) |
164 | | #define IS_LITTLE_ENDIAN |
165 | | #elif defined(__BIG_ENDIAN__) |
166 | | #define IS_BIG_ENDIAN |
167 | | #endif |
168 | | |
169 | | // there is also PDP endian ... |
170 | | |
171 | | #endif // __BYTE_ORDER |
172 | | |
173 | | // Define the OS's path separator |
174 | | #ifdef __cplusplus // C won't merge duplicate const variables at link time |
175 | | // Some headers provide a macro for this (GCC's system.h), remove it so that we |
176 | | // can use our own. |
177 | | #undef PATH_SEPARATOR |
178 | | #if defined(OS_WINDOWS) |
179 | | const char PATH_SEPARATOR = '\\'; |
180 | | #else |
181 | | const char PATH_SEPARATOR = '/'; |
182 | | #endif |
183 | | #endif |
184 | | |
185 | | // Windows has O_BINARY as a flag to open() (like "b" for fopen). |
186 | | // Linux doesn't need make this distinction. |
187 | | #if defined OS_LINUX && !defined O_BINARY |
188 | | #define O_BINARY 0 |
189 | | #endif |
190 | | |
191 | | // va_copy portability definitions |
192 | | #ifdef _MSC_VER |
193 | | // MSVC doesn't have va_copy yet. |
194 | | // This is believed to work for 32-bit msvc. This may not work at all for |
195 | | // other platforms. |
196 | | // If va_list uses the single-element-array trick, you will probably get |
197 | | // a compiler error here. |
198 | | // |
199 | | #include <stdarg.h> |
200 | | void va_copy(va_list& a, va_list& b) { |
201 | | a = b; |
202 | | } |
203 | | |
204 | | // Nor does it have uid_t |
205 | | typedef int uid_t; |
206 | | |
207 | | #endif |
208 | | |
209 | | // Mac OS X / Darwin features |
210 | | |
211 | | #if defined(__APPLE__) |
212 | | |
213 | | // For mmap, Linux defines both MAP_ANONYMOUS and MAP_ANON and says MAP_ANON is |
214 | | // deprecated. In Darwin, MAP_ANON is all there is. |
215 | | #if !defined MAP_ANONYMOUS |
216 | | #define MAP_ANONYMOUS MAP_ANON |
217 | | #endif |
218 | | |
219 | | // Linux has this in <sys/cdefs.h> |
220 | | #define __ptr_t void* |
221 | | |
222 | | // Linux has this in <linux/errno.h> |
223 | | #define EXFULL ENOMEM // not really that great a translation... |
224 | | |
225 | | // Darwin doesn't have strnlen. No comment. |
226 | | inline size_t strnlen(const char* s, size_t maxlen) { |
227 | | const char* end = (const char*)memchr(s, '\0', maxlen); |
228 | | if (end) return end - s; |
229 | | return maxlen; |
230 | | } |
231 | | |
232 | | namespace std {} // namespace std |
233 | | using namespace std; // Just like VC++, we need a using here. |
234 | | |
235 | | // Doesn't exist on OSX; used in google.cc for send() to mean "no flags". |
236 | | #ifndef MSG_NOSIGNAL |
237 | | #define MSG_NOSIGNAL 0 |
238 | | #endif |
239 | | |
240 | | // No SIGPWR on MacOSX. SIGINFO seems suitably obscure. |
241 | | #undef GOOGLE_OBSCURE_SIGNAL |
242 | | #define GOOGLE_OBSCURE_SIGNAL SIGINFO |
243 | | |
244 | | #elif defined(OS_CYGWIN) // Cygwin-specific behavior. |
245 | | |
246 | | #if defined(__CYGWIN32__) |
247 | | #define __WORDSIZE 32 |
248 | | #else |
249 | | // It's probably possible to support 64-bit, but the #defines will need checked. |
250 | | #error "Cygwin is currently only 32-bit." |
251 | | #endif |
252 | | |
253 | | // No signalling on Windows. |
254 | | #undef GOOGLE_OBSCURE_SIGNAL |
255 | | #define GOOGLE_OBSCURE_SIGNAL 0 |
256 | | |
257 | | struct stack_t { |
258 | | void* ss_sp = nullptr; |
259 | | int ss_flags; |
260 | | size_t ss_size; |
261 | | }; |
262 | | inline int sigaltstack(stack_t* ss, stack_t* oss) { |
263 | | return 0; |
264 | | } |
265 | | |
266 | | #define PTHREAD_STACK_MIN 0 // Not provided by cygwin |
267 | | |
268 | | // Scans memory for a character. |
269 | | // memrchr is used in a few places, but it's linux-specific. |
270 | | inline void* memrchr(const void* bytes, int find_char, size_t len) { |
271 | | const unsigned char* cursor = reinterpret_cast<const unsigned char*>(bytes) + len - 1; |
272 | | unsigned char actual_char = find_char; |
273 | | for (; cursor >= bytes; --cursor) { |
274 | | if (*cursor == actual_char) { |
275 | | return const_cast<void*>(reinterpret_cast<const void*>(cursor)); |
276 | | } |
277 | | } |
278 | | return NULL; |
279 | | } |
280 | | |
281 | | #endif |
282 | | |
283 | | // Klocwork static analysis tool's C/C++ compiler kwcc |
284 | | #if defined(__KLOCWORK__) |
285 | | #define STATIC_ANALYSIS |
286 | | #endif // __KLOCWORK__ |
287 | | |
288 | | // GCC-specific features |
289 | | |
290 | | #if (defined(__GNUC__) || defined(__APPLE__)) && !defined(SWIG) |
291 | | |
292 | | // |
293 | | // Tell the compiler to do printf format string checking if the |
294 | | // compiler supports it; see the 'format' attribute in |
295 | | // <http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html>. |
296 | | // |
297 | | // N.B.: As the GCC manual states, "[s]ince non-static C++ methods |
298 | | // have an implicit 'this' argument, the arguments of such methods |
299 | | // should be counted from two, not one." |
300 | | // |
301 | | #define PRINTF_ATTRIBUTE(string_index, first_to_check) \ |
302 | | __attribute__((__format__(__printf__, string_index, first_to_check))) |
303 | | #define SCANF_ATTRIBUTE(string_index, first_to_check) \ |
304 | | __attribute__((__format__(__scanf__, string_index, first_to_check))) |
305 | | |
306 | | // |
307 | | // Prevent the compiler from padding a structure to natural alignment |
308 | | // |
309 | | #define PACKED __attribute__((packed)) |
310 | | |
311 | | // Cache line alignment |
312 | | #if defined(__i386__) || defined(__x86_64__) |
313 | | #define CACHELINE_SIZE 64 |
314 | | #elif defined(__powerpc64__) |
315 | | // TODO(user) This is the L1 D-cache line size of our Power7 machines. |
316 | | // Need to check if this is appropriate for other PowerPC64 systems. |
317 | | #define CACHELINE_SIZE 128 |
318 | | #elif defined(__arm__) |
319 | | // Cache line sizes for ARM: These values are not strictly correct since |
320 | | // cache line sizes depend on implementations, not architectures. There |
321 | | // are even implementations with cache line sizes configurable at boot |
322 | | // time. |
323 | | #if defined(__ARM_ARCH_5T__) |
324 | | #define CACHELINE_SIZE 32 |
325 | | #elif defined(__ARM_ARCH_7A__) |
326 | | #define CACHELINE_SIZE 64 |
327 | | #endif |
328 | | #endif |
329 | | |
330 | | // This is a NOP if CACHELINE_SIZE is not defined. |
331 | | #ifdef CACHELINE_SIZE |
332 | | #define CACHELINE_ALIGNED __attribute__((aligned(CACHELINE_SIZE))) |
333 | | #else |
334 | | #define CACHELINE_ALIGNED |
335 | | #endif |
336 | | |
337 | | // |
338 | | // Prevent the compiler from complaining about or optimizing away variables |
339 | | // that appear unused |
340 | | // (careful, others e.g. third_party/libxml/xmlversion.h also define this) |
341 | | #undef ATTRIBUTE_UNUSED |
342 | | #define ATTRIBUTE_UNUSED __attribute__((unused)) |
343 | | |
344 | | // Same as above, but for class members. |
345 | | // As of 10/2013 this appears to only be supported in Clang/LLVM. |
346 | | // See http://patchwork.ozlabs.org/patch/232594/ which is not yet committed |
347 | | // in gcc trunk. |
348 | | #if defined(__llvm__) |
349 | | #define ATTRIBUTE_MEMBER_UNUSED ATTRIBUTE_UNUSED |
350 | | #else |
351 | | #define ATTRIBUTE_MEMBER_UNUSED |
352 | | #endif |
353 | | |
354 | | // |
355 | | // For functions we want to force inline or not inline. |
356 | | // Introduced in gcc 3.1. |
357 | | #define ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) |
358 | | #define HAVE_ATTRIBUTE_ALWAYS_INLINE 1 |
359 | | #define ATTRIBUTE_NOINLINE __attribute__((noinline)) |
360 | | #define HAVE_ATTRIBUTE_NOINLINE 1 |
361 | | |
362 | | // For weak functions |
363 | | #undef ATTRIBUTE_WEAK |
364 | | #define ATTRIBUTE_WEAK __attribute__((weak)) |
365 | | #define HAVE_ATTRIBUTE_WEAK 1 |
366 | | |
367 | | // For deprecated functions or variables, generate a warning at usage sites. |
368 | | // Verified to work as early as GCC 3.1.1 and clang 3.2 (so we'll assume any |
369 | | // clang is new enough). |
370 | | #if defined(__clang__) || \ |
371 | | (defined(COMPILER_GCC) && (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 30200) |
372 | | #define ATTRIBUTE_DEPRECATED(msg) __attribute__((deprecated(msg))) |
373 | | #else |
374 | | #define ATTRIBUTE_DEPRECATED(msg) |
375 | | #endif |
376 | | |
377 | | // Tell the compiler to use "initial-exec" mode for a thread-local variable. |
378 | | // See http://people.redhat.com/drepper/tls.pdf for the gory details. |
379 | | #define ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) |
380 | | |
381 | | // |
382 | | // Tell the compiler that some function parameters should be non-null pointers. |
383 | | // Note: As the GCC manual states, "[s]ince non-static C++ methods |
384 | | // have an implicit 'this' argument, the arguments of such methods |
385 | | // should be counted from two, not one." |
386 | | // |
387 | | #define ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index))) |
388 | | |
389 | | // |
390 | | // Tell the compiler that a given function never returns |
391 | | // |
392 | | #define ATTRIBUTE_NORETURN __attribute__((noreturn)) |
393 | | |
394 | | // Tell AddressSanitizer (or other memory testing tools) to ignore a given |
395 | | // function. Useful for cases when a function reads random locations on stack, |
396 | | // calls _exit from a cloned subprocess, deliberately accesses buffer |
397 | | // out of bounds or does other scary things with memory. |
398 | | #ifdef ADDRESS_SANITIZER |
399 | | #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS __attribute__((no_address_safety_analysis)) |
400 | | #else |
401 | | #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS |
402 | | #endif |
403 | | |
404 | | // Tell ThreadSanitizer to ignore a given function. This can dramatically reduce |
405 | | // the running time and memory requirements for racy code when TSAN is active. |
406 | | // GCC does not support this attribute at the time of this writing (GCC 4.8). |
407 | | #if defined(__llvm__) |
408 | | #define ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) |
409 | | #else |
410 | | #define ATTRIBUTE_NO_SANITIZE_THREAD |
411 | | #endif |
412 | | |
413 | | #ifndef HAVE_ATTRIBUTE_SECTION // may have been pre-set to 0, e.g. for Darwin |
414 | | #define HAVE_ATTRIBUTE_SECTION 1 |
415 | | #endif |
416 | | |
417 | | // |
418 | | // The legacy prod71 libc does not provide the stack alignment required for use |
419 | | // of SSE intrinsics. In order to properly use the intrinsics you need to use |
420 | | // a trampoline function which aligns the stack prior to calling your code, |
421 | | // or as of crosstool v10 with gcc 4.2.0 there is an attribute which asks |
422 | | // gcc to do this for you. |
423 | | // |
424 | | // It has also been discovered that crosstool up to and including v10 does not |
425 | | // provide proper alignment for pthread_once() functions in x86-64 code either. |
426 | | // Unfortunately gcc does not provide force_align_arg_pointer as an option in |
427 | | // x86-64 code, so this requires us to always have a trampoline. |
428 | | // |
429 | | // For an example of using this see util/hash/adler32* |
430 | | |
431 | | #if defined(__i386__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) |
432 | | #define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC __attribute__((force_align_arg_pointer)) |
433 | | #define REQUIRE_STACK_ALIGN_TRAMPOLINE (0) |
434 | | #elif defined(__i386__) || defined(__x86_64__) |
435 | | #define REQUIRE_STACK_ALIGN_TRAMPOLINE (1) |
436 | | #define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC |
437 | | #else |
438 | | #define REQUIRE_STACK_ALIGN_TRAMPOLINE (0) |
439 | | #define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC |
440 | | #endif |
441 | | |
442 | | // |
443 | | // Tell the compiler to warn about unused return values for functions declared |
444 | | // with this macro. The macro should be used on function declarations |
445 | | // following the argument list: |
446 | | // |
447 | | // Sprocket* AllocateSprocket() MUST_USE_RESULT; |
448 | | // |
449 | | #if defined(SWIG) |
450 | | #define MUST_USE_RESULT |
451 | | #elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) |
452 | | #define MUST_USE_RESULT __attribute__((warn_unused_result)) |
453 | | #else |
454 | | #define MUST_USE_RESULT |
455 | | #endif |
456 | | |
457 | | #if defined(__GNUC__) |
458 | | // Defined behavior on some of the uarchs: |
459 | | // PREFETCH_HINT_T0: |
460 | | // prefetch to all levels of the hierarchy (except on p4: prefetch to L2) |
461 | | // PREFETCH_HINT_NTA: |
462 | | // p4: fetch to L2, but limit to 1 way (out of the 8 ways) |
463 | | // core: skip L2, go directly to L1 |
464 | | // k8 rev E and later: skip L2, can go to either of the 2-ways in L1 |
465 | | enum PrefetchHint { |
466 | | PREFETCH_HINT_T0 = 3, // More temporal locality |
467 | | PREFETCH_HINT_T1 = 2, |
468 | | PREFETCH_HINT_T2 = 1, // Less temporal locality |
469 | | PREFETCH_HINT_NTA = 0 // No temporal locality |
470 | | }; |
471 | | #else |
472 | | // prefetch is a no-op for this target. Feel free to add more sections above. |
473 | | #endif |
474 | | |
475 | 0 | extern inline void prefetch(const char* x, int hint) { |
476 | 0 | #if defined(__llvm__) |
477 | 0 | // In the gcc version of prefetch(), hint is only a constant _after_ inlining |
478 | 0 | // (assumed to have been successful). llvm views things differently, and |
479 | 0 | // checks constant-ness _before_ inlining. This leads to compilation errors |
480 | 0 | // with using the other version of this code with llvm. |
481 | 0 | // |
482 | 0 | // One way round this is to use a switch statement to explicitly match |
483 | 0 | // prefetch hint enumerations, and invoke __builtin_prefetch for each valid |
484 | 0 | // value. llvm's optimization removes the switch and unused case statements |
485 | 0 | // after inlining, so that this boils down in the end to the same as for gcc; |
486 | 0 | // that is, a single inlined prefetchX instruction. |
487 | 0 | // |
488 | 0 | // Note that this version of prefetch() cannot verify constant-ness of hint. |
489 | 0 | // If client code calls prefetch() with a variable value for hint, it will |
490 | 0 | // receive the full expansion of the switch below, perhaps also not inlined. |
491 | 0 | // This should however not be a problem in the general case of well behaved |
492 | 0 | // caller code that uses the supplied prefetch hint enumerations. |
493 | 0 | switch (hint) { |
494 | 0 | case PREFETCH_HINT_T0: |
495 | 0 | __builtin_prefetch(x, 0, PREFETCH_HINT_T0); |
496 | 0 | break; |
497 | 0 | case PREFETCH_HINT_T1: |
498 | 0 | __builtin_prefetch(x, 0, PREFETCH_HINT_T1); |
499 | 0 | break; |
500 | 0 | case PREFETCH_HINT_T2: |
501 | 0 | __builtin_prefetch(x, 0, PREFETCH_HINT_T2); |
502 | 0 | break; |
503 | 0 | case PREFETCH_HINT_NTA: |
504 | 0 | __builtin_prefetch(x, 0, PREFETCH_HINT_NTA); |
505 | 0 | break; |
506 | 0 | default: |
507 | 0 | __builtin_prefetch(x); |
508 | 0 | break; |
509 | 0 | } |
510 | 0 | #elif defined(__GNUC__) |
511 | 0 | #if !defined(__i386) || defined(__SSE__) |
512 | 0 | if (__builtin_constant_p(hint)) { |
513 | 0 | __builtin_prefetch(x, 0, hint); |
514 | 0 | } else { |
515 | 0 | // Defaults to PREFETCH_HINT_T0 |
516 | 0 | __builtin_prefetch(x); |
517 | 0 | } |
518 | 0 | #else |
519 | 0 | // We want a __builtin_prefetch, but we build with the default -march=i386 |
520 | 0 | // where __builtin_prefetch quietly turns into nothing. |
521 | 0 | // Once we crank up to -march=pentium3 or higher the __SSE__ |
522 | 0 | // clause above will kick in with the builtin. |
523 | 0 | // -- mec 2006-06-06 |
524 | 0 | if (hint == PREFETCH_HINT_NTA) __asm__ __volatile__("prefetchnta (%0)" : : "r"(x)); |
525 | 0 | #endif |
526 | 0 | #else |
527 | 0 | // You get no effect. Feel free to add more sections above. |
528 | 0 | #endif |
529 | 0 | } |
530 | | |
531 | | #ifdef __cplusplus |
532 | | // prefetch intrinsic (bring data to L1 without polluting L2 cache) |
533 | 0 | extern inline void prefetch(const char* x) { |
534 | 0 | return prefetch(x, 0); |
535 | 0 | } |
536 | | #endif // ifdef __cplusplus |
537 | | |
538 | | // |
539 | | // GCC can be told that a certain branch is not likely to be taken (for |
540 | | // instance, a CHECK failure), and use that information in static analysis. |
541 | | // Giving it this information can help it optimize for the common case in |
542 | | // the absence of better information (ie. -fprofile-arcs). |
543 | | // |
544 | | #if defined(__GNUC__) |
545 | 4.13M | #define PREDICT_FALSE(x) (__builtin_expect(x, 0)) |
546 | 4.41M | #define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) |
547 | | #else |
548 | | #define PREDICT_FALSE(x) x |
549 | | #define PREDICT_TRUE(x) x |
550 | | #endif |
551 | | |
552 | | // |
553 | | // Tell GCC that a function is hot or cold. GCC can use this information to |
554 | | // improve static analysis, i.e. a conditional branch to a cold function |
555 | | // is likely to be not-taken. |
556 | | // This annotation is used for function declarations, e.g.: |
557 | | // int foo() ATTRIBUTE_HOT; |
558 | | // |
559 | | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) |
560 | | #define ATTRIBUTE_HOT __attribute__((hot)) |
561 | | #define ATTRIBUTE_COLD __attribute__((cold)) |
562 | | #else |
563 | | #define ATTRIBUTE_HOT |
564 | | #define ATTRIBUTE_COLD |
565 | | #endif |
566 | | |
567 | | #define FTELLO ftello |
568 | | #define FSEEKO fseeko |
569 | | |
570 | | #if !defined(__cplusplus) && !defined(__APPLE__) && !defined(OS_CYGWIN) |
571 | | // stdlib.h only declares this in C++, not in C, so we declare it here. |
572 | | // Also make sure to avoid declaring it on platforms which don't support it. |
573 | | extern int posix_memalign(void** memptr, size_t alignment, size_t size); |
574 | | #endif |
575 | | |
576 | 0 | inline void* aligned_malloc(size_t size, int minimum_alignment) { |
577 | 0 | #if defined(__APPLE__) |
578 | 0 | // mac lacks memalign(), posix_memalign(), however, according to |
579 | 0 | // http://stackoverflow.com/questions/196329/osx-lacks-memalign |
580 | 0 | // mac allocs are already 16-byte aligned. |
581 | 0 | if (minimum_alignment <= 16) return malloc(size); |
582 | 0 | // next, try to return page-aligned memory. perhaps overkill |
583 | 0 | #ifndef _POSIX_C_SOURCE |
584 | 0 | int page_size = getpagesize(); |
585 | 0 | #else |
586 | 0 | int page_size = vm_page_size; |
587 | 0 | #endif |
588 | 0 | if (minimum_alignment <= page_size) return valloc(size); |
589 | 0 | // give up |
590 | 0 | return NULL; |
591 | 0 | #elif defined(OS_CYGWIN) |
592 | 0 | return memalign(minimum_alignment, size); |
593 | 0 | #else // !__APPLE__ && !OS_CYGWIN |
594 | 0 | void* ptr = NULL; |
595 | 0 | if (posix_memalign(&ptr, minimum_alignment, size) != 0) |
596 | 0 | return NULL; |
597 | 0 | else |
598 | 0 | return ptr; |
599 | 0 | #endif |
600 | 0 | } |
601 | | |
602 | | #else // not GCC |
603 | | |
604 | | #define PRINTF_ATTRIBUTE(string_index, first_to_check) |
605 | | #define SCANF_ATTRIBUTE(string_index, first_to_check) |
606 | | #define PACKED |
607 | | #define CACHELINE_ALIGNED |
608 | | #define ATTRIBUTE_UNUSED |
609 | | #define ATTRIBUTE_ALWAYS_INLINE |
610 | | #define ATTRIBUTE_NOINLINE |
611 | | #define ATTRIBUTE_HOT |
612 | | #define ATTRIBUTE_COLD |
613 | | #define ATTRIBUTE_WEAK |
614 | | #define HAVE_ATTRIBUTE_WEAK 0 |
615 | | #define ATTRIBUTE_INITIAL_EXEC |
616 | | #define ATTRIBUTE_NONNULL(arg_index) |
617 | | #define ATTRIBUTE_NORETURN |
618 | | #define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC |
619 | | #define REQUIRE_STACK_ALIGN_TRAMPOLINE (0) |
620 | | #define MUST_USE_RESULT |
621 | | extern inline void prefetch(const char* x) {} |
622 | | #define PREDICT_FALSE(x) x |
623 | | #define PREDICT_TRUE(x) x |
624 | | |
625 | | // These should be redefined appropriately if better alternatives to |
626 | | // ftell/fseek exist in the compiler |
627 | | #define FTELLO ftell |
628 | | #define FSEEKO fseek |
629 | | |
630 | | #endif // GCC |
631 | | |
632 | | // |
633 | | // Provides a char array with the exact same alignment as another type. The |
634 | | // first parameter must be a complete type, the second parameter is how many |
635 | | // of that type to provide space for. |
636 | | // |
637 | | // ALIGNED_CHAR_ARRAY(struct stat, 16) storage_; |
638 | | // |
639 | | #if defined(__cplusplus) |
640 | | #undef ALIGNED_CHAR_ARRAY |
641 | | // Because MSVC and older GCCs require that the argument to their alignment |
642 | | // construct to be a literal constant integer, we use a template instantiated |
643 | | // at all the possible powers of two. |
644 | | #ifndef SWIG |
645 | | template <int alignment, int size> |
646 | | struct AlignType {}; |
647 | | template <int size> |
648 | | struct AlignType<0, size> { |
649 | | typedef char result[size]; |
650 | | }; |
651 | | #if defined(_MSC_VER) |
652 | | #define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __declspec(align(X)) |
653 | | #define BASE_PORT_H_ALIGN_OF(T) __alignof(T) |
654 | | #elif defined(__GNUC__) |
655 | | #define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __attribute__((aligned(X))) |
656 | | #define BASE_PORT_H_ALIGN_OF(T) __alignof__(T) |
657 | | #endif |
658 | | |
659 | | #if defined(BASE_PORT_H_ALIGN_ATTRIBUTE) |
660 | | |
661 | | #define BASE_PORT_H_ALIGNTYPE_TEMPLATE(X) \ |
662 | | template <int size> \ |
663 | | struct AlignType<X, size> { \ |
664 | | typedef BASE_PORT_H_ALIGN_ATTRIBUTE(X) char result[size]; \ |
665 | | } |
666 | | |
667 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(1); |
668 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(2); |
669 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(4); |
670 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(8); |
671 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(16); |
672 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(32); |
673 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(64); |
674 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(128); |
675 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(256); |
676 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(512); |
677 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(1024); |
678 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(2048); |
679 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(4096); |
680 | | BASE_PORT_H_ALIGNTYPE_TEMPLATE(8192); |
681 | | // Any larger and MSVC++ will complain. |
682 | | |
683 | | #define ALIGNED_CHAR_ARRAY(T, Size) \ |
684 | | typename AlignType<BASE_PORT_H_ALIGN_OF(T), sizeof(T) * Size>::result |
685 | | |
686 | | #undef BASE_PORT_H_ALIGNTYPE_TEMPLATE |
687 | | #undef BASE_PORT_H_ALIGN_ATTRIBUTE |
688 | | |
689 | | #else // defined(BASE_PORT_H_ALIGN_ATTRIBUTE) |
690 | | #define ALIGNED_CHAR_ARRAY you_must_define_ALIGNED_CHAR_ARRAY_for_your_compiler_in_base_port_h |
691 | | #endif // defined(BASE_PORT_H_ALIGN_ATTRIBUTE) |
692 | | |
693 | | #else // !SWIG |
694 | | |
695 | | // SWIG can't represent alignment and doesn't care about alignment on data |
696 | | // members (it works fine without it). |
697 | | template <typename Size> |
698 | | struct AlignType { |
699 | | typedef char result[Size]; |
700 | | }; |
701 | | #define ALIGNED_CHAR_ARRAY(T, Size) AlignType<Size * sizeof(T)>::result |
702 | | |
703 | | #endif // !SWIG |
704 | | #else // __cpluscplus |
705 | | #define ALIGNED_CHAR_ARRAY ALIGNED_CHAR_ARRAY_is_not_available_without_Cplusplus |
706 | | #endif // __cplusplus |
707 | | |
708 | | #ifdef _MSC_VER /* if Visual C++ */ |
709 | | |
710 | | // This compiler flag can be easily overlooked on MSVC. |
711 | | // _CHAR_UNSIGNED gets set with the /J flag. |
712 | | #ifndef _CHAR_UNSIGNED |
713 | | #error chars must be unsigned! Use the /J flag on the compiler command line. |
714 | | #endif |
715 | | |
716 | | // MSVC is a little hyper-active in its warnings |
717 | | // Signed vs. unsigned comparison is ok. |
718 | | #pragma warning(disable : 4018) |
719 | | // We know casting from a long to a char may lose data |
720 | | #pragma warning(disable : 4244) |
721 | | // Don't need performance warnings about converting ints to bools |
722 | | #pragma warning(disable : 4800) |
723 | | // Integral constant overflow is apparently ok too |
724 | | // for example: |
725 | | // short k; int n; |
726 | | // k = k + n; |
727 | | #pragma warning(disable : 4307) |
728 | | // It's ok to use this* in constructor |
729 | | // Example: |
730 | | // class C { |
731 | | // Container cont_; |
732 | | // C() : cont_(this) { ... |
733 | | #pragma warning(disable : 4355) |
734 | | // Truncating from double to float is ok |
735 | | #pragma warning(disable : 4305) |
736 | | |
737 | | #include <assert.h> |
738 | | #include <windows.h> |
739 | | #include <winsock2.h> |
740 | | #undef ERROR |
741 | | |
742 | | #include <float.h> // for nextafter functionality on windows |
743 | | #include <math.h> // for HUGE_VAL |
744 | | |
745 | | #ifndef HUGE_VALF |
746 | | #define HUGE_VALF (static_cast<float>(HUGE_VAL)) |
747 | | #endif |
748 | | |
749 | | namespace std {} // namespace std |
750 | | using namespace std; |
751 | | |
752 | | // VC++ doesn't understand "uint" |
753 | | #ifndef HAVE_UINT |
754 | | #define HAVE_UINT 1 |
755 | | typedef unsigned int uint; |
756 | | #endif |
757 | | |
758 | | // VC++ doesn't understand "ssize_t" |
759 | | #ifndef HAVE_SSIZET |
760 | | #define HAVE_SSIZET 1 |
761 | | // The following correctly defines ssize_t on most (all?) VC++ versions: |
762 | | // #include <BaseTsd.h> |
763 | | // typedef SSIZE_T ssize_t; |
764 | | // However, several projects in googleclient already use plain 'int', e.g., |
765 | | // googleclient/posix/unistd.h |
766 | | // googleclient/earth/client/libs/base/types.h |
767 | | // so to avoid conflicts with those definitions, we do the same here. |
768 | | typedef int ssize_t; |
769 | | #endif |
770 | | |
771 | | #define strtoq _strtoi64 |
772 | | #define strtouq _strtoui64 |
773 | | #define strtoll _strtoi64 |
774 | | #define strtoull _strtoui64 |
775 | | #define atoll _atoi64 |
776 | | |
777 | | // VC++ 6 and before ship without an ostream << operator for 64-bit ints |
778 | | #if (_MSC_VER <= 1200) |
779 | | #include <iosfwd> |
780 | | using std::ostream; |
781 | | inline ostream& operator<<(ostream& os, const unsigned __int64& num) { |
782 | | // Fake operator; doesn't actually do anything. |
783 | | LOG(FATAL) << "64-bit ostream operator << not supported in VC++ 6"; |
784 | | return os; |
785 | | } |
786 | | #endif |
787 | | |
788 | | // You say tomato, I say atotom |
789 | | #define PATH_MAX MAX_PATH |
790 | | |
791 | | // You say tomato, I say _tomato |
792 | | #define vsnprintf _vsnprintf |
793 | | #define snprintf _snprintf |
794 | | #define strcasecmp _stricmp |
795 | | #define strncasecmp _strnicmp |
796 | | |
797 | | #define nextafter _nextafter |
798 | | |
799 | | #define hypot _hypot |
800 | | #define hypotf _hypotf |
801 | | |
802 | | #define strdup _strdup |
803 | | #define tempnam _tempnam |
804 | | #define chdir _chdir |
805 | | #define getcwd _getcwd |
806 | | #define putenv _putenv |
807 | | |
808 | | // You say tomato, I say toma |
809 | | #define random() rand() |
810 | | #define srandom(x) srand(x) |
811 | | |
812 | | // You say juxtapose, I say transpose |
813 | | #define bcopy(s, d, n) memcpy(d, s, n) |
814 | | |
815 | | inline void* aligned_malloc(size_t size, int minimum_alignment) { |
816 | | return _aligned_malloc(size, minimum_alignment); |
817 | | } |
818 | | |
819 | | // ----- BEGIN VC++ STUBS & FAKE DEFINITIONS --------------------------------- |
820 | | |
821 | | // See http://en.wikipedia.org/wiki/IEEE_754 for details of |
822 | | // floating point format. |
823 | | |
824 | | enum { |
825 | | FP_NAN, // is "Not a Number" |
826 | | FP_INFINITE, // is either plus or minus infinity. |
827 | | FP_ZERO, |
828 | | FP_SUBNORMAL, // is too small to be represented in normalized format. |
829 | | FP_NORMAL // if nothing of the above is correct that it must be a |
830 | | // normal floating-point number. |
831 | | }; |
832 | | |
833 | | inline int fpclassify_double(double x) { |
834 | | const int float_point_class = _fpclass(x); |
835 | | int c99_class; |
836 | | switch (float_point_class) { |
837 | | case _FPCLASS_SNAN: // Signaling NaN |
838 | | case _FPCLASS_QNAN: // Quiet NaN |
839 | | c99_class = FP_NAN; |
840 | | break; |
841 | | case _FPCLASS_NZ: // Negative zero ( -0) |
842 | | case _FPCLASS_PZ: // Positive 0 (+0) |
843 | | c99_class = FP_ZERO; |
844 | | break; |
845 | | case _FPCLASS_NINF: // Negative infinity ( -INF) |
846 | | case _FPCLASS_PINF: // Positive infinity (+INF) |
847 | | c99_class = FP_INFINITE; |
848 | | break; |
849 | | case _FPCLASS_ND: // Negative denormalized |
850 | | case _FPCLASS_PD: // Positive denormalized |
851 | | c99_class = FP_SUBNORMAL; |
852 | | break; |
853 | | case _FPCLASS_NN: // Negative normalized non-zero |
854 | | case _FPCLASS_PN: // Positive normalized non-zero |
855 | | c99_class = FP_NORMAL; |
856 | | break; |
857 | | default: |
858 | | c99_class = FP_NAN; // Should never happen |
859 | | break; |
860 | | } |
861 | | return c99_class; |
862 | | } |
863 | | |
864 | | // This function handle the special subnormal case for float; it will |
865 | | // become a normal number while casting to double. |
866 | | // bit_cast is avoided to simplify dependency and to create a code that is |
867 | | // easy to deploy in C code |
868 | | inline int fpclassify_float(float x) { |
869 | | uint32 bitwise_representation; |
870 | | memcpy(&bitwise_representation, &x, 4); |
871 | | if ((bitwise_representation & 0x7f800000) == 0 && (bitwise_representation & 0x007fffff) != 0) |
872 | | return FP_SUBNORMAL; |
873 | | return fpclassify_double(x); |
874 | | } |
875 | | // |
876 | | // This define takes care of the denormalized float; the casting to |
877 | | // double make it a normal number |
878 | | #define fpclassify(x) ((sizeof(x) == sizeof(float)) ? fpclassify_float(x) : fpclassify_double(x)) |
879 | | |
880 | | #define isnan _isnan |
881 | | |
882 | | inline int isinf(double x) { |
883 | | const int float_point_class = _fpclass(x); |
884 | | if (float_point_class == _FPCLASS_PINF) return 1; |
885 | | if (float_point_class == _FPCLASS_NINF) return -1; |
886 | | return 0; |
887 | | } |
888 | | |
889 | | // #include "conflict-signal.h" |
890 | | typedef void (*sig_t)(int); |
891 | | |
892 | | // These actually belong in errno.h but there's a name confilict in errno |
893 | | // on WinNT. They (and a ton more) are also found in Winsock2.h, but |
894 | | // if'd out under NT. We need this subset at minimum. |
895 | | #define EXFULL ENOMEM // not really that great a translation... |
896 | | // The following are already defined in VS2010. |
897 | | #if (_MSC_VER < 1600) |
898 | | #define EWOULDBLOCK WSAEWOULDBLOCK |
899 | | #ifndef PTHREADS_REDHAT_WIN32 |
900 | | #define ETIMEDOUT WSAETIMEDOUT |
901 | | #endif |
902 | | #define ENOTSOCK WSAENOTSOCK |
903 | | #define EINPROGRESS WSAEINPROGRESS |
904 | | #define ECONNRESET WSAECONNRESET |
905 | | #endif |
906 | | |
907 | | // |
908 | | // Really from <string.h> |
909 | | // |
910 | | |
911 | | inline void bzero(void* s, int n) { |
912 | | memset(s, 0, n); |
913 | | } |
914 | | |
915 | | // From glob.h |
916 | | #define __ptr_t void* |
917 | | |
918 | | // Defined all over the place. |
919 | | typedef int pid_t; |
920 | | |
921 | | // From stat.h |
922 | | typedef unsigned int mode_t; |
923 | | |
924 | | // u_int16_t, int16_t don't exist in MSVC |
925 | | typedef unsigned short u_int16_t; |
926 | | typedef short int16_t; |
927 | | |
928 | | // ----- END VC++ STUBS & FAKE DEFINITIONS ---------------------------------- |
929 | | |
930 | | #endif // _MSC_VER |
931 | | |
932 | | #ifdef STL_MSVC // not always the same as _MSC_VER |
933 | | #include "base/port_hash.h" |
934 | | #else |
935 | | struct PortableHashBase {}; |
936 | | #endif |
937 | | |
938 | | #if defined(OS_WINDOWS) || defined(__APPLE__) |
939 | | // gethostbyname() *is* thread-safe for Windows native threads. It is also |
940 | | // safe on Mac OS X, where it uses thread-local storage, even though the |
941 | | // manpages claim otherwise. For details, see |
942 | | // http://lists.apple.com/archives/Darwin-dev/2006/May/msg00008.html |
943 | | #else |
944 | | // gethostbyname() is not thread-safe. So disallow its use. People |
945 | | // should either use the HostLookup::Lookup*() methods, or gethostbyname_r() |
946 | | #define gethostbyname gethostbyname_is_not_thread_safe_DO_NOT_USE |
947 | | #endif |
948 | | |
949 | | // create macros in which the programmer should enclose all specializations |
950 | | // for hash_maps and hash_sets. This is necessary since these classes are not |
951 | | // STL standardized. Depending on the STL implementation they are in different |
952 | | // namespaces. Right now the right namespace is passed by the Makefile |
953 | | // Examples: gcc3: -DHASH_NAMESPACE=__gnu_cxx |
954 | | // icc: -DHASH_NAMESPACE=std |
955 | | // gcc2: empty |
956 | | |
957 | | #ifndef HASH_NAMESPACE |
958 | | #define HASH_NAMESPACE_DECLARATION_START |
959 | | #define HASH_NAMESPACE_DECLARATION_END |
960 | | #else |
961 | | #define HASH_NAMESPACE_DECLARATION_START namespace HASH_NAMESPACE { |
962 | | #define HASH_NAMESPACE_DECLARATION_END } |
963 | | #endif |
964 | | |
965 | | // Our STL-like classes use __STD. |
966 | | #if defined(__GNUC__) || defined(__APPLE__) || defined(_MSC_VER) |
967 | | #define __STD std |
968 | | #endif |
969 | | |
970 | | #if defined __GNUC__ |
971 | | #define STREAM_SET(s, bit) (s).setstate(ios_base::bit) |
972 | | #define STREAM_SETF(s, flag) (s).setf(ios_base::flag) |
973 | | #else |
974 | | #define STREAM_SET(s, bit) (s).set(ios::bit) |
975 | | #define STREAM_SETF(s, flag) (s).setf(ios::flag) |
976 | | #endif |
977 | | |
978 | | // Portable handling of unaligned loads, stores, and copies. |
979 | | // On some platforms, like ARM, the copy functions can be more efficient |
980 | | // then a load and a store. |
981 | | |
982 | | #if defined(__i386) || defined(ARCH_ATHLON) || defined(__x86_64__) || defined(_ARCH_PPC) |
983 | | |
984 | | // x86 and x86-64 can perform unaligned loads/stores directly; |
985 | | // modern PowerPC hardware can also do unaligned integer loads and stores; |
986 | | // but note: the FPU still sends unaligned loads and stores to a trap handler! |
987 | | |
988 | | #define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16*>(_p)) |
989 | 8 | #define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32*>(_p)) |
990 | 1.19k | #define UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64*>(_p)) |
991 | | |
992 | | #define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16*>(_p) = (_val)) |
993 | 0 | #define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32*>(_p) = (_val)) |
994 | 0 | #define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64*>(_p) = (_val)) |
995 | | |
996 | | #elif defined(__arm__) && !defined(__ARM_ARCH_5__) && !defined(__ARM_ARCH_5T__) && \ |
997 | | !defined(__ARM_ARCH_5TE__) && !defined(__ARM_ARCH_5TEJ__) && !defined(__ARM_ARCH_6__) && \ |
998 | | !defined(__ARM_ARCH_6J__) && !defined(__ARM_ARCH_6K__) && !defined(__ARM_ARCH_6Z__) && \ |
999 | | !defined(__ARM_ARCH_6ZK__) && !defined(__ARM_ARCH_6T2__) |
1000 | | |
1001 | | // ARMv7 and newer support native unaligned accesses, but only of 16-bit |
1002 | | // and 32-bit values (not 64-bit); older versions either raise a fatal signal, |
1003 | | // do an unaligned read and rotate the words around a bit, or do the reads very |
1004 | | // slowly (trip through kernel mode). There's no simple #define that says just |
1005 | | // “ARMv7 or higher”, so we have to filter away all ARMv5 and ARMv6 |
1006 | | // sub-architectures. Newer gcc (>= 4.6) set an __ARM_FEATURE_ALIGNED #define, |
1007 | | // so in time, maybe we can move on to that. |
1008 | | // |
1009 | | // This is a mess, but there's not much we can do about it. |
1010 | | |
1011 | | #define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16*>(_p)) |
1012 | | #define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32*>(_p)) |
1013 | | |
1014 | | #define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16*>(_p) = (_val)) |
1015 | | #define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32*>(_p) = (_val)) |
1016 | | |
1017 | | // TODO(user): NEON supports unaligned 64-bit loads and stores. |
1018 | | // See if that would be more efficient on platforms supporting it, |
1019 | | // at least for copies. |
1020 | | |
1021 | | inline uint64 UNALIGNED_LOAD64(const void* p) { |
1022 | | uint64 t; |
1023 | | memcpy(&t, p, sizeof t); |
1024 | | return t; |
1025 | | } |
1026 | | |
1027 | | inline void UNALIGNED_STORE64(void* p, uint64 v) { |
1028 | | memcpy(p, &v, sizeof v); |
1029 | | } |
1030 | | |
1031 | | #else |
1032 | | |
1033 | | #define NEED_ALIGNED_LOADS |
1034 | | |
1035 | | // These functions are provided for architectures that don't support |
1036 | | // unaligned loads and stores. |
1037 | | |
1038 | | inline uint16 UNALIGNED_LOAD16(const void* p) { |
1039 | | uint16 t; |
1040 | | memcpy(&t, p, sizeof t); |
1041 | | return t; |
1042 | | } |
1043 | | |
1044 | | inline uint32 UNALIGNED_LOAD32(const void* p) { |
1045 | | uint32 t; |
1046 | | memcpy(&t, p, sizeof t); |
1047 | | return t; |
1048 | | } |
1049 | | |
1050 | | inline uint64 UNALIGNED_LOAD64(const void* p) { |
1051 | | uint64 t; |
1052 | | memcpy(&t, p, sizeof t); |
1053 | | return t; |
1054 | | } |
1055 | | |
1056 | | inline void UNALIGNED_STORE16(void* p, uint16 v) { |
1057 | | memcpy(p, &v, sizeof v); |
1058 | | } |
1059 | | |
1060 | | inline void UNALIGNED_STORE32(void* p, uint32 v) { |
1061 | | memcpy(p, &v, sizeof v); |
1062 | | } |
1063 | | |
1064 | | inline void UNALIGNED_STORE64(void* p, uint64 v) { |
1065 | | memcpy(p, &v, sizeof v); |
1066 | | } |
1067 | | |
1068 | | #endif |
1069 | | |
1070 | | #ifdef _LP64 |
1071 | | #define UNALIGNED_LOADW(_p) UNALIGNED_LOAD64(_p) |
1072 | | #define UNALIGNED_STOREW(_p, _val) UNALIGNED_STORE64(_p, _val) |
1073 | | #else |
1074 | | #define UNALIGNED_LOADW(_p) UNALIGNED_LOAD32(_p) |
1075 | | #define UNALIGNED_STOREW(_p, _val) UNALIGNED_STORE32(_p, _val) |
1076 | | #endif |
1077 | | |
1078 | | // NOTE(user): These are only exported to C++ because the macros they depend on |
1079 | | // use C++-only syntax. This #ifdef can be removed if/when the macros are fixed. |
1080 | | |
1081 | | #if defined(__cplusplus) |
1082 | | |
1083 | 0 | inline void UnalignedCopy16(const void* src, void* dst) { |
1084 | 0 | UNALIGNED_STORE16(dst, UNALIGNED_LOAD16(src)); |
1085 | 0 | } |
1086 | | |
1087 | 0 | inline void UnalignedCopy32(const void* src, void* dst) { |
1088 | 0 | UNALIGNED_STORE32(dst, UNALIGNED_LOAD32(src)); |
1089 | 0 | } |
1090 | | |
1091 | 0 | inline void UnalignedCopy64(const void* src, void* dst) { |
1092 | 0 | if (sizeof(void*) == 8) { |
1093 | 0 | UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src)); |
1094 | 0 | } else { |
1095 | 0 | const char* src_char = reinterpret_cast<const char*>(src); |
1096 | 0 | char* dst_char = reinterpret_cast<char*>(dst); |
1097 | 0 |
|
1098 | 0 | UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char)); |
1099 | 0 | UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4)); |
1100 | 0 | } |
1101 | 0 | } |
1102 | | |
1103 | | #endif // defined(__cpluscplus) |
1104 | | |
1105 | | // printf macros for size_t, in the style of inttypes.h |
1106 | | #ifdef _LP64 |
1107 | | #define __PRIS_PREFIX "z" |
1108 | | #else |
1109 | | #define __PRIS_PREFIX |
1110 | | #endif |
1111 | | |
1112 | | // Use these macros after a % in a printf format string |
1113 | | // to get correct 32/64 bit behavior, like this: |
1114 | | // size_t size = records.size(); |
1115 | | // printf("%" PRIuS "\n", size); |
1116 | | |
1117 | | #define PRIdS __PRIS_PREFIX "d" |
1118 | | #define PRIxS __PRIS_PREFIX "x" |
1119 | | #define PRIuS __PRIS_PREFIX "u" |
1120 | | #define PRIXS __PRIS_PREFIX "X" |
1121 | | #define PRIoS __PRIS_PREFIX "o" |
1122 | | |
1123 | | #define GPRIuPTHREAD "lu" |
1124 | | #define GPRIxPTHREAD "lx" |
1125 | | #ifdef OS_CYGWIN |
1126 | | #define PRINTABLE_PTHREAD(pthreadt) reinterpret_cast<uintptr_t>(pthreadt) |
1127 | | #else |
1128 | | #define PRINTABLE_PTHREAD(pthreadt) pthreadt |
1129 | | #endif |
1130 | | |
1131 | | #define SIZEOF_MEMBER(t, f) sizeof(((t*)4096)->f) |
1132 | | |
1133 | | #define OFFSETOF_MEMBER(t, f) \ |
1134 | | (reinterpret_cast<char*>(&reinterpret_cast<t*>(16)->f) - reinterpret_cast<char*>(16)) |
1135 | | |
1136 | | #ifdef PTHREADS_REDHAT_WIN32 |
1137 | | #include <iosfwd> |
1138 | | using std::ostream; // NOLINT(build/include) |
1139 | | #include <pthread.h> // NOLINT(build/include) |
1140 | | // pthread_t is not a simple integer or pointer on Win32 |
1141 | | std::ostream& operator<<(std::ostream& out, const pthread_t& thread_id); |
1142 | | #endif |
1143 | | |
1144 | | // GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least |
1145 | | // gcc-4.7 and clang-3.1 (2011-12-13). __cplusplus was defined to 1 |
1146 | | // in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is |
1147 | | // defined according to the language version in effect thereafter. I |
1148 | | // believe MSVC will also define __cplusplus according to the language |
1149 | | // version, but haven't checked that. |
1150 | | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L |
1151 | | // Define this to 1 if the code is compiled in C++11 mode; leave it |
1152 | | // undefined otherwise. Do NOT define it to 0 -- that causes |
1153 | | // '#ifdef LANG_CXX11' to behave differently from '#if LANG_CXX11'. |
1154 | | #define LANG_CXX11 1 |
1155 | | #endif |
1156 | | |
1157 | | // On some platforms, a "function pointer" points to a function descriptor |
1158 | | // rather than directly to the function itself. Use FUNC_PTR_TO_CHAR_PTR(func) |
1159 | | // to get a char-pointer to the first instruction of the function func. |
1160 | | #if defined(__powerpc__) || defined(__ia64) |
1161 | | // use opd section for function descriptors on these platforms, the function |
1162 | | // address is the first word of the descriptor |
1163 | | enum { kPlatformUsesOPDSections = 1 }; |
1164 | | #define FUNC_PTR_TO_CHAR_PTR(func) (reinterpret_cast<char**>(func)[0]) |
1165 | | #else |
1166 | | enum { kPlatformUsesOPDSections = 0 }; |
1167 | | #define FUNC_PTR_TO_CHAR_PTR(func) (reinterpret_cast<char*>(func)) |
1168 | | #endif |