mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Merge pull request #5775 from yandex/lfalloc2mimalloc
Use mimalloc instead of lfallocator
This commit is contained in:
commit
6e77fc4abe
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -85,3 +85,6 @@
|
||||
[submodule "contrib/rapidjson"]
|
||||
path = contrib/rapidjson
|
||||
url = https://github.com/Tencent/rapidjson
|
||||
[submodule "contrib/mimalloc"]
|
||||
path = contrib/mimalloc
|
||||
url = https://github.com/ClickHouse-Extras/mimalloc
|
||||
|
@ -335,7 +335,7 @@ include (cmake/find_hdfs3.cmake) # uses protobuf
|
||||
include (cmake/find_consistent-hashing.cmake)
|
||||
include (cmake/find_base64.cmake)
|
||||
include (cmake/find_hyperscan.cmake)
|
||||
include (cmake/find_lfalloc.cmake)
|
||||
include (cmake/find_mimalloc.cmake)
|
||||
include (cmake/find_simdjson.cmake)
|
||||
include (cmake/find_rapidjson.cmake)
|
||||
find_contrib_lib(cityhash)
|
||||
|
@ -1,11 +0,0 @@
|
||||
# TODO(danlark1). Disable LFAlloc for a while to fix mmap count problem
|
||||
if (NOT OS_LINUX AND NOT SANITIZE AND NOT ARCH_ARM AND NOT ARCH_32 AND NOT ARCH_PPC64LE AND NOT OS_FREEBSD AND NOT APPLE)
|
||||
option (ENABLE_LFALLOC "Set to FALSE to use system libgsasl library instead of bundled" ${NOT_UNBUNDLED})
|
||||
endif ()
|
||||
|
||||
if (ENABLE_LFALLOC)
|
||||
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 ()
|
14
cmake/find_mimalloc.cmake
Normal file
14
cmake/find_mimalloc.cmake
Normal file
@ -0,0 +1,14 @@
|
||||
if (OS_LINUX AND NOT SANITIZE AND NOT ARCH_ARM AND NOT ARCH_32 AND NOT ARCH_PPC64LE)
|
||||
option (ENABLE_MIMALLOC "Set to FALSE to disable usage of mimalloc for internal ClickHouse caches" ${NOT_UNBUNDLED})
|
||||
endif ()
|
||||
|
||||
if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/mimalloc/include/mimalloc.h")
|
||||
message (WARNING "submodule contrib/mimalloc is missing. to fix try run: \n git submodule update --init --recursive")
|
||||
endif ()
|
||||
|
||||
if (ENABLE_MIMALLOC)
|
||||
set (MIMALLOC_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/mimalloc/include)
|
||||
set (USE_MIMALLOC 1)
|
||||
set (MIMALLOC_LIBRARY mimalloc-static)
|
||||
message (STATUS "Using mimalloc: ${MIMALLOC_INCLUDE_DIR} : ${MIMALLOC_LIBRARY}")
|
||||
endif ()
|
12
contrib/CMakeLists.txt
vendored
12
contrib/CMakeLists.txt
vendored
@ -1,11 +1,11 @@
|
||||
# Third-party libraries may have substandard code.
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-result -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-format -Wno-misleading-indentation -Wno-stringop-overflow -Wno-implicit-function-declaration -Wno-return-type -Wno-array-bounds -Wno-bool-compare -Wno-int-conversion -Wno-switch -Wno-stringop-truncation")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-old-style-cast -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-result -Wno-deprecated-declarations -Wno-non-virtual-dtor -Wno-maybe-uninitialized -Wno-format -Wno-misleading-indentation -Wno-implicit-fallthrough -Wno-class-memaccess -Wno-sign-compare -Wno-array-bounds -Wno-missing-attributes -Wno-stringop-truncation -std=c++1z")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -std=c++1z")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wno-deprecated-declarations -Wno-format -Wno-parentheses-equality -Wno-tautological-constant-compare -Wno-tautological-constant-out-of-range-compare -Wno-implicit-function-declaration -Wno-return-type -Wno-pointer-bool-conversion -Wno-enum-conversion -Wno-int-conversion -Wno-switch -Wno-string-plus-int")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-old-style-cast -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wno-deprecated-declarations -Wno-non-virtual-dtor -Wno-format -Wno-inconsistent-missing-override -std=c++1z")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -std=c++1z")
|
||||
endif ()
|
||||
|
||||
set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL 1)
|
||||
@ -317,3 +317,7 @@ endif()
|
||||
if (USE_SIMDJSON)
|
||||
add_subdirectory (simdjson-cmake)
|
||||
endif()
|
||||
|
||||
if (USE_MIMALLOC)
|
||||
add_subdirectory (mimalloc)
|
||||
endif()
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,23 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
};
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
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.
|
@ -1,51 +0,0 @@
|
||||
#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"
|
@ -1,90 +0,0 @@
|
||||
#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();
|
||||
}
|
@ -1,189 +0,0 @@
|
||||
#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));
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
#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);
|
||||
}
|
@ -1,617 +0,0 @@
|
||||
#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
|
@ -1,168 +0,0 @@
|
||||
#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)
|
@ -1,242 +0,0 @@
|
||||
#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
|
@ -1,117 +0,0 @@
|
||||
#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>
|
1
contrib/mimalloc
vendored
Submodule
1
contrib/mimalloc
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b4ece3482f944b5d07d889cbaebaf9aa6c56cc03
|
@ -223,8 +223,9 @@ if(RE2_INCLUDE_DIR)
|
||||
target_include_directories(clickhouse_common_io SYSTEM BEFORE PUBLIC ${RE2_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if (USE_LFALLOC)
|
||||
target_include_directories (clickhouse_common_io SYSTEM BEFORE PUBLIC ${LFALLOC_INCLUDE_DIR})
|
||||
if (USE_MIMALLOC)
|
||||
target_include_directories (clickhouse_common_io SYSTEM BEFORE PUBLIC ${MIMALLOC_INCLUDE_DIR})
|
||||
target_link_libraries (clickhouse_common_io PRIVATE ${MIMALLOC_LIBRARY})
|
||||
endif ()
|
||||
|
||||
if(CPUID_LIBRARY)
|
||||
|
@ -1,53 +0,0 @@
|
||||
#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
|
@ -1,22 +0,0 @@
|
||||
#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);
|
||||
};
|
||||
|
||||
}
|
55
dbms/src/Common/MiAllocator.h
Normal file
55
dbms/src/Common/MiAllocator.h
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <Common/config.h>
|
||||
|
||||
#if !USE_MIMALLOC
|
||||
#error "do not include this file until USE_MIMALLOC is set to 1"
|
||||
#endif
|
||||
|
||||
#include <mimalloc.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/*
|
||||
* This is a different allocator that is based on mimalloc (Microsoft malloc).
|
||||
* It can be used separately from main allocator to catch heap corruptions and vulnerabilities (for example, for caches).
|
||||
* We use MI_SECURE mode in mimalloc to achieve such behaviour.
|
||||
*/
|
||||
struct MiAllocator
|
||||
{
|
||||
|
||||
static void * alloc(size_t size, size_t alignment = 0)
|
||||
{
|
||||
if (alignment == 0)
|
||||
return mi_malloc(size);
|
||||
else
|
||||
return mi_malloc_aligned(size, alignment);
|
||||
}
|
||||
|
||||
static void free(void * buf, size_t)
|
||||
{
|
||||
mi_free(buf);
|
||||
}
|
||||
|
||||
static void * realloc(void * old_ptr, size_t, size_t new_size, size_t alignment = 0)
|
||||
{
|
||||
if (old_ptr == nullptr)
|
||||
return alloc(new_size, alignment);
|
||||
|
||||
if (new_size == 0)
|
||||
{
|
||||
mi_free(old_ptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (alignment == 0)
|
||||
return mi_realloc(old_ptr, alignment);
|
||||
|
||||
return mi_realloc_aligned(old_ptr, new_size, alignment);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
#cmakedefine01 USE_CPUID
|
||||
#cmakedefine01 USE_CPUINFO
|
||||
#cmakedefine01 USE_BROTLI
|
||||
#cmakedefine01 USE_LFALLOC
|
||||
#cmakedefine01 USE_LFALLOC_RANDOM_HINT
|
||||
#cmakedefine01 USE_MIMALLOC
|
||||
|
||||
#cmakedefine01 CLICKHOUSE_SPLIT_BINARY
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include <Common/PODArray.h>
|
||||
|
||||
#include <Common/config.h>
|
||||
#if USE_LFALLOC
|
||||
#include <Common/LFAllocator.h>
|
||||
#if USE_MIMALLOC
|
||||
#include <Common/MiAllocator.h>
|
||||
#endif
|
||||
|
||||
namespace DB
|
||||
@ -43,8 +43,8 @@ struct MarkInCompressedFile
|
||||
}
|
||||
|
||||
};
|
||||
#if USE_LFALLOC
|
||||
using MarksInCompressedFile = PODArray<MarkInCompressedFile, 4096, LFAllocator>;
|
||||
#if USE_MIMALLOC
|
||||
using MarksInCompressedFile = PODArray<MarkInCompressedFile, 4096, MiAllocator>;
|
||||
#else
|
||||
using MarksInCompressedFile = PODArray<MarkInCompressedFile>;
|
||||
#endif
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include <IO/BufferWithOwnMemory.h>
|
||||
|
||||
#include <Common/config.h>
|
||||
#if USE_LFALLOC
|
||||
#include <Common/LFAllocator.h>
|
||||
#if USE_MIMALLOC
|
||||
#include <Common/MiAllocator.h>
|
||||
#endif
|
||||
|
||||
|
||||
@ -25,8 +25,8 @@ namespace DB
|
||||
|
||||
struct UncompressedCacheCell
|
||||
{
|
||||
#if USE_LFALLOC
|
||||
Memory<LFAllocator> data;
|
||||
#if USE_MIMALLOC
|
||||
Memory<MiAllocator> data;
|
||||
#else
|
||||
Memory<> data;
|
||||
#endif
|
||||
|
@ -262,8 +262,8 @@ void Compiler::compile(
|
||||
" -I " << compiler_headers << "/dbms/src/"
|
||||
" -isystem " << compiler_headers << "/contrib/cityhash102/include/"
|
||||
" -isystem " << compiler_headers << "/contrib/libpcg-random/include/"
|
||||
#if USE_LFALLOC
|
||||
" -isystem " << compiler_headers << "/contrib/lfalloc/src/"
|
||||
#if USE_MIMALLOC
|
||||
" -isystem " << compiler_headers << "/contrib/mimalloc/include/"
|
||||
#endif
|
||||
" -isystem " << compiler_headers << INTERNAL_DOUBLE_CONVERSION_INCLUDE_DIR
|
||||
" -isystem " << compiler_headers << INTERNAL_Poco_Foundation_INCLUDE_DIR
|
||||
|
@ -37,8 +37,7 @@ const char * auto_config_build[]
|
||||
"USE_GLIBC_COMPATIBILITY", "@GLIBC_COMPATIBILITY@",
|
||||
"USE_JEMALLOC", "@USE_JEMALLOC@",
|
||||
"USE_TCMALLOC", "@USE_TCMALLOC@",
|
||||
"USE_LFALLOC", "@USE_LFALLOC@",
|
||||
"USE_LFALLOC_RANDOM_HINT", "@USE_LFALLOC_RANDOM_HINT@",
|
||||
"USE_MIMALLOC", "@USE_MIMALLOC@",
|
||||
"USE_UNWIND", "@USE_UNWIND@",
|
||||
"USE_ICU", "@USE_ICU@",
|
||||
"USE_MYSQL", "@USE_MYSQL@",
|
||||
|
Loading…
Reference in New Issue
Block a user