// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- // Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef _BASICTYPES_H_ #define _BASICTYPES_H_ #include #include // for memcpy() #ifdef HAVE_INTTYPES_H #include // gets us PRId64, etc #endif // To use this in an autoconf setting, make sure you run the following // autoconf macros: // AC_HEADER_STDC /* for stdint_h and inttypes_h */ // AC_CHECK_TYPES([__int64]) /* defined in some windows platforms */ #ifdef HAVE_INTTYPES_H #include // uint16_t might be here; PRId64 too. #endif #ifdef HAVE_STDINT_H #include // to get uint16_t (ISO naming madness) #endif #include // our last best hope for uint16_t // Standard typedefs // All Google code is compiled with -funsigned-char to make "char" // unsigned. Google code therefore doesn't need a "uchar" type. // TODO(csilvers): how do we make sure unsigned-char works on non-gcc systems? typedef signed char schar; typedef int8_t int8; typedef int16_t int16; typedef int32_t int32; typedef int64_t int64; // NOTE: unsigned types are DANGEROUS in loops and other arithmetical // places. Use the signed types unless your variable represents a bit // pattern (eg a hash value) or you really need the extra bit. Do NOT // use 'unsigned' to express "this value should always be positive"; // use assertions for this. typedef uint8_t uint8; typedef uint16_t uint16; typedef uint32_t uint32; typedef uint64_t uint64; const uint16 kuint16max = ( (uint16) 0xFFFF); const uint32 kuint32max = ( (uint32) 0xFFFFFFFF); const uint64 kuint64max = ( (((uint64) kuint32max) << 32) | kuint32max ); const int8 kint8max = ( ( int8) 0x7F); const int16 kint16max = ( ( int16) 0x7FFF); const int32 kint32max = ( ( int32) 0x7FFFFFFF); const int64 kint64max = ( ((( int64) kint32max) << 32) | kuint32max ); const int8 kint8min = ( ( int8) 0x80); const int16 kint16min = ( ( int16) 0x8000); const int32 kint32min = ( ( int32) 0x80000000); const int64 kint64min = ( (((uint64) kint32min) << 32) | 0 ); // Define the "portable" printf and scanf macros, if they're not // already there (via the inttypes.h we #included above, hopefully). // Mostly it's old systems that don't support inttypes.h, so we assume // they're 32 bit. #ifndef PRIx64 #define PRIx64 "llx" #endif #ifndef SCNx64 #define SCNx64 "llx" #endif #ifndef PRId64 #define PRId64 "lld" #endif #ifndef SCNd64 #define SCNd64 "lld" #endif #ifndef PRIu64 #define PRIu64 "llu" #endif #ifndef PRIxPTR #define PRIxPTR "lx" #endif // Also allow for printing of a pthread_t. #define GPRIuPTHREAD "lu" #define GPRIxPTHREAD "lx" #if defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__APPLE__) || defined(__FreeBSD__) #define PRINTABLE_PTHREAD(pthreadt) reinterpret_cast(pthreadt) #else #define PRINTABLE_PTHREAD(pthreadt) pthreadt #endif #if defined(__GNUC__) #define PREDICT_TRUE(x) __builtin_expect(!!(x), 1) #define PREDICT_FALSE(x) __builtin_expect(!!(x), 0) #else #define PREDICT_TRUE(x) (x) #define PREDICT_FALSE(x) (x) #endif // A macro to disallow the evil copy constructor and operator= functions // This should be used in the private: declarations for a class #define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ TypeName(const TypeName&); \ void operator=(const TypeName&) // An alternate name that leaves out the moral judgment... :-) #define DISALLOW_COPY_AND_ASSIGN(TypeName) DISALLOW_EVIL_CONSTRUCTORS(TypeName) // The COMPILE_ASSERT macro can be used to verify that a compile time // expression is true. For example, you could use it to verify the // size of a static array: // // COMPILE_ASSERT(sizeof(num_content_type_names) == sizeof(int), // content_type_names_incorrect_size); // // or to make sure a struct is smaller than a certain size: // // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); // // The second argument to the macro is the name of the variable. If // the expression is false, most compilers will issue a warning/error // containing the name of the variable. // // Implementation details of COMPILE_ASSERT: // // - COMPILE_ASSERT works by defining an array type that has -1 // elements (and thus is invalid) when the expression is false. // // - The simpler definition // // #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] // // does not work, as gcc supports variable-length arrays whose sizes // are determined at run-time (this is gcc's extension and not part // of the C++ standard). As a result, gcc fails to reject the // following code with the simple definition: // // int foo; // COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is // // not a compile-time constant. // // - By using the type CompileAssert<(bool(expr))>, we ensures that // expr is a compile-time constant. (Template arguments must be // determined at compile-time.) // // - The outter parentheses in CompileAssert<(bool(expr))> are necessary // to work around a bug in gcc 3.4.4 and 4.0.1. If we had written // // CompileAssert // // instead, these compilers will refuse to compile // // COMPILE_ASSERT(5 > 0, some_message); // // (They seem to think the ">" in "5 > 0" marks the end of the // template argument list.) // // - The array size is (bool(expr) ? 1 : -1), instead of simply // // ((expr) ? 1 : -1). // // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. template struct CompileAssert { }; #ifdef HAVE___ATTRIBUTE__ # define ATTRIBUTE_UNUSED __attribute__((unused)) #else # define ATTRIBUTE_UNUSED #endif #if defined(HAVE___ATTRIBUTE__) && defined(HAVE_TLS) #define ATTR_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec"))) #else #define ATTR_INITIAL_EXEC #endif #define COMPILE_ASSERT(expr, msg) \ typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] ATTRIBUTE_UNUSED #define arraysize(a) (sizeof(a) / sizeof(*(a))) #define OFFSETOF_MEMBER(strct, field) \ (reinterpret_cast(&reinterpret_cast(16)->field) - \ reinterpret_cast(16)) // bit_cast implements the equivalent of // "*reinterpret_cast(&source)". // // The reinterpret_cast method would produce undefined behavior // according to ISO C++ specification section 3.10 -15 -. // bit_cast<> calls memcpy() which is blessed by the standard, // especially by the example in section 3.9. // // Fortunately memcpy() is very fast. In optimized mode, with a // constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline // code with the minimal amount of data movement. On a 32-bit system, // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) // compiles to two loads and two stores. template inline Dest bit_cast(const Source& source) { COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), bitcasting_unequal_sizes); Dest dest; memcpy(&dest, &source, sizeof(dest)); return dest; } // bit_store implements the equivalent of // "dest = *reinterpret_cast(&source)". // // This prevents undefined behavior when the dest pointer is unaligned. template inline void bit_store(Dest *dest, const Source *source) { COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), bitcasting_unequal_sizes); memcpy(dest, source, sizeof(Dest)); } #ifdef HAVE___ATTRIBUTE__ # define ATTRIBUTE_WEAK __attribute__((weak)) # define ATTRIBUTE_NOINLINE __attribute__((noinline)) #else # define ATTRIBUTE_WEAK # define ATTRIBUTE_NOINLINE #endif #if defined(HAVE___ATTRIBUTE__) && defined(__ELF__) # define ATTRIBUTE_VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) #else # define ATTRIBUTE_VISIBILITY_HIDDEN #endif // Section attributes are supported for both ELF and Mach-O, but in // very different ways. Here's the API we provide: // 1) ATTRIBUTE_SECTION: put this with the declaration of all functions // you want to be in the same linker section // 2) 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. // 3) 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. // 4) 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. // 5) ATTRIBUTE_SECTION_START/ATTRIBUTE_SECTION_STOP: call this to say // where in memory a given section is. All functions declared with // ATTRIBUTE_SECTION are guaranteed to be between START and STOP. #if defined(HAVE___ATTRIBUTE__) && defined(__ELF__) # define ATTRIBUTE_SECTION(name) __attribute__ ((section (#name))) __attribute__((noinline)) // 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 DECLARE_ATTRIBUTE_SECTION_VARS(name) \ extern char __start_##name[] ATTRIBUTE_WEAK; \ extern char __stop_##name[] ATTRIBUTE_WEAK # define INIT_ATTRIBUTE_SECTION_VARS(name) // no-op for ELF # define DEFINE_ATTRIBUTE_SECTION_VARS(name) // no-op for ELF // Return void* pointers to start/end of a section of code with functions // having ATTRIBUTE_SECTION(name), or 0 if no such function exists. // One must DECLARE_ATTRIBUTE_SECTION(name) for this to compile and link. # define ATTRIBUTE_SECTION_START(name) (reinterpret_cast(__start_##name)) # define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(__stop_##name)) # define HAVE_ATTRIBUTE_SECTION_START 1 #elif defined(HAVE___ATTRIBUTE__) && defined(__MACH__) # define ATTRIBUTE_SECTION(name) __attribute__ ((section ("__TEXT, " #name))) #include #include class AssignAttributeStartEnd { public: AssignAttributeStartEnd(const char* name, char** pstart, char** pend) { // Find out what dynamic library name is defined in if (_dyld_present()) { for (int i = _dyld_image_count() - 1; i >= 0; --i) { const mach_header* hdr = _dyld_get_image_header(i); #ifdef MH_MAGIC_64 if (hdr->magic == MH_MAGIC_64) { uint64_t len; *pstart = getsectdatafromheader_64((mach_header_64*)hdr, "__TEXT", 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; } } #endif if (hdr->magic == MH_MAGIC) { uint32_t len; *pstart = getsectdatafromheader(hdr, "__TEXT", 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("__TEXT", name, &len); *pend = *pstart + len; } }; #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) # define ATTRIBUTE_SECTION_START(name) (reinterpret_cast(__start_##name)) # define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(__stop_##name)) # define HAVE_ATTRIBUTE_SECTION_START 1 #else // not HAVE___ATTRIBUTE__ && __ELF__, nor HAVE___ATTRIBUTE__ && __MACH__ # define ATTRIBUTE_SECTION(name) # define DECLARE_ATTRIBUTE_SECTION_VARS(name) # define INIT_ATTRIBUTE_SECTION_VARS(name) # define DEFINE_ATTRIBUTE_SECTION_VARS(name) # define ATTRIBUTE_SECTION_START(name) (reinterpret_cast(0)) # define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(0)) #endif // HAVE___ATTRIBUTE__ and __ELF__ or __MACH__ #if defined(HAVE___ATTRIBUTE__) # if (defined(__i386__) || defined(__x86_64__)) # define CACHELINE_ALIGNED __attribute__((aligned(64))) # elif (defined(__PPC__) || defined(__PPC64__)) # define CACHELINE_ALIGNED __attribute__((aligned(16))) # elif (defined(__arm__)) # define CACHELINE_ALIGNED __attribute__((aligned(64))) // some ARMs have shorter cache lines (ARM1176JZF-S is 32 bytes for example) but obviously 64-byte aligned implies 32-byte aligned # elif (defined(__mips__)) # define CACHELINE_ALIGNED __attribute__((aligned(128))) # elif (defined(__aarch64__)) # define CACHELINE_ALIGNED __attribute__((aligned(64))) // implementation specific, Cortex-A53 and 57 should have 64 bytes # elif (defined(__s390__)) # define CACHELINE_ALIGNED __attribute__((aligned(256))) # elif (defined(__riscv) && __riscv_xlen == 64) # define CACHELINE_ALIGNED __attribute__((aligned(64))) # elif (defined(__e2k__)) # define CACHELINE_ALIGNED __attribute__((aligned(64))) # else # error Could not determine cache line length - unknown architecture # endif #else # define CACHELINE_ALIGNED #endif // defined(HAVE___ATTRIBUTE__) #if defined(HAVE___ATTRIBUTE__ALIGNED_FN) # define CACHELINE_ALIGNED_FN CACHELINE_ALIGNED #else # define CACHELINE_ALIGNED_FN #endif // Structure for discovering alignment union MemoryAligner { void* p; double d; size_t s; } CACHELINE_ALIGNED; #if defined(HAVE___ATTRIBUTE__) && defined(__ELF__) #define ATTRIBUTE_HIDDEN __attribute__((visibility("hidden"))) #else #define ATTRIBUTE_HIDDEN #endif #if defined(__GNUC__) #define ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) #elif defined(_MSC_VER) #define ATTRIBUTE_ALWAYS_INLINE __forceinline #else #define ATTRIBUTE_ALWAYS_INLINE #endif // The following enum should be used only as a constructor argument to indicate // that the variable has static storage class, and that the constructor should // do nothing to its state. It indicates to the reader that it is legal to // declare a static nistance of the class, provided the constructor is given // the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a // static variable that has a constructor or a destructor because invocation // order is undefined. However, IF the type can be initialized by filling with // zeroes (which the loader does for static variables), AND the destructor also // does nothing to the storage, then a constructor declared as // explicit MyClass(base::LinkerInitialized x) {} // and invoked as // static MyClass my_variable_name(base::LINKER_INITIALIZED); namespace base { enum LinkerInitialized { LINKER_INITIALIZED }; } #endif // _BASICTYPES_H_