123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- // -*- 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 <config.h>
- #include <string.h> // for memcpy()
- #ifdef HAVE_INTTYPES_H
- #include <inttypes.h> // 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 <inttypes.h> // uint16_t might be here; PRId64 too.
- #endif
- #ifdef HAVE_STDINT_H
- #include <stdint.h> // to get uint16_t (ISO naming madness)
- #endif
- #include <sys/types.h> // 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<uintptr_t>(pthreadt)
- #else
- #define PRINTABLE_PTHREAD(pthreadt) pthreadt
- #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<bool(expr)>
- //
- // 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 <bool>
- struct CompileAssert {
- };
- #ifdef HAVE___ATTRIBUTE__
- # define ATTRIBUTE_UNUSED __attribute__((unused))
- #else
- # define ATTRIBUTE_UNUSED
- #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<char*>(&reinterpret_cast<strct*>(16)->field) - \
- reinterpret_cast<char*>(16))
- // bit_cast<Dest,Source> implements the equivalent of
- // "*reinterpret_cast<Dest*>(&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 <class Dest, class Source>
- 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;
- }
- #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)))
- // 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<void*>(__start_##name))
- # define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
- # define HAVE_ATTRIBUTE_SECTION_START 1
- #elif defined(HAVE___ATTRIBUTE__) && defined(__MACH__)
- # define ATTRIBUTE_SECTION(name) __attribute__ ((section ("__TEXT, " #name)))
- #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
- 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<void*>(__start_##name))
- # define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__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<void*>(0))
- # define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(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(__s390x__))
- # define CACHELINE_ALIGNED __attribute__((aligned(256)))
- # else
- # error Could not determine cache line length - unknown architecture
- # endif
- #else
- # define CACHELINE_ALIGNED
- #endif // defined(HAVE___ATTRIBUTE__) && (__i386__ || __x86_64__)
- // Structure for discovering alignment
- union MemoryAligner {
- void* p;
- double d;
- size_t s;
- } CACHELINE_ALIGNED;
- // 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_
|