mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 09:32:06 +00:00
Merge pull request #4995 from danlark1/master
LFAlloc added to clickhouse to allocate MarkCache and UncompressedCache data in different ways
This commit is contained in:
commit
e346758cea
@ -317,6 +317,7 @@ include (cmake/find_hdfs3.cmake) # uses protobuf
|
|||||||
include (cmake/find_consistent-hashing.cmake)
|
include (cmake/find_consistent-hashing.cmake)
|
||||||
include (cmake/find_base64.cmake)
|
include (cmake/find_base64.cmake)
|
||||||
include (cmake/find_hyperscan.cmake)
|
include (cmake/find_hyperscan.cmake)
|
||||||
|
include (cmake/find_lfalloc.cmake)
|
||||||
find_contrib_lib(cityhash)
|
find_contrib_lib(cityhash)
|
||||||
find_contrib_lib(farmhash)
|
find_contrib_lib(farmhash)
|
||||||
find_contrib_lib(metrohash)
|
find_contrib_lib(metrohash)
|
||||||
|
9
cmake/find_lfalloc.cmake
Normal file
9
cmake/find_lfalloc.cmake
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
if (NOT SANITIZE AND NOT ARCH_ARM AND NOT ARCH_32 AND NOT ARCH_PPC64LE)
|
||||||
|
if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/lfalloc/src/lf_allocX64.h")
|
||||||
|
message (FATAL_ERROR "submodule contrib/lfalloc is missing. to fix try run: \n git submodule update --init --recursive")
|
||||||
|
endif()
|
||||||
|
set (USE_LFALLOC 1)
|
||||||
|
set (USE_LFALLOC_RANDOM_HINT 1)
|
||||||
|
set (LFALLOC_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/lfalloc/src)
|
||||||
|
message (STATUS "Using lfalloc=${USE_LFALLOC}: ${LFALLOC_INCLUDE_DIR}")
|
||||||
|
endif ()
|
1813
contrib/lfalloc/src/lf_allocX64.h
Normal file
1813
contrib/lfalloc/src/lf_allocX64.h
Normal file
File diff suppressed because it is too large
Load Diff
23
contrib/lfalloc/src/lfmalloc.h
Normal file
23
contrib/lfalloc/src/lfmalloc.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util/system/compiler.h"
|
||||||
|
|
||||||
|
namespace NMalloc {
|
||||||
|
volatile inline bool IsAllocatorCorrupted = false;
|
||||||
|
|
||||||
|
static inline void AbortFromCorruptedAllocator() {
|
||||||
|
IsAllocatorCorrupted = true;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TAllocHeader {
|
||||||
|
void* Block;
|
||||||
|
size_t AllocSize;
|
||||||
|
void Y_FORCE_INLINE Encode(void* block, size_t size, size_t signature) {
|
||||||
|
Block = block;
|
||||||
|
AllocSize = size | signature;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
33
contrib/lfalloc/src/util/README.md
Normal file
33
contrib/lfalloc/src/util/README.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
Style guide for the util folder is a stricter version of general style guide (mostly in terms of ambiguity resolution).
|
||||||
|
|
||||||
|
* all {} must be in K&R style
|
||||||
|
* &, * tied closer to a type, not to variable
|
||||||
|
* always use `using` not `typedef`
|
||||||
|
* even a single line block must be in braces {}:
|
||||||
|
```
|
||||||
|
if (A) {
|
||||||
|
B();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
* _ at the end of private data member of a class - `First_`, `Second_`
|
||||||
|
* every .h file must be accompanied with corresponding .cpp to avoid a leakage and check that it is self contained
|
||||||
|
* prohibited to use `printf`-like functions
|
||||||
|
|
||||||
|
|
||||||
|
Things declared in the general style guide, which sometimes are missed:
|
||||||
|
|
||||||
|
* `template <`, not `template<`
|
||||||
|
* `noexcept`, not `throw ()` nor `throw()`, not required for destructors
|
||||||
|
* indents inside `namespace` same as inside `class`
|
||||||
|
|
||||||
|
|
||||||
|
Requirements for a new code (and for corrections in an old code which involves change of behaviour) in util:
|
||||||
|
|
||||||
|
* presence of UNIT-tests
|
||||||
|
* presence of comments in Doxygen style
|
||||||
|
* accessors without Get prefix (`Length()`, but not `GetLength()`)
|
||||||
|
|
||||||
|
This guide is not a mandatory as there is the general style guide.
|
||||||
|
Nevertheless if it is not followed, then a next `ya style .` run in the util folder will undeservedly update authors of some lines of code.
|
||||||
|
|
||||||
|
Thus before a commit it is recommended to run `ya style .` in the util folder.
|
51
contrib/lfalloc/src/util/system/atomic.h
Normal file
51
contrib/lfalloc/src/util/system/atomic.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "defaults.h"
|
||||||
|
|
||||||
|
using TAtomicBase = intptr_t;
|
||||||
|
using TAtomic = volatile TAtomicBase;
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#include "atomic_gcc.h"
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#include "atomic_win.h"
|
||||||
|
#else
|
||||||
|
#error unsupported platform
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ATOMIC_COMPILER_BARRIER)
|
||||||
|
#define ATOMIC_COMPILER_BARRIER()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline TAtomicBase AtomicSub(TAtomic& a, TAtomicBase v) {
|
||||||
|
return AtomicAdd(a, -v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TAtomicBase AtomicGetAndSub(TAtomic& a, TAtomicBase v) {
|
||||||
|
return AtomicGetAndAdd(a, -v);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(USE_GENERIC_SETGET)
|
||||||
|
static inline TAtomicBase AtomicGet(const TAtomic& a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void AtomicSet(TAtomic& a, TAtomicBase v) {
|
||||||
|
a = v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline bool AtomicTryLock(TAtomic* a) {
|
||||||
|
return AtomicCas(a, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool AtomicTryAndTryLock(TAtomic* a) {
|
||||||
|
return (AtomicGet(*a) == 0) && AtomicTryLock(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void AtomicUnlock(TAtomic* a) {
|
||||||
|
ATOMIC_COMPILER_BARRIER();
|
||||||
|
AtomicSet(*a, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "atomic_ops.h"
|
90
contrib/lfalloc/src/util/system/atomic_gcc.h
Normal file
90
contrib/lfalloc/src/util/system/atomic_gcc.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ATOMIC_COMPILER_BARRIER() __asm__ __volatile__("" \
|
||||||
|
: \
|
||||||
|
: \
|
||||||
|
: "memory")
|
||||||
|
|
||||||
|
static inline TAtomicBase AtomicGet(const TAtomic& a) {
|
||||||
|
TAtomicBase tmp;
|
||||||
|
#if defined(_arm64_)
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"ldar %x[value], %[ptr] \n\t"
|
||||||
|
: [value] "=r"(tmp)
|
||||||
|
: [ptr] "Q"(a)
|
||||||
|
: "memory");
|
||||||
|
#else
|
||||||
|
__atomic_load(&a, &tmp, __ATOMIC_ACQUIRE);
|
||||||
|
#endif
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void AtomicSet(TAtomic& a, TAtomicBase v) {
|
||||||
|
#if defined(_arm64_)
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"stlr %x[value], %[ptr] \n\t"
|
||||||
|
: [ptr] "=Q"(a)
|
||||||
|
: [value] "r"(v)
|
||||||
|
: "memory");
|
||||||
|
#else
|
||||||
|
__atomic_store(&a, &v, __ATOMIC_RELEASE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicIncrement(TAtomic& p) {
|
||||||
|
return __atomic_add_fetch(&p, 1, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndIncrement(TAtomic& p) {
|
||||||
|
return __atomic_fetch_add(&p, 1, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicDecrement(TAtomic& p) {
|
||||||
|
return __atomic_sub_fetch(&p, 1, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndDecrement(TAtomic& p) {
|
||||||
|
return __atomic_fetch_sub(&p, 1, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicAdd(TAtomic& p, intptr_t v) {
|
||||||
|
return __atomic_add_fetch(&p, v, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndAdd(TAtomic& p, intptr_t v) {
|
||||||
|
return __atomic_fetch_add(&p, v, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicSwap(TAtomic* p, intptr_t v) {
|
||||||
|
(void)p; // disable strange 'parameter set but not used' warning on gcc
|
||||||
|
intptr_t ret;
|
||||||
|
__atomic_exchange(p, &v, &ret, __ATOMIC_SEQ_CST);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool AtomicCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
|
||||||
|
(void)a; // disable strange 'parameter set but not used' warning on gcc
|
||||||
|
return __atomic_compare_exchange(a, &compare, &exchange, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
|
||||||
|
(void)a; // disable strange 'parameter set but not used' warning on gcc
|
||||||
|
__atomic_compare_exchange(a, &compare, &exchange, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicOr(TAtomic& a, intptr_t b) {
|
||||||
|
return __atomic_or_fetch(&a, b, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicXor(TAtomic& a, intptr_t b) {
|
||||||
|
return __atomic_xor_fetch(&a, b, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicAnd(TAtomic& a, intptr_t b) {
|
||||||
|
return __atomic_and_fetch(&a, b, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void AtomicBarrier() {
|
||||||
|
__sync_synchronize();
|
||||||
|
}
|
189
contrib/lfalloc/src/util/system/atomic_ops.h
Normal file
189
contrib/lfalloc/src/util/system/atomic_ops.h
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TAtomic* AsAtomicPtr(T volatile* target) {
|
||||||
|
return reinterpret_cast<TAtomic*>(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline const TAtomic* AsAtomicPtr(T const volatile* target) {
|
||||||
|
return reinterpret_cast<const TAtomic*>(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
// integral types
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct TAtomicTraits {
|
||||||
|
enum {
|
||||||
|
Castable = std::is_integral<T>::value && sizeof(T) == sizeof(TAtomicBase) && !std::is_const<T>::value,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename TT>
|
||||||
|
using TEnableIfCastable = std::enable_if_t<TAtomicTraits<T>::Castable, TT>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicGet(T const volatile& target) {
|
||||||
|
return static_cast<T>(AtomicGet(*AsAtomicPtr(&target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, void> AtomicSet(T volatile& target, TAtomicBase value) {
|
||||||
|
AtomicSet(*AsAtomicPtr(&target), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicIncrement(T volatile& target) {
|
||||||
|
return static_cast<T>(AtomicIncrement(*AsAtomicPtr(&target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicGetAndIncrement(T volatile& target) {
|
||||||
|
return static_cast<T>(AtomicGetAndIncrement(*AsAtomicPtr(&target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicDecrement(T volatile& target) {
|
||||||
|
return static_cast<T>(AtomicDecrement(*AsAtomicPtr(&target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicGetAndDecrement(T volatile& target) {
|
||||||
|
return static_cast<T>(AtomicGetAndDecrement(*AsAtomicPtr(&target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicAdd(T volatile& target, TAtomicBase value) {
|
||||||
|
return static_cast<T>(AtomicAdd(*AsAtomicPtr(&target), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicGetAndAdd(T volatile& target, TAtomicBase value) {
|
||||||
|
return static_cast<T>(AtomicGetAndAdd(*AsAtomicPtr(&target), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicSub(T volatile& target, TAtomicBase value) {
|
||||||
|
return static_cast<T>(AtomicSub(*AsAtomicPtr(&target), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicGetAndSub(T volatile& target, TAtomicBase value) {
|
||||||
|
return static_cast<T>(AtomicGetAndSub(*AsAtomicPtr(&target), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicSwap(T volatile* target, TAtomicBase exchange) {
|
||||||
|
return static_cast<T>(AtomicSwap(AsAtomicPtr(target), exchange));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, bool> AtomicCas(T volatile* target, TAtomicBase exchange, TAtomicBase compare) {
|
||||||
|
return AtomicCas(AsAtomicPtr(target), exchange, compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicGetAndCas(T volatile* target, TAtomicBase exchange, TAtomicBase compare) {
|
||||||
|
return static_cast<T>(AtomicGetAndCas(AsAtomicPtr(target), exchange, compare));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, bool> AtomicTryLock(T volatile* target) {
|
||||||
|
return AtomicTryLock(AsAtomicPtr(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, bool> AtomicTryAndTryLock(T volatile* target) {
|
||||||
|
return AtomicTryAndTryLock(AsAtomicPtr(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, void> AtomicUnlock(T volatile* target) {
|
||||||
|
AtomicUnlock(AsAtomicPtr(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicOr(T volatile& target, TAtomicBase value) {
|
||||||
|
return static_cast<T>(AtomicOr(*AsAtomicPtr(&target), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicAnd(T volatile& target, TAtomicBase value) {
|
||||||
|
return static_cast<T>(AtomicAnd(*AsAtomicPtr(&target), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline TEnableIfCastable<T, T> AtomicXor(T volatile& target, TAtomicBase value) {
|
||||||
|
return static_cast<T>(AtomicXor(*AsAtomicPtr(&target), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointer types
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* AtomicGet(T* const volatile& target) {
|
||||||
|
return reinterpret_cast<T*>(AtomicGet(*AsAtomicPtr(&target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void AtomicSet(T* volatile& target, T* value) {
|
||||||
|
AtomicSet(*AsAtomicPtr(&target), reinterpret_cast<TAtomicBase>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
using TNullPtr = decltype(nullptr);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void AtomicSet(T* volatile& target, TNullPtr) {
|
||||||
|
AtomicSet(*AsAtomicPtr(&target), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* AtomicSwap(T* volatile* target, T* exchange) {
|
||||||
|
return reinterpret_cast<T*>(AtomicSwap(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* AtomicSwap(T* volatile* target, TNullPtr) {
|
||||||
|
return reinterpret_cast<T*>(AtomicSwap(AsAtomicPtr(target), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool AtomicCas(T* volatile* target, T* exchange, T* compare) {
|
||||||
|
return AtomicCas(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange), reinterpret_cast<TAtomicBase>(compare));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* AtomicGetAndCas(T* volatile* target, T* exchange, T* compare) {
|
||||||
|
return reinterpret_cast<T*>(AtomicGetAndCas(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange), reinterpret_cast<TAtomicBase>(compare)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool AtomicCas(T* volatile* target, T* exchange, TNullPtr) {
|
||||||
|
return AtomicCas(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* AtomicGetAndCas(T* volatile* target, T* exchange, TNullPtr) {
|
||||||
|
return reinterpret_cast<T*>(AtomicGetAndCas(AsAtomicPtr(target), reinterpret_cast<TAtomicBase>(exchange), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool AtomicCas(T* volatile* target, TNullPtr, T* compare) {
|
||||||
|
return AtomicCas(AsAtomicPtr(target), 0, reinterpret_cast<TAtomicBase>(compare));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* AtomicGetAndCas(T* volatile* target, TNullPtr, T* compare) {
|
||||||
|
return reinterpret_cast<T*>(AtomicGetAndCas(AsAtomicPtr(target), 0, reinterpret_cast<TAtomicBase>(compare)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool AtomicCas(T* volatile* target, TNullPtr, TNullPtr) {
|
||||||
|
return AtomicCas(AsAtomicPtr(target), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T* AtomicGetAndCas(T* volatile* target, TNullPtr, TNullPtr) {
|
||||||
|
return reinterpret_cast<T*>(AtomicGetAndCas(AsAtomicPtr(target), 0, 0));
|
||||||
|
}
|
114
contrib/lfalloc/src/util/system/atomic_win.h
Normal file
114
contrib/lfalloc/src/util/system/atomic_win.h
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <intrin.h>
|
||||||
|
|
||||||
|
#define USE_GENERIC_SETGET
|
||||||
|
|
||||||
|
#if defined(_i386_)
|
||||||
|
|
||||||
|
#pragma intrinsic(_InterlockedIncrement)
|
||||||
|
#pragma intrinsic(_InterlockedDecrement)
|
||||||
|
#pragma intrinsic(_InterlockedExchangeAdd)
|
||||||
|
#pragma intrinsic(_InterlockedExchange)
|
||||||
|
#pragma intrinsic(_InterlockedCompareExchange)
|
||||||
|
|
||||||
|
static inline intptr_t AtomicIncrement(TAtomic& a) {
|
||||||
|
return _InterlockedIncrement((volatile long*)&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndIncrement(TAtomic& a) {
|
||||||
|
return _InterlockedIncrement((volatile long*)&a) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicDecrement(TAtomic& a) {
|
||||||
|
return _InterlockedDecrement((volatile long*)&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndDecrement(TAtomic& a) {
|
||||||
|
return _InterlockedDecrement((volatile long*)&a) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicAdd(TAtomic& a, intptr_t b) {
|
||||||
|
return _InterlockedExchangeAdd((volatile long*)&a, b) + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndAdd(TAtomic& a, intptr_t b) {
|
||||||
|
return _InterlockedExchangeAdd((volatile long*)&a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicSwap(TAtomic* a, intptr_t b) {
|
||||||
|
return _InterlockedExchange((volatile long*)a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool AtomicCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
|
||||||
|
return _InterlockedCompareExchange((volatile long*)a, exchange, compare) == compare;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
|
||||||
|
return _InterlockedCompareExchange((volatile long*)a, exchange, compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // _x86_64_
|
||||||
|
|
||||||
|
#pragma intrinsic(_InterlockedIncrement64)
|
||||||
|
#pragma intrinsic(_InterlockedDecrement64)
|
||||||
|
#pragma intrinsic(_InterlockedExchangeAdd64)
|
||||||
|
#pragma intrinsic(_InterlockedExchange64)
|
||||||
|
#pragma intrinsic(_InterlockedCompareExchange64)
|
||||||
|
|
||||||
|
static inline intptr_t AtomicIncrement(TAtomic& a) {
|
||||||
|
return _InterlockedIncrement64((volatile __int64*)&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndIncrement(TAtomic& a) {
|
||||||
|
return _InterlockedIncrement64((volatile __int64*)&a) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicDecrement(TAtomic& a) {
|
||||||
|
return _InterlockedDecrement64((volatile __int64*)&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndDecrement(TAtomic& a) {
|
||||||
|
return _InterlockedDecrement64((volatile __int64*)&a) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicAdd(TAtomic& a, intptr_t b) {
|
||||||
|
return _InterlockedExchangeAdd64((volatile __int64*)&a, b) + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndAdd(TAtomic& a, intptr_t b) {
|
||||||
|
return _InterlockedExchangeAdd64((volatile __int64*)&a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicSwap(TAtomic* a, intptr_t b) {
|
||||||
|
return _InterlockedExchange64((volatile __int64*)a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool AtomicCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
|
||||||
|
return _InterlockedCompareExchange64((volatile __int64*)a, exchange, compare) == compare;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicGetAndCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
|
||||||
|
return _InterlockedCompareExchange64((volatile __int64*)a, exchange, compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicOr(TAtomic& a, intptr_t b) {
|
||||||
|
return _InterlockedOr64(&a, b) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicAnd(TAtomic& a, intptr_t b) {
|
||||||
|
return _InterlockedAnd64(&a, b) & b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline intptr_t AtomicXor(TAtomic& a, intptr_t b) {
|
||||||
|
return _InterlockedXor64(&a, b) ^ b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _x86_
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
static inline void AtomicBarrier() {
|
||||||
|
TAtomic val = 0;
|
||||||
|
|
||||||
|
AtomicSwap(&val, 0);
|
||||||
|
}
|
617
contrib/lfalloc/src/util/system/compiler.h
Normal file
617
contrib/lfalloc/src/util/system/compiler.h
Normal file
@ -0,0 +1,617 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// useful cross-platfrom definitions for compilers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_FUNC_SIGNATURE
|
||||||
|
*
|
||||||
|
* Use this macro to get pretty function name (see example).
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* void Hi() {
|
||||||
|
* Cout << Y_FUNC_SIGNATURE << Endl;
|
||||||
|
* }
|
||||||
|
|
||||||
|
* template <typename T>
|
||||||
|
* void Do() {
|
||||||
|
* Cout << Y_FUNC_SIGNATURE << Endl;
|
||||||
|
* }
|
||||||
|
|
||||||
|
* int main() {
|
||||||
|
* Hi(); // void Hi()
|
||||||
|
* Do<int>(); // void Do() [T = int]
|
||||||
|
* Do<TString>(); // void Do() [T = TString]
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_FUNC_SIGNATURE __PRETTY_FUNCTION__
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_FUNC_SIGNATURE __FUNCSIG__
|
||||||
|
#else
|
||||||
|
#define Y_FUNC_SIGNATURE ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define Y_PRINTF_FORMAT(n, m) __attribute__((__format__(__printf__, n, m)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Y_PRINTF_FORMAT
|
||||||
|
#define Y_PRINTF_FORMAT(n, m)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#define Y_NO_SANITIZE(...) __attribute__((no_sanitize(__VA_ARGS__)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_NO_SANITIZE)
|
||||||
|
#define Y_NO_SANITIZE(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_DECLARE_UNUSED
|
||||||
|
*
|
||||||
|
* Macro is needed to silence compiler warning about unused entities (e.g. function or argument).
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Y_DECLARE_UNUSED int FunctionUsedSolelyForDebugPurposes();
|
||||||
|
* assert(FunctionUsedSolelyForDebugPurposes() == 42);
|
||||||
|
*
|
||||||
|
* void Foo(const int argumentUsedOnlyForDebugPurposes Y_DECLARE_UNUSED) {
|
||||||
|
* assert(argumentUsedOnlyForDebugPurposes == 42);
|
||||||
|
* // however you may as well omit `Y_DECLARE_UNUSED` and use `UNUSED` macro instead
|
||||||
|
* Y_UNUSED(argumentUsedOnlyForDebugPurposes);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define Y_DECLARE_UNUSED __attribute__((unused))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Y_DECLARE_UNUSED
|
||||||
|
#define Y_DECLARE_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_LIKELY(Cond) __builtin_expect(!!(Cond), 1)
|
||||||
|
#define Y_UNLIKELY(Cond) __builtin_expect(!!(Cond), 0)
|
||||||
|
#define Y_PREFETCH_READ(Pointer, Priority) __builtin_prefetch((const void*)(Pointer), 0, Priority)
|
||||||
|
#define Y_PREFETCH_WRITE(Pointer, Priority) __builtin_prefetch((const void*)(Pointer), 1, Priority)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_FORCE_INLINE
|
||||||
|
*
|
||||||
|
* Macro to use in place of 'inline' in function declaration/definition to force
|
||||||
|
* it to be inlined.
|
||||||
|
*/
|
||||||
|
#if !defined(Y_FORCE_INLINE)
|
||||||
|
#if defined(CLANG_COVERAGE)
|
||||||
|
#/* excessive __always_inline__ might significantly slow down compilation of an instrumented unit */
|
||||||
|
#define Y_FORCE_INLINE inline
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_FORCE_INLINE __forceinline
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#/* Clang also defines __GNUC__ (as 4) */
|
||||||
|
#define Y_FORCE_INLINE inline __attribute__((__always_inline__))
|
||||||
|
#else
|
||||||
|
#define Y_FORCE_INLINE inline
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_NO_INLINE
|
||||||
|
*
|
||||||
|
* Macro to use in place of 'inline' in function declaration/definition to
|
||||||
|
* prevent it from being inlined.
|
||||||
|
*/
|
||||||
|
#if !defined(Y_NO_INLINE)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define Y_NO_INLINE __declspec(noinline)
|
||||||
|
#elif defined(__GNUC__) || defined(__INTEL_COMPILER)
|
||||||
|
#/* Clang also defines __GNUC__ (as 4) */
|
||||||
|
#define Y_NO_INLINE __attribute__((__noinline__))
|
||||||
|
#else
|
||||||
|
#define Y_NO_INLINE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//to cheat compiler about strict aliasing or similar problems
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_FAKE_READ(X) \
|
||||||
|
do { \
|
||||||
|
__asm__ __volatile__("" \
|
||||||
|
: \
|
||||||
|
: "m"(X)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define Y_FAKE_WRITE(X) \
|
||||||
|
do { \
|
||||||
|
__asm__ __volatile__("" \
|
||||||
|
: "=m"(X)); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_FAKE_READ)
|
||||||
|
#define Y_FAKE_READ(X)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_FAKE_WRITE)
|
||||||
|
#define Y_FAKE_WRITE(X)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Y_PREFETCH_READ
|
||||||
|
#define Y_PREFETCH_READ(Pointer, Priority) (void)(const void*)(Pointer), (void)Priority
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Y_PREFETCH_WRITE
|
||||||
|
#define Y_PREFETCH_WRITE(Pointer, Priority) (void)(const void*)(Pointer), (void)Priority
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Y_LIKELY
|
||||||
|
#define Y_LIKELY(Cond) (Cond)
|
||||||
|
#define Y_UNLIKELY(Cond) (Cond)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define _packed __attribute__((packed))
|
||||||
|
#else
|
||||||
|
#define _packed
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Y_WARN_UNUSED_RESULT
|
||||||
|
#define Y_WARN_UNUSED_RESULT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_HIDDEN __attribute__((visibility("hidden")))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_HIDDEN)
|
||||||
|
#define Y_HIDDEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_PUBLIC __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_PUBLIC)
|
||||||
|
#define Y_PUBLIC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_UNUSED) && !defined(__cplusplus)
|
||||||
|
#define Y_UNUSED(var) (void)(var)
|
||||||
|
#endif
|
||||||
|
#if !defined(Y_UNUSED) && defined(__cplusplus)
|
||||||
|
template <class... Types>
|
||||||
|
constexpr Y_FORCE_INLINE int Y_UNUSED(Types&&...) {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_ASSUME
|
||||||
|
*
|
||||||
|
* Macro that tells the compiler that it can generate optimized code
|
||||||
|
* as if the given expression will always evaluate true.
|
||||||
|
* The behavior is undefined if it ever evaluates false.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* // factored into a function so that it's testable
|
||||||
|
* inline int Avg(int x, int y) {
|
||||||
|
* if (x >= 0 && y >= 0) {
|
||||||
|
* return (static_cast<unsigned>(x) + static_cast<unsigned>(y)) >> 1;
|
||||||
|
* } else {
|
||||||
|
* // a slower implementation
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // we know that xs and ys are non-negative from domain knowledge,
|
||||||
|
* // but we can't change the types of xs and ys because of API constrains
|
||||||
|
* int Foo(const TVector<int>& xs, const TVector<int>& ys) {
|
||||||
|
* TVector<int> avgs;
|
||||||
|
* avgs.resize(xs.size());
|
||||||
|
* for (size_t i = 0; i < xs.size(); ++i) {
|
||||||
|
* auto x = xs[i];
|
||||||
|
* auto y = ys[i];
|
||||||
|
* Y_ASSUME(x >= 0);
|
||||||
|
* Y_ASSUME(y >= 0);
|
||||||
|
* xs[i] = Avg(x, y);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_ASSUME(condition) ((condition) ? (void)0 : __builtin_unreachable())
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_ASSUME(condition) __assume(condition)
|
||||||
|
#else
|
||||||
|
#define Y_ASSUME(condition) Y_UNUSED(condition)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
[[noreturn]]
|
||||||
|
#endif
|
||||||
|
Y_HIDDEN void _YandexAbort();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_UNREACHABLE
|
||||||
|
*
|
||||||
|
* Macro that marks the rest of the code branch unreachable.
|
||||||
|
* The behavior is undefined if it's ever reached.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* switch (i % 3) {
|
||||||
|
* case 0:
|
||||||
|
* return foo;
|
||||||
|
* case 1:
|
||||||
|
* return bar;
|
||||||
|
* case 2:
|
||||||
|
* return baz;
|
||||||
|
* default:
|
||||||
|
* Y_UNREACHABLE();
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__) || defined(_MSC_VER)
|
||||||
|
#define Y_UNREACHABLE() Y_ASSUME(0)
|
||||||
|
#else
|
||||||
|
#define Y_UNREACHABLE() _YandexAbort()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(undefined_sanitizer_enabled)
|
||||||
|
#define _ubsan_enabled_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
|
||||||
|
#if __has_feature(thread_sanitizer)
|
||||||
|
#define _tsan_enabled_
|
||||||
|
#endif
|
||||||
|
#if __has_feature(memory_sanitizer)
|
||||||
|
#define _msan_enabled_
|
||||||
|
#endif
|
||||||
|
#if __has_feature(address_sanitizer)
|
||||||
|
#define _asan_enabled_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if defined(thread_sanitizer_enabled) || defined(__SANITIZE_THREAD__)
|
||||||
|
#define _tsan_enabled_
|
||||||
|
#endif
|
||||||
|
#if defined(memory_sanitizer_enabled)
|
||||||
|
#define _msan_enabled_
|
||||||
|
#endif
|
||||||
|
#if defined(address_sanitizer_enabled) || defined(__SANITIZE_ADDRESS__)
|
||||||
|
#define _asan_enabled_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_asan_enabled_) || defined(_msan_enabled_) || defined(_tsan_enabled_) || defined(_ubsan_enabled_)
|
||||||
|
#define _san_enabled_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define __PRETTY_FUNCTION__ __FUNCSIG__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_WEAK __attribute__((weak))
|
||||||
|
#else
|
||||||
|
#define Y_WEAK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CUDACC_VER_MAJOR__)
|
||||||
|
#define Y_CUDA_AT_LEAST(x, y) (__CUDACC_VER_MAJOR__ > x || (__CUDACC_VER_MAJOR__ == x && __CUDACC_VER_MINOR__ >= y))
|
||||||
|
#else
|
||||||
|
#define Y_CUDA_AT_LEAST(x, y) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NVidia CUDA C++ Compiler did not know about noexcept keyword until version 9.0
|
||||||
|
#if !Y_CUDA_AT_LEAST(9, 0)
|
||||||
|
#if defined(__CUDACC__) && !defined(noexcept)
|
||||||
|
#define noexcept throw ()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define Y_COLD __attribute__((cold))
|
||||||
|
#define Y_LEAF __attribute__((leaf))
|
||||||
|
#define Y_WRAPPER __attribute__((artificial))
|
||||||
|
#else
|
||||||
|
#define Y_COLD
|
||||||
|
#define Y_LEAF
|
||||||
|
#define Y_WRAPPER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_PRAGMA
|
||||||
|
*
|
||||||
|
* Macro for use in other macros to define compiler pragma
|
||||||
|
* See below for other usage examples
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* #if defined(__clang__) || defined(__GNUC__)
|
||||||
|
* #define Y_PRAGMA_NO_WSHADOW \
|
||||||
|
* Y_PRAGMA("GCC diagnostic ignored \"-Wshadow\"")
|
||||||
|
* #elif defined(_MSC_VER)
|
||||||
|
* #define Y_PRAGMA_NO_WSHADOW \
|
||||||
|
* Y_PRAGMA("warning(disable:4456 4457")
|
||||||
|
* #else
|
||||||
|
* #define Y_PRAGMA_NO_WSHADOW
|
||||||
|
* #endif
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#define Y_PRAGMA(x) _Pragma(x)
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_PRAGMA(x) __pragma(x)
|
||||||
|
#else
|
||||||
|
#define Y_PRAGMA(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_PRAGMA_DIAGNOSTIC_PUSH
|
||||||
|
*
|
||||||
|
* Cross-compiler pragma to save diagnostic settings
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* GCC: https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
|
||||||
|
* MSVC: https://msdn.microsoft.com/en-us/library/2c8f766e.aspx
|
||||||
|
* Clang: https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_PUSH
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#define Y_PRAGMA_DIAGNOSTIC_PUSH \
|
||||||
|
Y_PRAGMA("GCC diagnostic push")
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_PRAGMA_DIAGNOSTIC_PUSH \
|
||||||
|
Y_PRAGMA(warning(push))
|
||||||
|
#else
|
||||||
|
#define Y_PRAGMA_DIAGNOSTIC_PUSH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_PRAGMA_DIAGNOSTIC_POP
|
||||||
|
*
|
||||||
|
* Cross-compiler pragma to restore diagnostic settings
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* GCC: https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
|
||||||
|
* MSVC: https://msdn.microsoft.com/en-us/library/2c8f766e.aspx
|
||||||
|
* Clang: https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_POP
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#define Y_PRAGMA_DIAGNOSTIC_POP \
|
||||||
|
Y_PRAGMA("GCC diagnostic pop")
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_PRAGMA_DIAGNOSTIC_POP \
|
||||||
|
Y_PRAGMA(warning(pop))
|
||||||
|
#else
|
||||||
|
#define Y_PRAGMA_DIAGNOSTIC_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_PRAGMA_NO_WSHADOW
|
||||||
|
*
|
||||||
|
* Cross-compiler pragma to disable warnings about shadowing variables
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_PUSH
|
||||||
|
* Y_PRAGMA_NO_WSHADOW
|
||||||
|
*
|
||||||
|
* // some code which use variable shadowing, e.g.:
|
||||||
|
*
|
||||||
|
* for (int i = 0; i < 100; ++i) {
|
||||||
|
* Use(i);
|
||||||
|
*
|
||||||
|
* for (int i = 42; i < 100500; ++i) { // this i is shadowing previous i
|
||||||
|
* AnotherUse(i);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_POP
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#define Y_PRAGMA_NO_WSHADOW \
|
||||||
|
Y_PRAGMA("GCC diagnostic ignored \"-Wshadow\"")
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_PRAGMA_NO_WSHADOW \
|
||||||
|
Y_PRAGMA(warning(disable : 4456 4457))
|
||||||
|
#else
|
||||||
|
#define Y_PRAGMA_NO_WSHADOW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ def Y_PRAGMA_NO_UNUSED_FUNCTION
|
||||||
|
*
|
||||||
|
* Cross-compiler pragma to disable warnings about unused functions
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
|
||||||
|
* Clang: https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-function
|
||||||
|
* MSVC: there is no such warning
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_PUSH
|
||||||
|
* Y_PRAGMA_NO_UNUSED_FUNCTION
|
||||||
|
*
|
||||||
|
* // some code which introduces a function which later will not be used, e.g.:
|
||||||
|
*
|
||||||
|
* void Foo() {
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* int main() {
|
||||||
|
* return 0; // Foo() never called
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_POP
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#define Y_PRAGMA_NO_UNUSED_FUNCTION \
|
||||||
|
Y_PRAGMA("GCC diagnostic ignored \"-Wunused-function\"")
|
||||||
|
#else
|
||||||
|
#define Y_PRAGMA_NO_UNUSED_FUNCTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ def Y_PRAGMA_NO_UNUSED_PARAMETER
|
||||||
|
*
|
||||||
|
* Cross-compiler pragma to disable warnings about unused function parameters
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
|
||||||
|
* Clang: https://clang.llvm.org/docs/DiagnosticsReference.html#wunused-parameter
|
||||||
|
* MSVC: https://msdn.microsoft.com/en-us/library/26kb9fy0.aspx
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_PUSH
|
||||||
|
* Y_PRAGMA_NO_UNUSED_PARAMETER
|
||||||
|
*
|
||||||
|
* // some code which introduces a function with unused parameter, e.g.:
|
||||||
|
*
|
||||||
|
* void foo(int a) {
|
||||||
|
* // a is not referenced
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* int main() {
|
||||||
|
* foo(1);
|
||||||
|
* return 0;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_POP
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#define Y_PRAGMA_NO_UNUSED_PARAMETER \
|
||||||
|
Y_PRAGMA("GCC diagnostic ignored \"-Wunused-parameter\"")
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_PRAGMA_NO_UNUSED_PARAMETER \
|
||||||
|
Y_PRAGMA(warning(disable : 4100))
|
||||||
|
#else
|
||||||
|
#define Y_PRAGMA_NO_UNUSED_PARAMETER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_PRAGMA_NO_DEPRECATED
|
||||||
|
*
|
||||||
|
* Cross compiler pragma to disable warnings and errors about deprecated
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* GCC: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
|
||||||
|
* Clang: https://clang.llvm.org/docs/DiagnosticsReference.html#wdeprecated
|
||||||
|
* MSVC: https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4996?view=vs-2017
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_PUSH
|
||||||
|
* Y_PRAGMA_NO_DEPRECATED
|
||||||
|
*
|
||||||
|
* [deprecated] void foo() {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* int main() {
|
||||||
|
* foo();
|
||||||
|
* return 0;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Y_PRAGMA_DIAGNOSTIC_POP
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#define Y_PRAGMA_NO_DEPRECATED \
|
||||||
|
Y_PRAGMA("GCC diagnostic ignored \"-Wdeprecated\"")
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define Y_PRAGMA_NO_DEPRECATED \
|
||||||
|
Y_PRAGMA(warning(disable : 4996))
|
||||||
|
#else
|
||||||
|
#define Y_PRAGMA_NO_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
/**
|
||||||
|
* @def Y_CONST_FUNCTION
|
||||||
|
methods and functions, marked with this method are promised to:
|
||||||
|
1. do not have side effects
|
||||||
|
2. this method do not read global memory
|
||||||
|
NOTE: this attribute can't be set for methods that depend on data, pointed by this
|
||||||
|
this allow compilers to do hard optimization of that functions
|
||||||
|
NOTE: in common case this attribute can't be set if method have pointer-arguments
|
||||||
|
NOTE: as result there no any reason to discard result of such method
|
||||||
|
*/
|
||||||
|
#define Y_CONST_FUNCTION [[gnu::const]]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_CONST_FUNCTION)
|
||||||
|
#define Y_CONST_FUNCTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
/**
|
||||||
|
* @def Y_PURE_FUNCTION
|
||||||
|
methods and functions, marked with this method are promised to:
|
||||||
|
1. do not have side effects
|
||||||
|
2. result will be the same if no global memory changed
|
||||||
|
this allow compilers to do hard optimization of that functions
|
||||||
|
NOTE: as result there no any reason to discard result of such method
|
||||||
|
*/
|
||||||
|
#define Y_PURE_FUNCTION [[gnu::pure]]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_PURE_FUNCTION)
|
||||||
|
#define Y_PURE_FUNCTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ def Y_HAVE_INT128
|
||||||
|
*
|
||||||
|
* Defined when the compiler supports __int128 extension
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
*
|
||||||
|
* #if defined(Y_HAVE_INT128)
|
||||||
|
* __int128 myVeryBigInt = 12345678901234567890;
|
||||||
|
* #endif
|
||||||
|
*
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
#if defined(__SIZEOF_INT128__)
|
||||||
|
#define Y_HAVE_INT128 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XRAY macro must be passed to compiler if XRay is enabled.
|
||||||
|
*
|
||||||
|
* Define everything XRay-specific as a macro so that it doesn't cause errors
|
||||||
|
* for compilers that doesn't support XRay.
|
||||||
|
*/
|
||||||
|
#if defined(XRAY) && defined(__cplusplus)
|
||||||
|
#include <xray/xray_interface.h>
|
||||||
|
#define Y_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]]
|
||||||
|
#define Y_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]]
|
||||||
|
#define Y_XRAY_CUSTOM_EVENT(__string, __length) \
|
||||||
|
do { \
|
||||||
|
__xray_customevent(__string, __length); \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define Y_XRAY_ALWAYS_INSTRUMENT
|
||||||
|
#define Y_XRAY_NEVER_INSTRUMENT
|
||||||
|
#define Y_XRAY_CUSTOM_EVENT(__string, __length) \
|
||||||
|
do { \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
168
contrib/lfalloc/src/util/system/defaults.h
Normal file
168
contrib/lfalloc/src/util/system/defaults.h
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
#if defined _unix_
|
||||||
|
#define LOCSLASH_C '/'
|
||||||
|
#define LOCSLASH_S "/"
|
||||||
|
#else
|
||||||
|
#define LOCSLASH_C '\\'
|
||||||
|
#define LOCSLASH_S "\\"
|
||||||
|
#endif // _unix_
|
||||||
|
|
||||||
|
#if defined(__INTEL_COMPILER) && defined(__cplusplus)
|
||||||
|
#include <new>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// low and high parts of integers
|
||||||
|
#if !defined(_win_)
|
||||||
|
#include <sys/param.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BSD) || defined(_android_)
|
||||||
|
|
||||||
|
#if defined(BSD)
|
||||||
|
#include <machine/endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_android_)
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||||
|
#define _little_endian_
|
||||||
|
#elif (BYTE_ORDER == BIG_ENDIAN)
|
||||||
|
#define _big_endian_
|
||||||
|
#else
|
||||||
|
#error unknown endian not supported
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif (defined(_sun_) && !defined(__i386__)) || defined(_hpux_) || defined(WHATEVER_THAT_HAS_BIG_ENDIAN)
|
||||||
|
#define _big_endian_
|
||||||
|
#else
|
||||||
|
#define _little_endian_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// alignment
|
||||||
|
#if (defined(_sun_) && !defined(__i386__)) || defined(_hpux_) || defined(__alpha__) || defined(__ia64__) || defined(WHATEVER_THAT_NEEDS_ALIGNING_QUADS)
|
||||||
|
#define _must_align8_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(_sun_) && !defined(__i386__)) || defined(_hpux_) || defined(__alpha__) || defined(__ia64__) || defined(WHATEVER_THAT_NEEDS_ALIGNING_LONGS)
|
||||||
|
#define _must_align4_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(_sun_) && !defined(__i386__)) || defined(_hpux_) || defined(__alpha__) || defined(__ia64__) || defined(WHATEVER_THAT_NEEDS_ALIGNING_SHORTS)
|
||||||
|
#define _must_align2_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define alias_hack __attribute__((__may_alias__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef alias_hack
|
||||||
|
#define alias_hack
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
||||||
|
#define PRAGMA(x) _Pragma(#x)
|
||||||
|
#define RCSID(idstr) PRAGMA(comment(exestr, idstr))
|
||||||
|
#else
|
||||||
|
#define RCSID(idstr) static const char rcsid[] = idstr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
|
#ifdef _win_
|
||||||
|
#include <malloc.h>
|
||||||
|
#elif defined(_sun_)
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define Y_IF_DEBUG(X)
|
||||||
|
#else
|
||||||
|
#define Y_IF_DEBUG(X) X
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def Y_ARRAY_SIZE
|
||||||
|
*
|
||||||
|
* This macro is needed to get number of elements in a statically allocated fixed size array. The
|
||||||
|
* expression is a compile-time constant and therefore can be used in compile time computations.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* enum ENumbers {
|
||||||
|
* EN_ONE,
|
||||||
|
* EN_TWO,
|
||||||
|
* EN_SIZE
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* const char* NAMES[] = {
|
||||||
|
* "one",
|
||||||
|
* "two"
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static_assert(Y_ARRAY_SIZE(NAMES) == EN_SIZE, "you should define `NAME` for each enumeration");
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* This macro also catches type errors. If you see a compiler error like "warning: division by zero
|
||||||
|
* is undefined" when using `Y_ARRAY_SIZE` then you are probably giving it a pointer.
|
||||||
|
*
|
||||||
|
* Since all of our code is expected to work on a 64 bit platform where pointers are 8 bytes we may
|
||||||
|
* falsefully accept pointers to types of sizes that are divisors of 8 (1, 2, 4 and 8).
|
||||||
|
*/
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
namespace NArraySizePrivate {
|
||||||
|
template <class T>
|
||||||
|
struct TArraySize;
|
||||||
|
|
||||||
|
template <class T, size_t N>
|
||||||
|
struct TArraySize<T[N]> {
|
||||||
|
enum {
|
||||||
|
Result = N
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, size_t N>
|
||||||
|
struct TArraySize<T (&)[N]> {
|
||||||
|
enum {
|
||||||
|
Result = N
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Y_ARRAY_SIZE(arr) ((size_t)::NArraySizePrivate::TArraySize<decltype(arr)>::Result)
|
||||||
|
#else
|
||||||
|
#undef Y_ARRAY_SIZE
|
||||||
|
#define Y_ARRAY_SIZE(arr) \
|
||||||
|
((sizeof(arr) / sizeof((arr)[0])) / static_cast<size_t>(!(sizeof(arr) % sizeof((arr)[0]))))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef Y_ARRAY_BEGIN
|
||||||
|
#define Y_ARRAY_BEGIN(arr) (arr)
|
||||||
|
|
||||||
|
#undef Y_ARRAY_END
|
||||||
|
#define Y_ARRAY_END(arr) ((arr) + Y_ARRAY_SIZE(arr))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concatenates two symbols, even if one of them is itself a macro.
|
||||||
|
*/
|
||||||
|
#define Y_CAT(X, Y) Y_CAT_I(X, Y)
|
||||||
|
#define Y_CAT_I(X, Y) Y_CAT_II(X, Y)
|
||||||
|
#define Y_CAT_II(X, Y) X##Y
|
||||||
|
|
||||||
|
#define Y_STRINGIZE(X) UTIL_PRIVATE_STRINGIZE_AUX(X)
|
||||||
|
#define UTIL_PRIVATE_STRINGIZE_AUX(X) #X
|
||||||
|
|
||||||
|
#if defined(__COUNTER__)
|
||||||
|
#define Y_GENERATE_UNIQUE_ID(N) Y_CAT(N, __COUNTER__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(Y_GENERATE_UNIQUE_ID)
|
||||||
|
#define Y_GENERATE_UNIQUE_ID(N) Y_CAT(N, __LINE__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NPOS ((size_t)-1)
|
242
contrib/lfalloc/src/util/system/platform.h
Normal file
242
contrib/lfalloc/src/util/system/platform.h
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// What OS ?
|
||||||
|
// our definition has the form _{osname}_
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#define _win64_
|
||||||
|
#define _win32_
|
||||||
|
#elif defined(__WIN32__) || defined(_WIN32) // _WIN32 is also defined by the 64-bit compiler for backward compatibility
|
||||||
|
#define _win32_
|
||||||
|
#else
|
||||||
|
#define _unix_
|
||||||
|
#if defined(__sun__) || defined(sun) || defined(sparc) || defined(__sparc)
|
||||||
|
#define _sun_
|
||||||
|
#endif
|
||||||
|
#if defined(__hpux__)
|
||||||
|
#define _hpux_
|
||||||
|
#endif
|
||||||
|
#if defined(__linux__)
|
||||||
|
#define _linux_
|
||||||
|
#endif
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
#define _freebsd_
|
||||||
|
#endif
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
#define _cygwin_
|
||||||
|
#endif
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#define _darwin_
|
||||||
|
#endif
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
#define _android_
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__IOS__)
|
||||||
|
#define _ios_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_linux_)
|
||||||
|
#if defined(_musl_)
|
||||||
|
//nothing to do
|
||||||
|
#elif defined(_android_)
|
||||||
|
#define _bionic_
|
||||||
|
#else
|
||||||
|
#define _glibc_
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_darwin_)
|
||||||
|
#define unix
|
||||||
|
#define __unix__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_win32_) || defined(_win64_)
|
||||||
|
#define _win_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__arm__) || defined(__ARM__) || defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM)
|
||||||
|
#if defined(__arm64) || defined(__arm64__) || defined(__aarch64__)
|
||||||
|
#define _arm64_
|
||||||
|
#else
|
||||||
|
#define _arm32_
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_arm64_) || defined(_arm32_)
|
||||||
|
#define _arm_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* __ia64__ and __x86_64__ - defined by GNU C.
|
||||||
|
* _M_IA64, _M_X64, _M_AMD64 - defined by Visual Studio.
|
||||||
|
*
|
||||||
|
* Microsoft can define _M_IX86, _M_AMD64 (before Visual Studio 8)
|
||||||
|
* or _M_X64 (starting in Visual Studio 8).
|
||||||
|
*/
|
||||||
|
#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64)
|
||||||
|
#define _x86_64_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(_M_IX86)
|
||||||
|
#define _i386_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__ia64__) || defined(_M_IA64)
|
||||||
|
#define _ia64_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__powerpc__)
|
||||||
|
#define _ppc_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__powerpc64__)
|
||||||
|
#define _ppc64_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(sparc) && !defined(__sparc) && !defined(__hpux__) && !defined(__alpha__) && !defined(_ia64_) && !defined(_x86_64_) && !defined(_arm_) && !defined(_i386_) && !defined(_ppc_) && !defined(_ppc64_)
|
||||||
|
#error "platform not defined, please, define one"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_x86_64_) || defined(_i386_)
|
||||||
|
#define _x86_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__MIC__)
|
||||||
|
#define _mic_
|
||||||
|
#define _k1om_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// stdio or MessageBox
|
||||||
|
#if defined(__CONSOLE__) || defined(_CONSOLE)
|
||||||
|
#define _console_
|
||||||
|
#endif
|
||||||
|
#if (defined(_win_) && !defined(_console_))
|
||||||
|
#define _windows_
|
||||||
|
#elif !defined(_console_)
|
||||||
|
#define _console_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SSE__) || defined(SSE_ENABLED)
|
||||||
|
#define _sse_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SSE2__) || defined(SSE2_ENABLED)
|
||||||
|
#define _sse2_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SSE3__) || defined(SSE3_ENABLED)
|
||||||
|
#define _sse3_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SSSE3__) || defined(SSSE3_ENABLED)
|
||||||
|
#define _ssse3_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(POPCNT_ENABLED)
|
||||||
|
#define _popcnt_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__DLL__) || defined(_DLL)
|
||||||
|
#define _dll_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 16, 32 or 64
|
||||||
|
#if defined(__sparc_v9__) || defined(_x86_64_) || defined(_ia64_) || defined(_arm64_) || defined(_ppc64_)
|
||||||
|
#define _64_
|
||||||
|
#else
|
||||||
|
#define _32_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* All modern 64-bit Unix systems use scheme LP64 (long, pointers are 64-bit).
|
||||||
|
* Microsoft uses a different scheme: LLP64 (long long, pointers are 64-bit).
|
||||||
|
*
|
||||||
|
* Scheme LP64 LLP64
|
||||||
|
* char 8 8
|
||||||
|
* short 16 16
|
||||||
|
* int 32 32
|
||||||
|
* long 64 32
|
||||||
|
* long long 64 64
|
||||||
|
* pointer 64 64
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(_32_)
|
||||||
|
#define SIZEOF_PTR 4
|
||||||
|
#elif defined(_64_)
|
||||||
|
#define SIZEOF_PTR 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PLATFORM_DATA_ALIGN SIZEOF_PTR
|
||||||
|
|
||||||
|
#if !defined(SIZEOF_PTR)
|
||||||
|
#error todo
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIZEOF_CHAR 1
|
||||||
|
#define SIZEOF_UNSIGNED_CHAR 1
|
||||||
|
#define SIZEOF_SHORT 2
|
||||||
|
#define SIZEOF_UNSIGNED_SHORT 2
|
||||||
|
#define SIZEOF_INT 4
|
||||||
|
#define SIZEOF_UNSIGNED_INT 4
|
||||||
|
|
||||||
|
#if defined(_32_)
|
||||||
|
#define SIZEOF_LONG 4
|
||||||
|
#define SIZEOF_UNSIGNED_LONG 4
|
||||||
|
#elif defined(_64_)
|
||||||
|
#if defined(_win_)
|
||||||
|
#define SIZEOF_LONG 4
|
||||||
|
#define SIZEOF_UNSIGNED_LONG 4
|
||||||
|
#else
|
||||||
|
#define SIZEOF_LONG 8
|
||||||
|
#define SIZEOF_UNSIGNED_LONG 8
|
||||||
|
#endif // _win_
|
||||||
|
#endif // _32_
|
||||||
|
|
||||||
|
#if !defined(SIZEOF_LONG)
|
||||||
|
#error todo
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIZEOF_LONG_LONG 8
|
||||||
|
#define SIZEOF_UNSIGNED_LONG_LONG 8
|
||||||
|
|
||||||
|
#undef SIZEOF_SIZE_T // in case we include <Python.h> which defines it, too
|
||||||
|
#define SIZEOF_SIZE_T SIZEOF_PTR
|
||||||
|
|
||||||
|
#if defined(__INTEL_COMPILER)
|
||||||
|
#pragma warning(disable 1292)
|
||||||
|
#pragma warning(disable 1469)
|
||||||
|
#pragma warning(disable 193)
|
||||||
|
#pragma warning(disable 271)
|
||||||
|
#pragma warning(disable 383)
|
||||||
|
#pragma warning(disable 424)
|
||||||
|
#pragma warning(disable 444)
|
||||||
|
#pragma warning(disable 584)
|
||||||
|
#pragma warning(disable 593)
|
||||||
|
#pragma warning(disable 981)
|
||||||
|
#pragma warning(disable 1418)
|
||||||
|
#pragma warning(disable 304)
|
||||||
|
#pragma warning(disable 810)
|
||||||
|
#pragma warning(disable 1029)
|
||||||
|
#pragma warning(disable 1419)
|
||||||
|
#pragma warning(disable 177)
|
||||||
|
#pragma warning(disable 522)
|
||||||
|
#pragma warning(disable 858)
|
||||||
|
#pragma warning(disable 111)
|
||||||
|
#pragma warning(disable 1599)
|
||||||
|
#pragma warning(disable 411)
|
||||||
|
#pragma warning(disable 304)
|
||||||
|
#pragma warning(disable 858)
|
||||||
|
#pragma warning(disable 444)
|
||||||
|
#pragma warning(disable 913)
|
||||||
|
#pragma warning(disable 310)
|
||||||
|
#pragma warning(disable 167)
|
||||||
|
#pragma warning(disable 180)
|
||||||
|
#pragma warning(disable 1572)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#undef _WINSOCKAPI_
|
||||||
|
#define _WINSOCKAPI_
|
||||||
|
#undef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
117
contrib/lfalloc/src/util/system/types.h
Normal file
117
contrib/lfalloc/src/util/system/types.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// DO_NOT_STYLE
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
typedef int8_t i8;
|
||||||
|
typedef int16_t i16;
|
||||||
|
typedef uint8_t ui8;
|
||||||
|
typedef uint16_t ui16;
|
||||||
|
|
||||||
|
typedef int yssize_t;
|
||||||
|
#define PRIYSZT "d"
|
||||||
|
|
||||||
|
#if defined(_darwin_) && defined(_32_)
|
||||||
|
typedef unsigned long ui32;
|
||||||
|
typedef long i32;
|
||||||
|
#else
|
||||||
|
typedef uint32_t ui32;
|
||||||
|
typedef int32_t i32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_darwin_) && defined(_64_)
|
||||||
|
typedef unsigned long ui64;
|
||||||
|
typedef long i64;
|
||||||
|
#else
|
||||||
|
typedef uint64_t ui64;
|
||||||
|
typedef int64_t i64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LL(number) INT64_C(number)
|
||||||
|
#define ULL(number) UINT64_C(number)
|
||||||
|
|
||||||
|
// Macro for size_t and ptrdiff_t types
|
||||||
|
#if defined(_32_)
|
||||||
|
# if defined(_darwin_)
|
||||||
|
# define PRISZT "lu"
|
||||||
|
# undef PRIi32
|
||||||
|
# define PRIi32 "li"
|
||||||
|
# undef SCNi32
|
||||||
|
# define SCNi32 "li"
|
||||||
|
# undef PRId32
|
||||||
|
# define PRId32 "li"
|
||||||
|
# undef SCNd32
|
||||||
|
# define SCNd32 "li"
|
||||||
|
# undef PRIu32
|
||||||
|
# define PRIu32 "lu"
|
||||||
|
# undef SCNu32
|
||||||
|
# define SCNu32 "lu"
|
||||||
|
# undef PRIx32
|
||||||
|
# define PRIx32 "lx"
|
||||||
|
# undef SCNx32
|
||||||
|
# define SCNx32 "lx"
|
||||||
|
# elif !defined(_cygwin_)
|
||||||
|
# define PRISZT PRIu32
|
||||||
|
# else
|
||||||
|
# define PRISZT "u"
|
||||||
|
# endif
|
||||||
|
# define SCNSZT SCNu32
|
||||||
|
# define PRIPDT PRIi32
|
||||||
|
# define SCNPDT SCNi32
|
||||||
|
# define PRITMT PRIi32
|
||||||
|
# define SCNTMT SCNi32
|
||||||
|
#elif defined(_64_)
|
||||||
|
# if defined(_darwin_)
|
||||||
|
# define PRISZT "lu"
|
||||||
|
# undef PRIu64
|
||||||
|
# define PRIu64 PRISZT
|
||||||
|
# undef PRIx64
|
||||||
|
# define PRIx64 "lx"
|
||||||
|
# undef PRIX64
|
||||||
|
# define PRIX64 "lX"
|
||||||
|
# undef PRId64
|
||||||
|
# define PRId64 "ld"
|
||||||
|
# undef PRIi64
|
||||||
|
# define PRIi64 "li"
|
||||||
|
# undef SCNi64
|
||||||
|
# define SCNi64 "li"
|
||||||
|
# undef SCNu64
|
||||||
|
# define SCNu64 "lu"
|
||||||
|
# undef SCNx64
|
||||||
|
# define SCNx64 "lx"
|
||||||
|
# else
|
||||||
|
# define PRISZT PRIu64
|
||||||
|
# endif
|
||||||
|
# define SCNSZT SCNu64
|
||||||
|
# define PRIPDT PRIi64
|
||||||
|
# define SCNPDT SCNi64
|
||||||
|
# define PRITMT PRIi64
|
||||||
|
# define SCNTMT SCNi64
|
||||||
|
#else
|
||||||
|
# error "Unsupported platform"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// SUPERLONG
|
||||||
|
#if !defined(DONT_USE_SUPERLONG) && !defined(SUPERLONG_MAX)
|
||||||
|
#define SUPERLONG_MAX ~LL(0)
|
||||||
|
typedef i64 SUPERLONG;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// UNICODE
|
||||||
|
// UCS-2, native byteorder
|
||||||
|
typedef ui16 wchar16;
|
||||||
|
// internal symbol type: UTF-16LE
|
||||||
|
typedef wchar16 TChar;
|
||||||
|
typedef ui32 wchar32;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <basetsd.h>
|
||||||
|
typedef SSIZE_T ssize_t;
|
||||||
|
#define HAVE_SSIZE_T 1
|
||||||
|
#include <wchar.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
@ -155,7 +155,6 @@ if (USE_EMBEDDED_COMPILER)
|
|||||||
target_include_directories (dbms SYSTEM BEFORE PUBLIC ${LLVM_INCLUDE_DIRS})
|
target_include_directories (dbms SYSTEM BEFORE PUBLIC ${LLVM_INCLUDE_DIRS})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE_UC STREQUAL "RELEASE" OR CMAKE_BUILD_TYPE_UC STREQUAL "RELWITHDEBINFO" OR CMAKE_BUILD_TYPE_UC STREQUAL "MINSIZEREL")
|
if (CMAKE_BUILD_TYPE_UC STREQUAL "RELEASE" OR CMAKE_BUILD_TYPE_UC STREQUAL "RELWITHDEBINFO" OR CMAKE_BUILD_TYPE_UC STREQUAL "MINSIZEREL")
|
||||||
# Won't generate debug info for files with heavy template instantiation to achieve faster linking and lower size.
|
# Won't generate debug info for files with heavy template instantiation to achieve faster linking and lower size.
|
||||||
set_source_files_properties(
|
set_source_files_properties(
|
||||||
@ -214,6 +213,10 @@ target_link_libraries (clickhouse_common_io
|
|||||||
|
|
||||||
target_include_directories(clickhouse_common_io SYSTEM BEFORE PUBLIC ${RE2_INCLUDE_DIR})
|
target_include_directories(clickhouse_common_io SYSTEM BEFORE PUBLIC ${RE2_INCLUDE_DIR})
|
||||||
|
|
||||||
|
if (USE_LFALLOC)
|
||||||
|
target_include_directories (clickhouse_common_io SYSTEM BEFORE PUBLIC ${LFALLOC_INCLUDE_DIR})
|
||||||
|
endif ()
|
||||||
|
|
||||||
if(CPUID_LIBRARY)
|
if(CPUID_LIBRARY)
|
||||||
target_link_libraries(clickhouse_common_io PRIVATE ${CPUID_LIBRARY})
|
target_link_libraries(clickhouse_common_io PRIVATE ${CPUID_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
53
dbms/src/Common/LFAllocator.cpp
Normal file
53
dbms/src/Common/LFAllocator.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include <Common/config.h>
|
||||||
|
|
||||||
|
#if USE_LFALLOC
|
||||||
|
#include "LFAllocator.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <lf_allocX64.h>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
void * LFAllocator::alloc(size_t size, size_t alignment)
|
||||||
|
{
|
||||||
|
if (alignment == 0)
|
||||||
|
return LFAlloc(size);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void * ptr;
|
||||||
|
int res = LFPosixMemalign(&ptr, alignment, size);
|
||||||
|
return res ? nullptr : ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LFAllocator::free(void * buf, size_t)
|
||||||
|
{
|
||||||
|
LFFree(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void * LFAllocator::realloc(void * old_ptr, size_t, size_t new_size, size_t alignment)
|
||||||
|
{
|
||||||
|
if (old_ptr == nullptr)
|
||||||
|
{
|
||||||
|
void * result = LFAllocator::alloc(new_size, alignment);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (new_size == 0)
|
||||||
|
{
|
||||||
|
LFFree(old_ptr);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * new_ptr = LFAllocator::alloc(new_size, alignment);
|
||||||
|
if (new_ptr == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
size_t old_size = LFGetSize(old_ptr);
|
||||||
|
memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size));
|
||||||
|
LFFree(old_ptr);
|
||||||
|
return new_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
22
dbms/src/Common/LFAllocator.h
Normal file
22
dbms/src/Common/LFAllocator.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Common/config.h>
|
||||||
|
|
||||||
|
#if !USE_LFALLOC
|
||||||
|
#error "do not include this file until USE_LFALLOC is set to 1"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
struct LFAllocator
|
||||||
|
{
|
||||||
|
static void * alloc(size_t size, size_t alignment = 0);
|
||||||
|
|
||||||
|
static void free(void * buf, size_t);
|
||||||
|
|
||||||
|
static void * realloc(void * buf, size_t, size_t new_size, size_t alignment = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -25,6 +25,8 @@
|
|||||||
#cmakedefine01 USE_BROTLI
|
#cmakedefine01 USE_BROTLI
|
||||||
#cmakedefine01 USE_SSL
|
#cmakedefine01 USE_SSL
|
||||||
#cmakedefine01 USE_HYPERSCAN
|
#cmakedefine01 USE_HYPERSCAN
|
||||||
|
#cmakedefine01 USE_LFALLOC
|
||||||
|
#cmakedefine01 USE_LFALLOC_RANDOM_HINT
|
||||||
|
|
||||||
#cmakedefine01 CLICKHOUSE_SPLIT_BINARY
|
#cmakedefine01 CLICKHOUSE_SPLIT_BINARY
|
||||||
#cmakedefine01 LLVM_HAS_RTTI
|
#cmakedefine01 LLVM_HAS_RTTI
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include <Common/PODArray.h>
|
#include <Common/PODArray.h>
|
||||||
|
|
||||||
|
#include <Common/config.h>
|
||||||
|
#if USE_LFALLOC
|
||||||
|
#include <Common/LFAllocator.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -33,7 +37,9 @@ struct MarkInCompressedFile
|
|||||||
return "(" + DB::toString(offset_in_compressed_file) + "," + DB::toString(offset_in_decompressed_block) + ")";
|
return "(" + DB::toString(offset_in_compressed_file) + "," + DB::toString(offset_in_decompressed_block) + ")";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#if USE_LFALLOC
|
||||||
|
using MarksInCompressedFile = PODArray<MarkInCompressedFile, 4096, LFAllocator>;
|
||||||
|
#else
|
||||||
using MarksInCompressedFile = PODArray<MarkInCompressedFile>;
|
using MarksInCompressedFile = PODArray<MarkInCompressedFile>;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
#include <Common/ProfileEvents.h>
|
#include <Common/ProfileEvents.h>
|
||||||
#include <IO/BufferWithOwnMemory.h>
|
#include <IO/BufferWithOwnMemory.h>
|
||||||
|
|
||||||
|
#include <Common/config.h>
|
||||||
|
#if USE_LFALLOC
|
||||||
|
#include <Common/LFAllocator.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace ProfileEvents
|
namespace ProfileEvents
|
||||||
{
|
{
|
||||||
@ -20,7 +25,11 @@ namespace DB
|
|||||||
|
|
||||||
struct UncompressedCacheCell
|
struct UncompressedCacheCell
|
||||||
{
|
{
|
||||||
|
#if USE_LFALLOC
|
||||||
|
Memory<LFAllocator> data;
|
||||||
|
#else
|
||||||
Memory<> data;
|
Memory<> data;
|
||||||
|
#endif
|
||||||
size_t compressed_size;
|
size_t compressed_size;
|
||||||
UInt32 additional_bytes;
|
UInt32 additional_bytes;
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <Poco/Util/Application.h>
|
#include <Poco/Util/Application.h>
|
||||||
#include <ext/unlock_guard.h>
|
#include <ext/unlock_guard.h>
|
||||||
#include <Common/ClickHouseRevision.h>
|
#include <Common/ClickHouseRevision.h>
|
||||||
|
#include <Common/config.h>
|
||||||
#include <Common/SipHash.h>
|
#include <Common/SipHash.h>
|
||||||
#include <Common/ShellCommand.h>
|
#include <Common/ShellCommand.h>
|
||||||
#include <Common/StringUtils/StringUtils.h>
|
#include <Common/StringUtils/StringUtils.h>
|
||||||
@ -261,6 +262,9 @@ void Compiler::compile(
|
|||||||
" -I " << compiler_headers << "/dbms/src/"
|
" -I " << compiler_headers << "/dbms/src/"
|
||||||
" -isystem " << compiler_headers << "/contrib/cityhash102/include/"
|
" -isystem " << compiler_headers << "/contrib/cityhash102/include/"
|
||||||
" -isystem " << compiler_headers << "/contrib/libpcg-random/include/"
|
" -isystem " << compiler_headers << "/contrib/libpcg-random/include/"
|
||||||
|
#if USE_LFALLOC
|
||||||
|
" -isystem " << compiler_headers << "/contrib/lfalloc/src/"
|
||||||
|
#endif
|
||||||
" -isystem " << compiler_headers << INTERNAL_DOUBLE_CONVERSION_INCLUDE_DIR
|
" -isystem " << compiler_headers << INTERNAL_DOUBLE_CONVERSION_INCLUDE_DIR
|
||||||
" -isystem " << compiler_headers << INTERNAL_Poco_Foundation_INCLUDE_DIR
|
" -isystem " << compiler_headers << INTERNAL_Poco_Foundation_INCLUDE_DIR
|
||||||
" -isystem " << compiler_headers << INTERNAL_Boost_INCLUDE_DIRS
|
" -isystem " << compiler_headers << INTERNAL_Boost_INCLUDE_DIRS
|
||||||
|
@ -57,6 +57,8 @@ const char * auto_config_build[]
|
|||||||
"USE_BROTLI", "@USE_BROTLI@",
|
"USE_BROTLI", "@USE_BROTLI@",
|
||||||
"USE_SSL", "@USE_SSL@",
|
"USE_SSL", "@USE_SSL@",
|
||||||
"USE_HYPERSCAN", "@USE_HYPERSCAN@",
|
"USE_HYPERSCAN", "@USE_HYPERSCAN@",
|
||||||
|
"USE_LFALLOC", "@USE_LFALLOC@",
|
||||||
|
"USE_LFALLOC_RANDOM_HINT", "@USE_LFALLOC_RANDOM_HINT@",
|
||||||
|
|
||||||
nullptr, nullptr
|
nullptr, nullptr
|
||||||
};
|
};
|
||||||
|
@ -61,7 +61,6 @@ add_library (common ${LINK_MODE}
|
|||||||
if (USE_JEMALLOC)
|
if (USE_JEMALLOC)
|
||||||
message (STATUS "Link jemalloc: ${JEMALLOC_LIBRARIES}")
|
message (STATUS "Link jemalloc: ${JEMALLOC_LIBRARIES}")
|
||||||
set (MALLOC_LIBRARIES ${JEMALLOC_LIBRARIES})
|
set (MALLOC_LIBRARIES ${JEMALLOC_LIBRARIES})
|
||||||
|
|
||||||
elseif (USE_TCMALLOC)
|
elseif (USE_TCMALLOC)
|
||||||
if (DEBUG_TCMALLOC AND NOT GPERFTOOLS_TCMALLOC_MINIMAL_DEBUG)
|
if (DEBUG_TCMALLOC AND NOT GPERFTOOLS_TCMALLOC_MINIMAL_DEBUG)
|
||||||
message (FATAL_ERROR "Requested DEBUG_TCMALLOC but debug library is not found. You should install Google Perftools. Example: sudo apt-get install libgoogle-perftools-dev")
|
message (FATAL_ERROR "Requested DEBUG_TCMALLOC but debug library is not found. You should install Google Perftools. Example: sudo apt-get install libgoogle-perftools-dev")
|
||||||
|
Loading…
Reference in New Issue
Block a user