This repository has been archived by the owner on Jul 27, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 238
/
Copy pathport.h
executable file
·1315 lines (1115 loc) · 41.9 KB
/
port.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// These are weird things we need to do to get this compiling on
// random systems (and on SWIG).
#ifndef BASE_PORT_H_
#define BASE_PORT_H_
#include <limits.h> // So we can set the bounds of our types
#include <string.h> // for memcpy()
#include <stdlib.h> // for free()
#if defined(__APPLE__)
#include <unistd.h> // for getpagesize() on mac
#elif defined(OS_CYGWIN)
#include <malloc.h> // for memalign()
#endif
#include "base/integral_types.h"
// Must happens before inttypes.h inclusion */
#if defined(__APPLE__)
/* From MacOSX's inttypes.h:
* "C++ implementations should define these macros only when
* __STDC_FORMAT_MACROS is defined before <inttypes.h> is included." */
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif /* __STDC_FORMAT_MACROS */
#endif /* __APPLE__ */
/* Default for most OSes */
/* We use SIGPWR since that seems unlikely to be used for other reasons. */
#define GOOGLE_OBSCURE_SIGNAL SIGPWR
#if defined OS_LINUX || defined OS_CYGWIN
// _BIG_ENDIAN
#include <endian.h>
// The uint mess:
// mysql.h sets _GNU_SOURCE which sets __USE_MISC in <features.h>
// sys/types.h typedefs uint if __USE_MISC
// mysql typedefs uint if HAVE_UINT not set
// The following typedef is carefully considered, and should not cause
// any clashes
#if !defined(__USE_MISC)
#if !defined(HAVE_UINT)
#define HAVE_UINT 1
typedef unsigned int uint;
#endif
#if !defined(HAVE_USHORT)
#define HAVE_USHORT 1
typedef unsigned short ushort;
#endif
#if !defined(HAVE_ULONG)
#define HAVE_ULONG 1
typedef unsigned long ulong;
#endif
#endif
#if defined(__cplusplus)
#include <cstddef> // For _GLIBCXX macros
#endif
#if !defined(HAVE_TLS) && defined(_GLIBCXX_HAVE_TLS) && defined(__x86_64__)
#define HAVE_TLS 1
#endif
#elif defined OS_FREEBSD
// _BIG_ENDIAN
#include <machine/endian.h>
#elif defined __APPLE__
// BIG_ENDIAN
#include <machine/endian.h> // NOLINT(build/include)
/* Let's try and follow the Linux convention */
#define __BYTE_ORDER BYTE_ORDER
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BIG_ENDIAN BIG_ENDIAN
#endif
// The following guarenty declaration of the byte swap functions, and
// define __BYTE_ORDER for MSVC
#ifdef _MSC_VER
#include <stdlib.h> // NOLINT(build/include)
#define __BYTE_ORDER __LITTLE_ENDIAN
#define bswap_16(x) _byteswap_ushort(x)
#define bswap_32(x) _byteswap_ulong(x)
#define bswap_64(x) _byteswap_uint64(x)
#elif defined(__APPLE__)
// Mac OS X / Darwin features
#include <libkern/OSByteOrder.h>
#define bswap_16(x) OSSwapInt16(x)
#define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x)
#elif defined(__GLIBC__)
#include <byteswap.h> // IWYU pragma: export
#else
static inline uint16 bswap_16(uint16 x) {
return ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);
}
#define bswap_16(x) bswap_16(x)
static inline uint32 bswap_32(uint32 x) {
return (((x & 0xFF) << 24) |
((x & 0xFF00) << 8) |
((x & 0xFF0000) >> 8) |
((x & 0xFF000000) >> 24));
}
#define bswap_32(x) bswap_32(x)
static inline uint64 bswap_64(uint64 x) {
return (((x & GG_ULONGLONG(0xFF)) << 56) |
((x & GG_ULONGLONG(0xFF00)) << 40) |
((x & GG_ULONGLONG(0xFF0000)) << 24) |
((x & GG_ULONGLONG(0xFF000000)) << 8) |
((x & GG_ULONGLONG(0xFF00000000)) >> 8) |
((x & GG_ULONGLONG(0xFF0000000000)) >> 24) |
((x & GG_ULONGLONG(0xFF000000000000)) >> 40) |
((x & GG_ULONGLONG(0xFF00000000000000)) >> 56));
}
#define bswap_64(x) bswap_64(x)
#endif
// define the macros IS_LITTLE_ENDIAN or IS_BIG_ENDIAN
// using the above endian definitions from endian.h if
// endian.h was included
#ifdef __BYTE_ORDER
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define IS_LITTLE_ENDIAN
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
#define IS_BIG_ENDIAN
#endif
#else
#if defined(__LITTLE_ENDIAN__)
#define IS_LITTLE_ENDIAN
#elif defined(__BIG_ENDIAN__)
#define IS_BIG_ENDIAN
#endif
// there is also PDP endian ...
#endif // __BYTE_ORDER
// Define the OS's path separator
#ifdef __cplusplus // C won't merge duplicate const variables at link time
// Some headers provide a macro for this (GCC's system.h), remove it so that we
// can use our own.
#undef PATH_SEPARATOR
#if defined(OS_WINDOWS)
const char PATH_SEPARATOR = '\\';
#else
const char PATH_SEPARATOR = '/';
#endif
#endif
// Windows has O_BINARY as a flag to open() (like "b" for fopen).
// Linux doesn't need make this distinction.
#if defined OS_LINUX && !defined O_BINARY
#define O_BINARY 0
#endif
// va_copy portability definitions
#ifdef _MSC_VER
// MSVC doesn't have va_copy yet.
// This is believed to work for 32-bit msvc. This may not work at all for
// other platforms.
// If va_list uses the single-element-array trick, you will probably get
// a compiler error here.
//
#include <stdarg.h>
inline void va_copy(va_list& a, va_list& b) {
a = b;
}
// Nor does it have uid_t
typedef int uid_t;
#endif
// Mac OS X / Darwin features
#if defined(__APPLE__)
// For mmap, Linux defines both MAP_ANONYMOUS and MAP_ANON and says MAP_ANON is
// deprecated. In Darwin, MAP_ANON is all there is.
#if !defined MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
// Linux has this in <sys/cdefs.h>
#define __ptr_t void *
// Linux has this in <linux/errno.h>
#define EXFULL ENOMEM // not really that great a translation...
// Mach-O supports sections (albeit with small names), but doesn't have
// vars at the beginning and end. Instead you should call the function
// getsectdata("__DATA", name, &size).
#define HAVE_ATTRIBUTE_SECTION 1
// Any function with ATTRIBUTE_SECTION must not be inlined, or it will
// be placed into whatever section its caller is placed into.
#define ATTRIBUTE_SECTION(name) \
__attribute__ ((section ("__DATA, " #name))) __attribute__ ((noinline))
#define ENUM_DYLD_BOOL // so that we don't pollute the global namespace
extern "C" {
#include <mach-o/getsect.h>
#include <mach-o/dyld.h>
}
class AssignAttributeStartEnd {
public:
AssignAttributeStartEnd(const char* name, char** pstart, char** pend) {
// Find out what dynamic library name is defined in
for (int i = _dyld_image_count() - 1; i >= 0; --i) {
const mach_header* hdr = _dyld_get_image_header(i);
uint32_t len;
*pstart = getsectdatafromheader(hdr, "__DATA", name, &len);
if (*pstart) { // NULL if not defined in this dynamic library
*pstart += _dyld_get_image_vmaddr_slide(i); // correct for reloc
*pend = *pstart + len;
return;
}
}
// If we get here, not defined in a dll at all. See if defined statically.
unsigned long len; // don't ask me why this type isn't uint32_t too...
*pstart = getsectdata("__DATA", name, &len);
*pend = *pstart + len;
}
};
// 1) DEFINE_ATTRIBUTE_SECTION_VARS: must be called once per unique
// name. You want to make sure this is executed before any
// DECLARE_ATTRIBUTE_SECTION_VARS; the easiest way is to put them
// in the same .cc file. Put this call at the global level.
// 2) INIT_ATTRIBUTE_SECTION_VARS: you can scatter calls to this in
// multiple places to help ensure execution before any
// DECLARE_ATTRIBUTE_SECTION_VARS. You must have at least one
// DEFINE, but you can have many INITs. Put each in its own scope.
// 3) DECLARE_ATTRIBUTE_SECTION_VARS: must be called before using
// ATTRIBUTE_SECTION_START or ATTRIBUTE_SECTION_STOP on a name.
// Put this call at the global level.
#define DECLARE_ATTRIBUTE_SECTION_VARS(name) \
extern char* __start_##name; \
extern char* __stop_##name;
#define INIT_ATTRIBUTE_SECTION_VARS(name) \
DECLARE_ATTRIBUTE_SECTION_VARS(name); \
static const AssignAttributeStartEnd __assign_##name( \
#name, &__start_##name, &__stop_##name)
#define DEFINE_ATTRIBUTE_SECTION_VARS(name) \
char* __start_##name, *__stop_##name; \
INIT_ATTRIBUTE_SECTION_VARS(name)
// Darwin doesn't have strnlen. No comment.
inline size_t strnlen(const char *s, size_t maxlen) {
const char* end = (const char *)memchr(s, '\0', maxlen);
if (end)
return end - s;
return maxlen;
}
namespace std {} // Avoid error if we didn't see std.
using namespace std; // Just like VC++, we need a using here.
// Doesn't exist on OSX; used in google.cc for send() to mean "no flags".
#define MSG_NOSIGNAL 0
// No SIGPWR on MacOSX. SIGINFO seems suitably obscure.
#undef GOOGLE_OBSCURE_SIGNAL
#define GOOGLE_OBSCURE_SIGNAL SIGINFO
#elif defined(OS_CYGWIN) // Cygwin-specific behavior.
#if defined(__CYGWIN32__)
#define __WORDSIZE 32
#else
// It's probably possible to support 64-bit, but the #defines will need checked.
#error "Cygwin is currently only 32-bit."
#endif
// No signalling on Windows.
#undef GOOGLE_OBSCURE_SIGNAL
#define GOOGLE_OBSCURE_SIGNAL 0
struct stack_t {
void* ss_sp;
int ss_flags;
size_t ss_size;
};
inline int sigaltstack(stack_t* ss, stack_t* oss) { return 0; }
#define PTHREAD_STACK_MIN 0 // Not provided by cygwin
// Scans memory for a character.
// memrchr is used in a few places, but it's linux-specific.
inline void* memrchr(const void* bytes, int find_char, size_t len) {
const unsigned char* cursor =
reinterpret_cast<const unsigned char*>(bytes) + len - 1;
unsigned char actual_char = find_char;
for (; cursor >= bytes; --cursor) {
if (*cursor == actual_char) {
return const_cast<void*>(reinterpret_cast<const void*>(cursor));
}
}
return NULL;
}
#endif
// Klocwork static analysis tool's C/C++ complier kwcc
#if defined(__KLOCWORK__)
#define STATIC_ANALYSIS
#endif // __KLOCWORK__
// GCC-specific features
#if (defined(__GNUC__) || defined(__APPLE__)) && !defined(SWIG)
//
// Tell the compiler to do printf format string checking if the
// compiler supports it; see the 'format' attribute in
// <http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html>.
//
// N.B.: As the GCC manual states, "[s]ince non-static C++ methods
// have an implicit 'this' argument, the arguments of such methods
// should be counted from two, not one."
//
#define PRINTF_ATTRIBUTE(string_index, first_to_check) \
__attribute__((__format__ (__printf__, string_index, first_to_check)))
#define SCANF_ATTRIBUTE(string_index, first_to_check) \
__attribute__((__format__ (__scanf__, string_index, first_to_check)))
//
// Prevent the compiler from padding a structure to natural alignment
//
#define PACKED __attribute__ ((packed))
// Cache line alignment
#if defined(__i386__) || defined(__x86_64__)
#define CACHELINE_SIZE 64
#elif defined(__powerpc64__)
// TODO(user) This is the L1 D-cache line size of our Power7 machines.
// Need to check if this is appropriate for other PowerPC64 systems.
#define CACHELINE_SIZE 128
#elif defined(__arm__)
// Cache line sizes for ARM: These values are not strictly correct since
// cache line sizes depend on implementations, not architectures. There
// are even implementations with cache line sizes configurable at boot
// time.
#if defined(__ARM_ARCH_5T__)
#define CACHELINE_SIZE 32
#elif defined(__ARM_ARCH_7A__)
#define CACHELINE_SIZE 64
#endif
#endif
// This is a NOP if CACHELINE_SIZE is not defined.
#ifdef CACHELINE_SIZE
#define CACHELINE_ALIGNED __attribute__((aligned(CACHELINE_SIZE)))
#else
#define CACHELINE_ALIGNED
#endif
//
// Prevent the compiler from complaining about or optimizing away variables
// that appear unused
// (careful, others e.g. third_party/libxml/xmlversion.h also define this)
#undef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__ ((unused))
//
// For functions we want to force inline or not inline.
// Introduced in gcc 3.1.
#define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
#define HAVE_ATTRIBUTE_ALWAYS_INLINE 1
#define ATTRIBUTE_NOINLINE __attribute__ ((noinline))
#define HAVE_ATTRIBUTE_NOINLINE 1
// For weak functions
#undef ATTRIBUTE_WEAK
#define ATTRIBUTE_WEAK __attribute__ ((weak))
#define HAVE_ATTRIBUTE_WEAK 1
// Tell the compiler to use "initial-exec" mode for a thread-local variable.
// See http://people.redhat.com/drepper/tls.pdf for the gory details.
#define ATTRIBUTE_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec")))
//
// Tell the compiler that some function parameters should be non-null pointers.
// Note: As the GCC manual states, "[s]ince non-static C++ methods
// have an implicit 'this' argument, the arguments of such methods
// should be counted from two, not one."
//
#define ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index)))
//
// Tell the compiler that a given function never returns
//
#define ATTRIBUTE_NORETURN __attribute__((noreturn))
// Tell AddressSanitizer (or other memory testing tools) to ignore a given
// function. Useful for cases when a function reads random locations on stack,
// calls _exit from a cloned subprocess, deliberately accesses buffer
// out of bounds or does other scary things with memory.
#ifdef ADDRESS_SANITIZER
#define ATTRIBUTE_NO_SANITIZE_ADDRESS \
__attribute__((no_sanitize_address))
#else
#define ATTRIBUTE_NO_SANITIZE_ADDRESS
#endif
// Tell MemorySanitizer to relax the handling of a given function. All "Use of
// uninitialized value" warnings from such functions will be suppressed, and all
// values loaded from memory will be considered fully initialized.
// This is similar to the ADDRESS_SANITIZER attribute above, but deals with
// initializedness rather than addressability issues.
#ifdef MEMORY_SANITIZER
#define ATTRIBUTE_NO_SANITIZE_MEMORY \
__attribute__((no_sanitize_memory))
#else
#define ATTRIBUTE_NO_SANITIZE_MEMORY
#endif
#ifndef HAVE_ATTRIBUTE_SECTION // may have been pre-set to 0, e.g. for Darwin
#define HAVE_ATTRIBUTE_SECTION 1
#endif
#if HAVE_ATTRIBUTE_SECTION // define section support for the case of GCC
//
// Tell the compiler/linker to put a given function into a section and define
// "__start_ ## name" and "__stop_ ## name" symbols to bracket the section.
// Sections can not span more than none compilation unit.
// This functionality is supported by GNU linker.
// Any function with ATTRIBUTE_SECTION must not be inlined, or it will
// be placed into whatever section its caller is placed into.
//
#ifndef ATTRIBUTE_SECTION
#define ATTRIBUTE_SECTION(name) \
__attribute__ ((section (#name))) __attribute__ ((noinline))
#endif
//
// Weak section declaration to be used as a global declaration
// for ATTRIBUTE_SECTION_START|STOP(name) to compile and link
// even without functions with ATTRIBUTE_SECTION(name).
// DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's
// a no-op on ELF but not on Mach-O.
//
#ifndef DECLARE_ATTRIBUTE_SECTION_VARS
#define DECLARE_ATTRIBUTE_SECTION_VARS(name) \
extern char __start_##name[] ATTRIBUTE_WEAK; \
extern char __stop_##name[] ATTRIBUTE_WEAK
#endif
#ifndef DEFINE_ATTRIBUTE_SECTION_VARS
#define INIT_ATTRIBUTE_SECTION_VARS(name)
#define DEFINE_ATTRIBUTE_SECTION_VARS(name)
#endif
//
// Return void* pointers to start/end of a section of code with
// functions having ATTRIBUTE_SECTION(name).
// Returns 0 if no such functions exits.
// One must DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and link.
//
#define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))
#define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
#endif // HAVE_ATTRIBUTE_SECTION
#if defined(__i386__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC __attribute__((force_align_arg_pointer))
#define REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
#elif defined(__i386__) || defined(__x86_64__)
#define REQUIRE_STACK_ALIGN_TRAMPOLINE (1)
#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
#else
#define REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
#endif
//
// Tell the compiler to warn about unused return values for functions declared
// with this macro. The macro should be used on function declarations
// following the argument list:
//
// Sprocket* AllocateSprocket() MUST_USE_RESULT;
//
#if defined(SWIG)
#define MUST_USE_RESULT
#elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define MUST_USE_RESULT __attribute__ ((warn_unused_result))
#else
#define MUST_USE_RESULT
#endif
#if defined(__GNUC__)
// Defined behavior on some of the uarchs:
// PREFETCH_HINT_T0:
// prefetch to all levels of the hierarchy (except on p4: prefetch to L2)
// PREFETCH_HINT_NTA:
// p4: fetch to L2, but limit to 1 way (out of the 8 ways)
// core: skip L2, go directly to L1
// k8 rev E and later: skip L2, can go to either of the 2-ways in L1
enum PrefetchHint {
PREFETCH_HINT_T0 = 3, // More temporal locality
PREFETCH_HINT_T1 = 2,
PREFETCH_HINT_T2 = 1, // Less temporal locality
PREFETCH_HINT_NTA = 0 // No temporal locality
};
#else
// prefetch is a no-op for this target. Feel free to add more sections above.
#endif
extern inline void prefetch(const char *x, int hint) {
#if defined(__llvm__)
// In the gcc version of prefetch(), hint is only a constant _after_ inlining
// (assumed to have been successful). llvm views things differently, and
// checks constant-ness _before_ inlining. This leads to compilation errors
// with using the other version of this code with llvm.
//
// One way round this is to use a switch statement to explicitly match
// prefetch hint enumerations, and invoke __builtin_prefetch for each valid
// value. llvm's optimization removes the switch and unused case statements
// after inlining, so that this boils down in the end to the same as for gcc;
// that is, a single inlined prefetchX instruction.
//
// Note that this version of prefetch() cannot verify constant-ness of hint.
// If client code calls prefetch() with a variable value for hint, it will
// receive the full expansion of the switch below, perhaps also not inlined.
// This should however not be a problem in the general case of well behaved
// caller code that uses the supplied prefetch hint enumerations.
switch (hint) {
case PREFETCH_HINT_T0:
__builtin_prefetch(x, 0, PREFETCH_HINT_T0);
break;
case PREFETCH_HINT_T1:
__builtin_prefetch(x, 0, PREFETCH_HINT_T1);
break;
case PREFETCH_HINT_T2:
__builtin_prefetch(x, 0, PREFETCH_HINT_T2);
break;
case PREFETCH_HINT_NTA:
__builtin_prefetch(x, 0, PREFETCH_HINT_NTA);
break;
default:
__builtin_prefetch(x);
break;
}
#elif defined(__GNUC__)
#if !defined(__i386) || defined(__SSE__)
if (__builtin_constant_p(hint)) {
__builtin_prefetch(x, 0, hint);
} else {
// Defaults to PREFETCH_HINT_T0
__builtin_prefetch(x);
}
#else
// We want a __builtin_prefetch, but we build with the default -march=i386
// where __builtin_prefetch quietly turns into nothing.
// Once we crank up to -march=pentium3 or higher the __SSE__
// clause above will kick in with the builtin.
// -- mec 2006-06-06
if (hint == PREFETCH_HINT_NTA)
__asm__ __volatile__("prefetchnta (%0)" : : "r"(x));
#endif
#else
// You get no effect. Feel free to add more sections above.
#endif
}
#ifdef __cplusplus
// prefetch intrinsic (bring data to L1 without polluting L2 cache)
extern inline void prefetch(const char *x) {
return prefetch(x, 0);
}
#endif // ifdef __cplusplus
//
// GCC can be told that a certain branch is not likely to be taken (for
// instance, a CHECK failure), and use that information in static analysis.
// Giving it this information can help it optimize for the common case in
// the absence of better information (ie. -fprofile-arcs).
//
#if defined(__GNUC__)
#define PREDICT_FALSE(x) (__builtin_expect(x, 0))
#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
#else
#define PREDICT_FALSE(x) x
#define PREDICT_TRUE(x) x
#endif
//
// Tell GCC that a function is hot or cold. GCC can use this information to
// improve static analysis, i.e. a conditional branch to a cold function
// is likely to be not-taken.
// This annotation is used for function declarations, e.g.:
// int foo() ATTRIBUTE_HOT;
//
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
#define ATTRIBUTE_HOT __attribute__ ((hot))
#define ATTRIBUTE_COLD __attribute__ ((cold))
#else
#define ATTRIBUTE_HOT
#define ATTRIBUTE_COLD
#endif
#define FTELLO ftello
#define FSEEKO fseeko
#if !defined(__cplusplus) && !defined(__APPLE__) && !defined(OS_CYGWIN)
// stdlib.h only declares this in C++, not in C, so we declare it here.
// Also make sure to avoid declaring it on platforms which don't support it.
extern int posix_memalign(void **memptr, size_t alignment, size_t size);
#endif
inline void *aligned_malloc(size_t size, int minimum_alignment) {
#if defined(__APPLE__)
// mac lacks memalign(), posix_memalign(), however, according to
// http://stackoverflow.com/questions/196329/osx-lacks-memalign
// mac allocs are already 16-byte aligned.
if (minimum_alignment <= 16)
return malloc(size);
// next, try to return page-aligned memory. perhaps overkill
if (minimum_alignment <= getpagesize())
return valloc(size);
// give up
return NULL;
#elif defined(OS_CYGWIN)
return memalign(minimum_alignment, size);
#else // !__APPLE__ && !OS_CYGWIN
void *ptr = NULL;
if (posix_memalign(&ptr, minimum_alignment, size) != 0)
return NULL;
else
return ptr;
#endif
}
inline void aligned_free(void *aligned_memory) {
free(aligned_memory);
}
#else // not GCC
#define PRINTF_ATTRIBUTE(string_index, first_to_check)
#define SCANF_ATTRIBUTE(string_index, first_to_check)
#define PACKED
#define CACHELINE_ALIGNED
#define ATTRIBUTE_UNUSED
#define ATTRIBUTE_ALWAYS_INLINE
#define ATTRIBUTE_NOINLINE
#define ATTRIBUTE_HOT
#define ATTRIBUTE_COLD
#define ATTRIBUTE_WEAK
#define HAVE_ATTRIBUTE_WEAK 0
#define ATTRIBUTE_INITIAL_EXEC
#define ATTRIBUTE_NONNULL(arg_index)
#define ATTRIBUTE_NORETURN
#define HAVE_ATTRIBUTE_SECTION 0
#define ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
#define REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
#define MUST_USE_RESULT
extern inline void prefetch(const char *x) {}
#define PREDICT_FALSE(x) x
#define PREDICT_TRUE(x) x
// These should be redefined appropriately if better alternatives to
// ftell/fseek exist in the compiler
#define FTELLO ftell
#define FSEEKO fseek
#endif // GCC
//
// Provides a char array with the exact same alignment as another type. The
// first parameter must be a complete type, the second parameter is how many
// of that type to provide space for.
//
// ALIGNED_CHAR_ARRAY(struct stat, 16) storage_;
//
#if defined(__cplusplus)
#undef ALIGNED_CHAR_ARRAY
// Because MSVC and older GCCs require that the argument to their alignment
// construct to be a literal constant integer, we use a template instantiated
// at all the possible powers of two.
#ifndef SWIG
template<int alignment, int size> struct AlignType { };
template<int size> struct AlignType<0, size> { typedef char result[size]; };
#if defined(_MSC_VER)
#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __declspec(align(X))
#define BASE_PORT_H_ALIGN_OF(T) __alignof(T)
#elif defined(__GNUC__)
#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __attribute__((aligned(X)))
#define BASE_PORT_H_ALIGN_OF(T) __alignof__(T)
#endif
#if defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
#define BASE_PORT_H_ALIGNTYPE_TEMPLATE(X) \
template<int size> struct AlignType<X, size> { \
typedef BASE_PORT_H_ALIGN_ATTRIBUTE(X) char result[size]; \
}
BASE_PORT_H_ALIGNTYPE_TEMPLATE(1);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(2);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(4);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(8);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(16);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(32);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(64);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(128);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(256);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(512);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(1024);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(2048);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(4096);
BASE_PORT_H_ALIGNTYPE_TEMPLATE(8192);
// Any larger and MSVC++ will complain.
#define ALIGNED_CHAR_ARRAY(T, Size) \
typename AlignType<BASE_PORT_H_ALIGN_OF(T), sizeof(T) * Size>::result
#undef BASE_PORT_H_ALIGNTYPE_TEMPLATE
#undef BASE_PORT_H_ALIGN_ATTRIBUTE
#else // defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
#define ALIGNED_CHAR_ARRAY you_must_define_ALIGNED_CHAR_ARRAY_for_your_compiler_in_base_port_h
#endif // defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
#else // !SWIG
// SWIG can't represent alignment and doesn't care about alignment on data
// members (it works fine without it).
template<typename Size>
struct AlignType { typedef char result[Size]; };
#define ALIGNED_CHAR_ARRAY(T, Size) AlignType<Size * sizeof(T)>::result
#endif // !SWIG
#else // __cpluscplus
#define ALIGNED_CHAR_ARRAY ALIGNED_CHAR_ARRAY_is_not_available_without_Cplusplus
#endif // __cplusplus
#if !HAVE_ATTRIBUTE_SECTION // provide dummy definitions
#define ATTRIBUTE_SECTION(name)
#define INIT_ATTRIBUTE_SECTION_VARS(name)
#define DEFINE_ATTRIBUTE_SECTION_VARS(name)
#define DECLARE_ATTRIBUTE_SECTION_VARS(name)
#define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0))
#define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0))
#endif // !HAVE_ATTRIBUTE_SECTION
#ifdef _MSC_VER /* if Visual C++ */
// This compiler flag can be easily overlooked on MSVC.
// _CHAR_UNSIGNED gets set with the /J flag.
#ifndef _CHAR_UNSIGNED
#error chars must be unsigned! Use the /J flag on the compiler command line.
#endif
// MSVC is a little hyper-active in its warnings
// Signed vs. unsigned comparison is ok.
#pragma warning(disable : 4018 )
// We know casting from a long to a char may lose data
#pragma warning(disable : 4244 )
// Don't need performance warnings about converting ints to bools
#pragma warning(disable : 4800 )
// Integral constant overflow is apparently ok too
// for example:
// short k; int n;
// k = k + n;
#pragma warning(disable : 4307 )
// It's ok to use this* in constructor
// Example:
// class C {
// Container cont_;
// C() : cont_(this) { ...
#pragma warning(disable : 4355 )
// Truncating from double to float is ok
#pragma warning(disable : 4305 )
#include <winsock2.h>
#include <assert.h>
#include <windows.h>
#undef ERROR
#include <float.h> // for nextafter functionality on windows
#include <math.h> // for HUGE_VAL
#ifndef HUGE_VALF
#define HUGE_VALF (static_cast<float>(HUGE_VAL))
#endif
namespace std {} // Avoid error if we didn't see std.
using namespace std;
// VC++ doesn't understand "uint"
#ifndef HAVE_UINT
#define HAVE_UINT 1
typedef unsigned int uint;
#endif
// VC++ doesn't understand "ssize_t"
#ifndef HAVE_SSIZET
#define HAVE_SSIZET 1
// The following correctly defines ssize_t on most (all?) VC++ versions:
// #include <BaseTsd.h>
// typedef SSIZE_T ssize_t;
// However, several projects in googleclient already use plain 'int', e.g.,
// googleclient/posix/unistd.h
// googleclient/earth/client/libs/base/types.h
// so to avoid conflicts with those definitions, we do the same here.
typedef int ssize_t;
#endif
#define strtoq _strtoi64
#define strtouq _strtoui64
#define strtoll _strtoi64
#define strtoull _strtoui64
#define atoll _atoi64
// VC++ 6 and before ship without an ostream << operator for 64-bit ints
#if (_MSC_VER <= 1200)
#include <iosfwd>
using std::ostream;
inline ostream& operator<< (ostream& os, const unsigned __int64& num ) {
// Fake operator; doesn't actually do anything.
LOG(FATAL) << "64-bit ostream operator << not supported in VC++ 6";
return os;
}
#endif
// You say tomato, I say atotom
#define PATH_MAX MAX_PATH
// You say tomato, I say _tomato
#define vsnprintf _vsnprintf
#define snprintf _snprintf
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define nextafter _nextafter
#define hypot _hypot
#define hypotf _hypotf
#define strdup _strdup
#define tempnam _tempnam
#define chdir _chdir
#define getcwd _getcwd
#define putenv _putenv
// You say tomato, I say toma
#define random() rand()
#define srandom(x) srand(x)
// You say juxtapose, I say transpose
#define bcopy(s, d, n) memcpy(d, s, n)
inline void *aligned_malloc(size_t size, int minimum_alignment) {
return _aligned_malloc(size, minimum_alignment);
}
inline void aligned_free(void *aligned_memory) {
_aligned_free(aligned_memory);
}
// ----- BEGIN VC++ STUBS & FAKE DEFINITIONS ---------------------------------
// See http://en.wikipedia.org/wiki/IEEE_754 for details of
// floating point format.
enum {
FP_NAN, // is "Not a Number"
FP_INFINITE, // is either plus or minus infinity.
FP_ZERO,
FP_SUBNORMAL, // is too small to be represented in normalized format.
FP_NORMAL // if nothing of the above is correct that it must be a
// normal floating-point number.
};
inline int fpclassify_double(double x) {
const int float_point_class =_fpclass(x);
int c99_class;
switch (float_point_class) {
case _FPCLASS_SNAN: // Signaling NaN
case _FPCLASS_QNAN: // Quiet NaN
c99_class = FP_NAN;
break;
case _FPCLASS_NZ: // Negative zero ( -0)
case _FPCLASS_PZ: // Positive 0 (+0)
c99_class = FP_ZERO;
break;
case _FPCLASS_NINF: // Negative infinity ( -INF)
case _FPCLASS_PINF: // Positive infinity (+INF)
c99_class = FP_INFINITE;
break;
case _FPCLASS_ND: // Negative denormalized
case _FPCLASS_PD: // Positive denormalized
c99_class = FP_SUBNORMAL;
break;
case _FPCLASS_NN: // Negative normalized non-zero
case _FPCLASS_PN: // Positive normalized non-zero
c99_class = FP_NORMAL;
break;
default:
c99_class = FP_NAN; // Should never happen
break;
}
return c99_class;
}
// This function handle the special subnormal case for float; it will
// become a normal number while casting to double.
// bit_cast is avoided to simplify dependency and to create a code that is
// easy to deploy in C code
inline int fpclassify_float(float x) {
uint32 bitwise_representation;
memcpy(&bitwise_representation, &x, 4);
if ((bitwise_representation & 0x7f800000) == 0 &&
(bitwise_representation & 0x007fffff) != 0)
return FP_SUBNORMAL;
return fpclassify_double(x);
}
//
// This define takes care of the denormalized float; the casting to
// double make it a normal number
#define fpclassify(x) ((sizeof(x) == sizeof(float)) ? fpclassify_float(x) : fpclassify_double(x))
#define isnan _isnan
inline int isinf(double x) {
const int float_point_class =_fpclass(x);
if (float_point_class == _FPCLASS_PINF) return 1;
if (float_point_class == _FPCLASS_NINF) return -1;
return 0;
}
// #include "conflict-signal.h"
typedef void (*sig_t)(int);
// These actually belong in errno.h but there's a name confilict in errno
// on WinNT. They (and a ton more) are also found in Winsock2.h, but
// if'd out under NT. We need this subset at minimum.
#define EXFULL ENOMEM // not really that great a translation...
// The following are already defined in VS2010.
#if (_MSC_VER < 1600)
#define EWOULDBLOCK WSAEWOULDBLOCK
#ifndef PTHREADS_REDHAT_WIN32
#define ETIMEDOUT WSAETIMEDOUT
#endif
#define ENOTSOCK WSAENOTSOCK
#define EINPROGRESS WSAEINPROGRESS
#define ECONNRESET WSAECONNRESET
#endif
//
// Really from <string.h>
//
inline void bzero(void *s, int n) {
memset(s, 0, n);
}
// From glob.h
#define __ptr_t void *
// Defined all over the place.