X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FPortability.h;h=fbd8e3aba8786fab5297c0073e5fa5b459c1df0e;hb=b7a982a8f0e04cd4940ed31fa31529b1a94ad1c6;hp=ccd90380001c7d108230362238eef08549c4d011;hpb=ce4dec4c322aee6b9905be54bb67956d76270b65;p=folly.git diff --git a/folly/Portability.h b/folly/Portability.h index ccd90380..fbd8e3ab 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -1,5 +1,5 @@ /* - * Copyright 2013 Facebook, Inc. + * Copyright 2015 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,27 +17,290 @@ #ifndef FOLLY_PORTABILITY_H_ #define FOLLY_PORTABILITY_H_ -#include "folly-config.h" +#ifndef FOLLY_NO_CONFIG +#include +#endif + +#ifdef FOLLY_PLATFORM_CONFIG +#include FOLLY_PLATFORM_CONFIG +#endif + +#if FOLLY_HAVE_FEATURES_H +#include +#endif -#ifdef FOLLY_HAVE_SCHED_H +#include + +#ifdef __APPLE__ +# include +#endif + +#if FOLLY_HAVE_SCHED_H #include #ifndef FOLLY_HAVE_PTHREAD_YIELD #define pthread_yield sched_yield #endif #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 +#endif // MaxAlign: max_align_t isn't supported by gcc #ifdef __GNUC__ -struct MaxAlign { char c; } __attribute__((aligned)); +struct MaxAlign { char c; } __attribute__((__aligned__)); #else /* !__GNUC__ */ # error Cannot define MaxAlign on this platform #endif +// compiler specific attribute translation +// msvc should come first, so if clang is in msvc mode it gets the right defines + +// NOTE: this will only do checking in msvc with versions that support /analyze +#if _MSC_VER +# ifdef _USE_ATTRIBUTES_FOR_SAL +# undef _USE_ATTRIBUTES_FOR_SAL +# endif +/* nolint */ +# define _USE_ATTRIBUTES_FOR_SAL 1 +# include +# define FOLLY_PRINTF_FORMAT _Printf_format_string_ +# define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) /**/ +#else +# define FOLLY_PRINTF_FORMAT /**/ +# define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) \ + __attribute__((__format__(__printf__, format_param, dots_param))) +#endif + +// deprecated #if defined(__clang__) || defined(__GNUC__) -# define FOLLY_NORETURN __attribute__((noreturn)) +# define FOLLY_DEPRECATED(msg) __attribute__((__deprecated__(msg))) +#else +# define FOLLY_DEPRECATED +#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 #endif +// noinline +#ifdef _MSC_VER +# define FOLLY_NOINLINE __declspec(noinline) +#elif defined(__clang__) || defined(__GNUC__) +# define FOLLY_NOINLINE __attribute__((__noinline__)) +#else +# define FOLLY_NOINLINE +#endif + +// always inline +#ifdef _MSC_VER +# define FOLLY_ALWAYS_INLINE __forceinline +#elif defined(__clang__) || defined(__GNUC__) +# define FOLLY_ALWAYS_INLINE inline __attribute__((__always_inline__)) +#else +# define FOLLY_ALWAYS_INLINE +#endif + +// detection for 64 bit +#if defined(__x86_64__) || defined(_M_X64) +# define FOLLY_X64 1 +#else +# define FOLLY_X64 0 +#endif + +#if defined(__aarch64__) +# define FOLLY_A64 1 +#else +# define FOLLY_A64 0 +#endif + +// packing is very ugly in msvc +#ifdef _MSC_VER +# define FOLLY_PACK_ATTR /**/ +# define FOLLY_PACK_PUSH __pragma(pack(push, 1)) +# define FOLLY_PACK_POP __pragma(pack(pop)) +#elif defined(__clang__) || defined(__GNUC__) +# define FOLLY_PACK_ATTR __attribute__((__packed__)) +# define FOLLY_PACK_PUSH /**/ +# define FOLLY_PACK_POP /**/ +#else +# define FOLLY_PACK_ATTR /**/ +# define FOLLY_PACK_PUSH /**/ +# define FOLLY_PACK_POP /**/ +#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 +#endif + + +/* Define macro wrappers for C++11's "final" and "override" keywords, which + * are supported in gcc 4.7 but not gcc 4.6. */ +#if !defined(FOLLY_FINAL) && !defined(FOLLY_OVERRIDE) +# if defined(__clang__) || __GNUC_PREREQ(4, 7) +# define FOLLY_FINAL final +# define FOLLY_OVERRIDE override +# else +# define FOLLY_FINAL /**/ +# define FOLLY_OVERRIDE /**/ +# endif +#endif + +/* Platform specific TLS support + * gcc implements __thread + * msvc implements __declspec(thread) + * the semantics are the same + * (but remember __thread has different semantics when using emutls (ex. apple)) + */ +#if defined(_MSC_VER) +# define FOLLY_TLS __declspec(thread) +#elif defined(__GNUC__) || defined(__clang__) +# define FOLLY_TLS __thread +#else +# error cannot define platform specific thread local storage +#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 namepsaces. Wrap this decision +// up in a macro to make forward-declarations easier. +#if FOLLY_USE_LIBCPP +#include <__config> +#define FOLLY_NAMESPACE_STD_BEGIN _LIBCPP_BEGIN_NAMESPACE_STD +#define FOLLY_NAMESPACE_STD_END _LIBCPP_END_NAMESPACE_STD +#else +#define FOLLY_NAMESPACE_STD_BEGIN namespace std { +#define FOLLY_NAMESPACE_STD_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) + +// compiler specific to compiler specific +// nolint +# define __PRETTY_FUNCTION__ __FUNCSIG__ +#endif + +#if FOLLY_UNUSUAL_GFLAGS_NAMESPACE +namespace FOLLY_GFLAGS_NAMESPACE { } +namespace gflags { +using namespace FOLLY_GFLAGS_NAMESPACE; +} // namespace gflags +#endif + +// for TARGET_OS_IPHONE +#ifdef __APPLE__ +#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) +# define FOLLY_HAS_RTTI 1 +#endif + +namespace folly { + +inline void asm_volatile_pause() { +#if defined(__i386__) || FOLLY_X64 + asm volatile ("pause"); +#elif FOLLY_A64 + asm volatile ("wfe"); +#endif +} +inline void asm_pause() { +#if defined(__i386__) || FOLLY_X64 + asm ("pause"); +#elif FOLLY_A64 + asm ("wfe"); +#endif +} + +} + #endif // FOLLY_PORTABILITY_H_