YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

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