X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FPortability.h;h=7b822cda2d60da1fe3849b32f4d7de09554d7ea8;hb=cd201c86411f960e6e63c8222a334cea5ed67768;hp=0e9c471b1f13ff1bf7fc55f03cbcafb743df80fe;hpb=eeb13d00be50f10535ce2868a80ba5a20dbcbee0;p=folly.git diff --git a/folly/Portability.h b/folly/Portability.h index 0e9c471b..7b822cda 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,54 +14,24 @@ * limitations under the License. */ -#ifndef FOLLY_PORTABILITY_H_ -#define FOLLY_PORTABILITY_H_ - -// @nocommit invalidate ccache 20151125 (see #8764509) +#pragma once #include #include -#ifndef FOLLY_NO_CONFIG -#include -#endif - -#ifdef FOLLY_PLATFORM_CONFIG -#include FOLLY_PLATFORM_CONFIG -#endif - -#if FOLLY_HAVE_FEATURES_H -#include -#endif +#include #include -#ifdef __APPLE__ -# include -#endif - -#if FOLLY_HAVE_SCHED_H - #include - #ifndef FOLLY_HAVE_PTHREAD_YIELD - #define pthread_yield sched_yield - #endif -#endif - -#ifndef FOLLY_HAVE_UNALIGNED_READS -#define FOLLY_HAVE_UNALIGNED_READS 0 -#endif - -// A change in folly/MemoryMapping.cpp uses MAP_ANONYMOUS, which is named -// MAP_ANON on OSX/BSD. -#if defined(__APPLE__) || defined(__FreeBSD__) - #include - #ifndef MAP_ANONYMOUS - #ifdef MAP_ANON - #define MAP_ANONYMOUS MAP_ANON - #endif - #endif +// Unaligned loads and stores +namespace folly { +#if FOLLY_HAVE_UNALIGNED_ACCESS +constexpr bool kHasUnalignedAccess = true; +#else +constexpr bool kHasUnalignedAccess = false; #endif +} // compiler specific attribute translation // msvc should come first, so if clang is in msvc mode it gets the right defines @@ -100,31 +70,27 @@ # define FOLLY_DEPRECATED(msg) #endif -// noreturn -#if defined(_MSC_VER) -# define FOLLY_NORETURN __declspec(noreturn) -#elif defined(__clang__) || defined(__GNUC__) -# define FOLLY_NORETURN __attribute__((__noreturn__)) -#else -# define FOLLY_NORETURN +// warn unused result +#if defined(__has_cpp_attribute) +#if __has_cpp_attribute(nodiscard) +#define FOLLY_NODISCARD [[nodiscard]] #endif - -// noinline -#ifdef _MSC_VER -# define FOLLY_NOINLINE __declspec(noinline) +#endif +#if !defined FOLLY_NODISCARD +#if defined(_MSC_VER) && (_MSC_VER >= 1700) +#define FOLLY_NODISCARD _Check_return_ #elif defined(__clang__) || defined(__GNUC__) -# define FOLLY_NOINLINE __attribute__((__noinline__)) +#define FOLLY_NODISCARD __attribute__((__warn_unused_result__)) #else -# define FOLLY_NOINLINE +#define FOLLY_NODISCARD +#endif #endif -// always inline +// target #ifdef _MSC_VER -# define FOLLY_ALWAYS_INLINE __forceinline -#elif defined(__clang__) || defined(__GNUC__) -# define FOLLY_ALWAYS_INLINE inline __attribute__((__always_inline__)) +# define FOLLY_TARGET_ATTRIBUTE(target) #else -# define FOLLY_ALWAYS_INLINE inline +# define FOLLY_TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) #endif // detection for 64 bit @@ -146,6 +112,27 @@ # define FOLLY_PPC64 0 #endif +namespace folly { +constexpr bool kIsArchAmd64 = FOLLY_X64 == 1; +constexpr bool kIsArchAArch64 = FOLLY_A64 == 1; +constexpr bool kIsArchPPC64 = FOLLY_PPC64 == 1; +} + +namespace folly { + +#if FOLLY_SANITIZE_ADDRESS +constexpr bool kIsSanitizeAddress = true; +#else +constexpr bool kIsSanitizeAddress = false; +#endif + +#if FOLLY_SANITIZE_THREAD +constexpr bool kIsSanitizeThread = true; +#else +constexpr bool kIsSanitizeThread = false; +#endif +} + // packing is very ugly in msvc #ifdef _MSC_VER # define FOLLY_PACK_ATTR /**/ @@ -171,12 +158,10 @@ #elif defined(__clang__) || defined(__GNUC__) # define FOLLY_PUSH_WARNING _Pragma("GCC diagnostic push") # define FOLLY_POP_WARNING _Pragma("GCC diagnostic pop") -#define FOLLY_GCC_DISABLE_WARNING_INTERNAL3(warningName) #warningName -#define FOLLY_GCC_DISABLE_WARNING_INTERNAL2(warningName) \ - FOLLY_GCC_DISABLE_WARNING_INTERNAL3(warningName) -#define FOLLY_GCC_DISABLE_WARNING(warningName) \ - _Pragma(FOLLY_GCC_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored \ - FOLLY_GCC_DISABLE_WARNING_INTERNAL3(-W##warningName))) +# define FOLLY_GCC_DISABLE_WARNING_INTERNAL2(warningName) #warningName +# define FOLLY_GCC_DISABLE_WARNING(warningName) \ + _Pragma( \ + FOLLY_GCC_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored warningName)) // Disable the MSVC warnings. # define FOLLY_MSVC_DISABLE_WARNING(warningNumber) #else @@ -186,16 +171,12 @@ # define FOLLY_MSVC_DISABLE_WARNING(warningNumber) #endif -// portable version check -#ifndef __GNUC_PREREQ -# if defined __GNUC__ && defined __GNUC_MINOR__ -/* nolint */ -# define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= \ - ((maj) << 16) + (min)) -# else -/* nolint */ -# define __GNUC_PREREQ(maj, min) 0 -# endif +#ifdef HAVE_SHADOW_LOCAL_WARNINGS +#define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS \ + FOLLY_GCC_DISABLE_WARNING("-Wshadow-compatible-local") \ + FOLLY_GCC_DISABLE_WARNING("-Wshadow-local") +#else +#define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS /* empty */ #endif #if defined(__GNUC__) && !defined(__APPLE__) && !__GNUC_PREREQ(4,9) @@ -231,20 +212,10 @@ namespace std { typedef ::max_align_t max_align_t; } # error cannot define platform specific thread local storage #endif -#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE +#if FOLLY_MOBILE #undef FOLLY_TLS #endif -// Define to 1 if you have the `preadv' and `pwritev' functions, respectively -#if !defined(FOLLY_HAVE_PREADV) && !defined(FOLLY_HAVE_PWRITEV) -# if defined(__GLIBC_PREREQ) -# if __GLIBC_PREREQ(2, 10) -# define FOLLY_HAVE_PREADV 1 -# define FOLLY_HAVE_PWRITEV 1 -# endif -# endif -#endif - // It turns out that GNU libstdc++ and LLVM libc++ differ on how they implement // the 'std' namespace; the latter uses inline namespaces. Wrap this decision // up in a macro to make forward-declarations easier. @@ -260,65 +231,18 @@ namespace std { typedef ::max_align_t max_align_t; } // If the new c++ ABI is used, __cxx11 inline namespace needs to be added to // some types, e.g. std::list. #if _GLIBCXX_USE_CXX11_ABI -# define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN _GLIBCXX_BEGIN_NAMESPACE_CXX11 +#define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN \ + inline _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define FOLLY_GLIBCXX_NAMESPACE_CXX11_END _GLIBCXX_END_NAMESPACE_CXX11 #else # define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN # define FOLLY_GLIBCXX_NAMESPACE_CXX11_END #endif -// Some platforms lack clock_gettime(2) and clock_getres(2). Inject our own -// versions of these into the global namespace. -#if FOLLY_HAVE_CLOCK_GETTIME -#include -#else -#include -#endif - -// Provide our own std::__throw_* wrappers for platforms that don't have them -#if FOLLY_HAVE_BITS_FUNCTEXCEPT_H -#include -#else -#include -#endif - -#if defined(__cplusplus) -// Unfortunately, boost::has_trivial_copy is broken in libc++ due to its -// usage of __has_trivial_copy(), so we can't use it as a -// least-common-denominator for C++11 implementations that don't support -// std::is_trivially_copyable. -// -// http://stackoverflow.com/questions/12754886/has-trivial-copy-behaves-differently-in-clang-and-gcc-whos-right -// -// As a result, use std::is_trivially_copyable() where it exists, and fall back -// to Boost otherwise. -#if FOLLY_HAVE_STD__IS_TRIVIALLY_COPYABLE -#include -#define FOLLY_IS_TRIVIALLY_COPYABLE(T) \ - (std::is_trivially_copyable::value) -#else -#include -#define FOLLY_IS_TRIVIALLY_COPYABLE(T) \ - (boost::has_trivial_copy::value && \ - boost::has_trivial_destructor::value) -#endif -#endif // __cplusplus - // MSVC specific defines // mainly for posix compat #ifdef _MSC_VER - -// this definition is in a really silly place with a silly name -// and ifdefing it every time we want it is painful -#include -typedef SSIZE_T ssize_t; - -// sprintf semantics are not exactly identical -// but current usage is not a problem -# define snprintf _snprintf - -// semantics here are identical -# define strerror_r(errno,buf,len) strerror_s(buf,len,errno) +#include // compiler specific to compiler specific // nolint @@ -327,12 +251,20 @@ typedef SSIZE_T ssize_t; // Hide a GCC specific thing that breaks MSVC if left alone. # define __extension__ -#ifdef _M_IX86_FP -# define FOLLY_SSE _M_IX86_FP -# define FOLLY_SSE_MINOR 0 +// We have compiler support for the newest of the new, but +// MSVC doesn't tell us that. +#define __SSE4_2__ 1 + #endif +// Debug +namespace folly { +#ifdef NDEBUG +constexpr auto kIsDebug = false; +#else +constexpr auto kIsDebug = true; #endif +} // Endianness namespace folly { @@ -389,72 +321,38 @@ using namespace FOLLY_GFLAGS_NAMESPACE; #include #endif -// MacOS doesn't have malloc_usable_size() -#if defined(__APPLE__) && !defined(FOLLY_HAVE_MALLOC_USABLE_SIZE) -inline size_t malloc_usable_size(void* ptr) { - return malloc_size(ptr); -} -#endif - // RTTI may not be enabled for this compilation unit. #if defined(__GXX_RTTI) || defined(__cpp_rtti) || \ (defined(_MSC_VER) && defined(_CPPRTTI)) # define FOLLY_HAS_RTTI 1 #endif -#ifdef _MSC_VER -# include +#if defined(__APPLE__) || defined(_MSC_VER) +#define FOLLY_STATIC_CTOR_PRIORITY_MAX +#else +// 101 is the highest priority allowed by the init_priority attribute. +// This priority is already used by JEMalloc and other memory allocators so +// we will take the next one. +#define FOLLY_STATIC_CTOR_PRIORITY_MAX __attribute__((__init_priority__(102))) #endif namespace folly { -inline void asm_volatile_memory() { -#if defined(__clang__) || defined(__GNUC__) - asm volatile("" : : : "memory"); -#elif defined(_MSC_VER) - ::_ReadWriteBarrier(); -#endif -} - -inline void asm_volatile_pause() { -#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) - ::_mm_pause(); -#elif defined(__i386__) || FOLLY_X64 - asm volatile ("pause"); -#elif FOLLY_A64 - asm volatile ("wfe"); -#elif FOLLY_PPC64 - asm volatile("or 27,27,27"); -#endif -} -inline void asm_pause() { -#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) - ::_mm_pause(); -#elif defined(__i386__) || FOLLY_X64 - asm ("pause"); -#elif FOLLY_A64 - asm ("wfe"); -#elif FOLLY_PPC64 - asm ("or 31,31,31"); +#if __OBJC__ +constexpr auto kIsObjC = true; +#else +constexpr auto kIsObjC = false; #endif -} -constexpr size_t constexpr_strlen(const char* s) { -#if defined(__clang__) - return __builtin_strlen(s); +#if defined(__linux__) && !FOLLY_MOBILE +constexpr auto kIsLinux = true; #else - return strlen(s); +constexpr auto kIsLinux = false; #endif -} -#if defined(__APPLE__) || defined(_MSC_VER) -#define MAX_STATIC_CONSTRUCTOR_PRIORITY +#if defined(_WIN32) +constexpr auto kIsWindows = true; #else -// 101 is the highest priority allowed by the init_priority attribute. -// This priority is already used by JEMalloc and other memory allocators so -// we will take the next one. -#define MAX_STATIC_CONSTRUCTOR_PRIORITY __attribute__ ((__init_priority__(102))) +constexpr auto kIsWindows = false; #endif - -} // namespace folly -#endif // FOLLY_PORTABILITY_H_ +}