/* * Copyright 2015-2024 Leonid Yuriev * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * . */ #pragma once /*----------------------------------------------------------------------------*/ /* Microsoft compiler generates a lot of warning for self includes... */ #ifdef _MSC_VER #pragma warning(push, 1) #pragma warning(disable : 4548) /* expression before comma has no effect; \ expected expression with side - effect */ #pragma warning(disable : 4530) /* C++ exception handler used, but unwind \ * semantics are not enabled. Specify /EHsc */ #pragma warning(disable : 4577) /* 'noexcept' used with no exception handling \ * mode specified; termination on exception is \ * not guaranteed. Specify /EHsc */ #endif /* _MSC_VER (warnings) */ #if defined(_WIN32) || defined(_WIN64) #if !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS #endif /* _CRT_SECURE_NO_WARNINGS */ #if !defined(_NO_CRT_STDIO_INLINE) && MDBX_BUILD_SHARED_LIBRARY && \ !defined(xMDBX_TOOLS) && MDBX_WITHOUT_MSVC_CRT #define _NO_CRT_STDIO_INLINE #endif #elif !defined(_POSIX_C_SOURCE) #define _POSIX_C_SOURCE 200809L #endif /* Windows */ /*----------------------------------------------------------------------------*/ /* basic C99 includes */ #include #include #include #include #include #include #include #include #include #include #include #if (-6 & 5) || CHAR_BIT != 8 || UINT_MAX < 0xffffffff || ULONG_MAX % 0xFFFF #error \ "Sanity checking failed: Two's complement, reasonably sized integer types" #endif #ifndef SSIZE_MAX #define SSIZE_MAX INTPTR_MAX #endif #if UINTPTR_MAX > 0xffffFFFFul || ULONG_MAX > 0xffffFFFFul || defined(_WIN64) #define MDBX_WORDBITS 64 #else #define MDBX_WORDBITS 32 #endif /* MDBX_WORDBITS */ /*----------------------------------------------------------------------------*/ /* feature testing */ #ifndef __has_warning #define __has_warning(x) (0) #endif #ifndef __has_include #define __has_include(x) (0) #endif #ifndef __has_feature #define __has_feature(x) (0) #endif #ifndef __has_extension #define __has_extension(x) (0) #endif #if __has_feature(thread_sanitizer) #define __SANITIZE_THREAD__ 1 #endif #if __has_feature(address_sanitizer) #define __SANITIZE_ADDRESS__ 1 #endif #ifndef __GNUC_PREREQ #if defined(__GNUC__) && defined(__GNUC_MINOR__) #define __GNUC_PREREQ(maj, min) \ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) #else #define __GNUC_PREREQ(maj, min) (0) #endif #endif /* __GNUC_PREREQ */ #ifndef __CLANG_PREREQ #ifdef __clang__ #define __CLANG_PREREQ(maj, min) \ ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min)) #else #define __CLANG_PREREQ(maj, min) (0) #endif #endif /* __CLANG_PREREQ */ #ifndef __GLIBC_PREREQ #if defined(__GLIBC__) && defined(__GLIBC_MINOR__) #define __GLIBC_PREREQ(maj, min) \ ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min)) #else #define __GLIBC_PREREQ(maj, min) (0) #endif #endif /* __GLIBC_PREREQ */ /*----------------------------------------------------------------------------*/ /* C11' alignas() */ #if __has_include() #include #endif #if defined(alignas) || defined(__cplusplus) #define MDBX_ALIGNAS(N) alignas(N) #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define MDBX_ALIGNAS(N) _Alignas(N) #elif defined(_MSC_VER) #define MDBX_ALIGNAS(N) __declspec(align(N)) #elif __has_attribute(__aligned__) || defined(__GNUC__) #define MDBX_ALIGNAS(N) __attribute__((__aligned__(N))) #else #error "FIXME: Required alignas() or equivalent." #endif /* MDBX_ALIGNAS */ /*----------------------------------------------------------------------------*/ /* Systems macros and includes */ #ifndef __extern_C #ifdef __cplusplus #define __extern_C extern "C" #else #define __extern_C #endif #endif /* __extern_C */ #if !defined(nullptr) && !defined(__cplusplus) || \ (__cplusplus < 201103L && !defined(_MSC_VER)) #define nullptr NULL #endif #if defined(__APPLE__) || defined(_DARWIN_C_SOURCE) #include #include #ifndef MAC_OS_X_VERSION_MIN_REQUIRED #define MAC_OS_X_VERSION_MIN_REQUIRED 1070 /* Mac OS X 10.7, 2011 */ #endif #endif /* Apple OSX & iOS */ #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__BSD__) || defined(__bsdi__) || defined(__DragonFly__) || \ defined(__APPLE__) || defined(__MACH__) #include #include #include #include #if defined(__FreeBSD__) || defined(__DragonFly__) #include #elif defined(__OpenBSD__) || defined(__NetBSD__) #include #else #define SYSCTL_LEGACY_NONCONST_MIB #endif #ifndef __MACH__ #include #endif #else #include #if !(defined(__sun) || defined(__SVR4) || defined(__svr4__) || \ defined(_WIN32) || defined(_WIN64)) #include #endif /* !Solaris */ #endif /* !xBSD */ #if defined(__FreeBSD__) || __has_include() #include #endif #if defined(__APPLE__) || defined(__MACH__) || __has_include() #include #endif /* MacOS */ #if defined(__MACH__) #include #include #include #include #endif #if defined(__linux__) || defined(__gnu_linux__) #include #include #include #endif /* Linux */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 0 #endif #ifndef _XOPEN_SOURCE_EXTENDED #define _XOPEN_SOURCE_EXTENDED 0 #else #include #endif /* _XOPEN_SOURCE_EXTENDED */ #if defined(__sun) || defined(__SVR4) || defined(__svr4__) #include #include /* On Solaris, it's easier to add a missing prototype rather than find a * combination of #defines that break nothing. */ __extern_C key_t ftok(const char *, int); #endif /* SunOS/Solaris */ #if defined(_WIN32) || defined(_WIN64) /*-------------------------------------*/ #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0601 /* Windows 7 */ #elif _WIN32_WINNT < 0x0500 #error At least 'Windows 2000' API is required for libmdbx. #endif /* _WIN32_WINNT */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif /* WIN32_LEAN_AND_MEAN */ #include #include #include #include #include #else /*----------------------------------------------------------------------*/ #include #if !defined(_POSIX_MAPPED_FILES) || _POSIX_MAPPED_FILES < 1 #error "libmdbx requires the _POSIX_MAPPED_FILES feature" #endif /* _POSIX_MAPPED_FILES */ #include #include #include #include #include #include #include #include #include #include #include #include #endif /*---------------------------------------------------------------------*/ #if defined(__ANDROID_API__) || defined(ANDROID) #include #if __ANDROID_API__ >= 21 #include #endif #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS != MDBX_WORDBITS #error "_FILE_OFFSET_BITS != MDBX_WORDBITS" (_FILE_OFFSET_BITS != MDBX_WORDBITS) #elif defined(__FILE_OFFSET_BITS) && __FILE_OFFSET_BITS != MDBX_WORDBITS #error "__FILE_OFFSET_BITS != MDBX_WORDBITS" (__FILE_OFFSET_BITS != MDBX_WORDBITS) #endif #endif /* Android */ #if defined(HAVE_SYS_STAT_H) || __has_include() #include #endif #if defined(HAVE_SYS_TYPES_H) || __has_include() #include #endif #if defined(HAVE_SYS_FILE_H) || __has_include() #include #endif /*----------------------------------------------------------------------------*/ /* Byteorder */ #if defined(i386) || defined(__386) || defined(__i386) || defined(__i386__) || \ defined(i486) || defined(__i486) || defined(__i486__) || defined(i586) || \ defined(__i586) || defined(__i586__) || defined(i686) || \ defined(__i686) || defined(__i686__) || defined(_M_IX86) || \ defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || \ defined(__INTEL__) || defined(__x86_64) || defined(__x86_64__) || \ defined(__amd64__) || defined(__amd64) || defined(_M_X64) || \ defined(_M_AMD64) || defined(__IA32__) || defined(__INTEL__) #ifndef __ia32__ /* LY: define neutral __ia32__ for x86 and x86-64 */ #define __ia32__ 1 #endif /* __ia32__ */ #if !defined(__amd64__) && \ (defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || \ defined(_M_X64) || defined(_M_AMD64)) /* LY: define trusty __amd64__ for all AMD64/x86-64 arch */ #define __amd64__ 1 #endif /* __amd64__ */ #endif /* all x86 */ #if !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__) || \ !defined(__ORDER_BIG_ENDIAN__) #if defined(__GLIBC__) || defined(__GNU_LIBRARY__) || \ defined(__ANDROID_API__) || defined(HAVE_ENDIAN_H) || __has_include() #include #elif defined(__APPLE__) || defined(__MACH__) || defined(__OpenBSD__) || \ defined(HAVE_MACHINE_ENDIAN_H) || __has_include() #include #elif defined(HAVE_SYS_ISA_DEFS_H) || __has_include() #include #elif (defined(HAVE_SYS_TYPES_H) && defined(HAVE_SYS_ENDIAN_H)) || \ (__has_include() && __has_include()) #include #include #elif defined(__bsdi__) || defined(__DragonFly__) || defined(__FreeBSD__) || \ defined(__NetBSD__) || defined(HAVE_SYS_PARAM_H) || __has_include() #include #endif /* OS */ #if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN) #define __ORDER_LITTLE_ENDIAN__ __LITTLE_ENDIAN #define __ORDER_BIG_ENDIAN__ __BIG_ENDIAN #define __BYTE_ORDER__ __BYTE_ORDER #elif defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) #define __ORDER_LITTLE_ENDIAN__ _LITTLE_ENDIAN #define __ORDER_BIG_ENDIAN__ _BIG_ENDIAN #define __BYTE_ORDER__ _BYTE_ORDER #else #define __ORDER_LITTLE_ENDIAN__ 1234 #define __ORDER_BIG_ENDIAN__ 4321 #if defined(__LITTLE_ENDIAN__) || \ (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \ defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \ defined(__MIPSEL__) || defined(_MIPSEL) || defined(__MIPSEL) || \ defined(_M_ARM) || defined(_M_ARM64) || defined(__e2k__) || \ defined(__elbrus_4c__) || defined(__elbrus_8c__) || defined(__bfin__) || \ defined(__BFIN__) || defined(__ia64__) || defined(_IA64) || \ defined(__IA64__) || defined(__ia64) || defined(_M_IA64) || \ defined(__itanium__) || defined(__ia32__) || defined(__CYGWIN__) || \ defined(_WIN64) || defined(_WIN32) || defined(__TOS_WIN__) || \ defined(__WINDOWS__) #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ #elif defined(__BIG_ENDIAN__) || \ (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \ defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \ defined(__MIPSEB__) || defined(_MIPSEB) || defined(__MIPSEB) || \ defined(__m68k__) || defined(M68000) || defined(__hppa__) || \ defined(__hppa) || defined(__HPPA__) || defined(__sparc__) || \ defined(__sparc) || defined(__370__) || defined(__THW_370__) || \ defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__) #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ #else #error __BYTE_ORDER__ should be defined. #endif /* Arch */ #endif #endif /* __BYTE_ORDER__ || __ORDER_LITTLE_ENDIAN__ || __ORDER_BIG_ENDIAN__ */ /*----------------------------------------------------------------------------*/ /* Availability of CMOV or equivalent */ #ifndef MDBX_HAVE_CMOV #if defined(__e2k__) #define MDBX_HAVE_CMOV 1 #elif defined(__thumb2__) || defined(__thumb2) #define MDBX_HAVE_CMOV 1 #elif defined(__thumb__) || defined(__thumb) || defined(__TARGET_ARCH_THUMB) #define MDBX_HAVE_CMOV 0 #elif defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || \ defined(__aarch64) || defined(__arm__) || defined(__arm) || \ defined(__CC_ARM) #define MDBX_HAVE_CMOV 1 #elif (defined(__riscv__) || defined(__riscv64)) && \ (defined(__riscv_b) || defined(__riscv_bitmanip)) #define MDBX_HAVE_CMOV 1 #elif defined(i686) || defined(__i686) || defined(__i686__) || \ (defined(_M_IX86) && _M_IX86 > 600) || defined(__x86_64) || \ defined(__x86_64__) || defined(__amd64__) || defined(__amd64) || \ defined(_M_X64) || defined(_M_AMD64) #define MDBX_HAVE_CMOV 1 #else #define MDBX_HAVE_CMOV 0 #endif #endif /* MDBX_HAVE_CMOV */ /*----------------------------------------------------------------------------*/ /* Compiler's includes for builtins/intrinsics */ #if defined(_MSC_VER) || defined(__INTEL_COMPILER) #include #elif __GNUC_PREREQ(4, 4) || defined(__clang__) #if defined(__e2k__) #include #include #endif /* __e2k__ */ #if defined(__ia32__) #include #include #endif /* __ia32__ */ #ifdef __ARM_NEON #include #endif #elif defined(__SUNPRO_C) || defined(__sun) || defined(sun) #include #elif (defined(_HPUX_SOURCE) || defined(__hpux) || defined(__HP_aCC)) && \ (defined(HP_IA64) || defined(__ia64)) #include #elif defined(__IBMC__) && defined(__powerpc) #include #elif defined(_AIX) #include #include #elif (defined(__osf__) && defined(__DECC)) || defined(__alpha) #include #include #elif defined(__MWERKS__) /* CodeWarrior - troubles ? */ #pragma gcc_extensions #elif defined(__SNC__) /* Sony PS3 - troubles ? */ #elif defined(__hppa__) || defined(__hppa) #include #else #error Unsupported C compiler, please use GNU C 4.4 or newer #endif /* Compiler */ #if !defined(__noop) && !defined(_MSC_VER) #define __noop \ do { \ } while (0) #endif /* __noop */ #if defined(__fallthrough) && \ (defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)) #undef __fallthrough #endif /* __fallthrough workaround for MinGW */ #ifndef __fallthrough #if defined(__cplusplus) && (__has_cpp_attribute(fallthrough) && \ (!defined(__clang__) || __clang__ > 4)) || \ __cplusplus >= 201703L #define __fallthrough [[fallthrough]] #elif __GNUC_PREREQ(8, 0) && defined(__cplusplus) && __cplusplus >= 201103L #define __fallthrough [[fallthrough]] #elif __GNUC_PREREQ(7, 0) && \ (!defined(__LCC__) || (__LCC__ == 124 && __LCC_MINOR__ >= 12) || \ (__LCC__ == 125 && __LCC_MINOR__ >= 5) || (__LCC__ >= 126)) #define __fallthrough __attribute__((__fallthrough__)) #elif defined(__clang__) && defined(__cplusplus) && __cplusplus >= 201103L && \ __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") #define __fallthrough [[clang::fallthrough]] #else #define __fallthrough #endif #endif /* __fallthrough */ #ifndef __unreachable #if __GNUC_PREREQ(4, 5) || __has_builtin(__builtin_unreachable) #define __unreachable() __builtin_unreachable() #elif defined(_MSC_VER) #define __unreachable() __assume(0) #else #define __unreachable() \ do { \ } while (1) #endif #endif /* __unreachable */ #ifndef __prefetch #if defined(__GNUC__) || defined(__clang__) || __has_builtin(__builtin_prefetch) #define __prefetch(ptr) __builtin_prefetch(ptr) #else #define __prefetch(ptr) \ do { \ (void)(ptr); \ } while (0) #endif #endif /* __prefetch */ #ifndef offsetof #define offsetof(type, member) __builtin_offsetof(type, member) #endif /* offsetof */ #ifndef container_of #define container_of(ptr, type, member) \ ((type *)((char *)(ptr)-offsetof(type, member))) #endif /* container_of */ /*----------------------------------------------------------------------------*/ #ifndef __always_inline #if defined(__GNUC__) || __has_attribute(__always_inline__) #define __always_inline __inline __attribute__((__always_inline__)) #elif defined(_MSC_VER) #define __always_inline __forceinline #else #define __always_inline #endif #endif /* __always_inline */ #ifndef __noinline #if defined(__GNUC__) || __has_attribute(__noinline__) #define __noinline __attribute__((__noinline__)) #elif defined(_MSC_VER) #define __noinline __declspec(noinline) #else #define __noinline #endif #endif /* __noinline */ #ifndef __must_check_result #if defined(__GNUC__) || __has_attribute(__warn_unused_result__) #define __must_check_result __attribute__((__warn_unused_result__)) #else #define __must_check_result #endif #endif /* __must_check_result */ #ifndef __nothrow #if defined(__cplusplus) #if __cplusplus < 201703L #define __nothrow throw() #else #define __nothrow noexcept(true) #endif /* __cplusplus */ #elif defined(__GNUC__) || __has_attribute(__nothrow__) #define __nothrow __attribute__((__nothrow__)) #elif defined(_MSC_VER) && defined(__cplusplus) #define __nothrow __declspec(nothrow) #else #define __nothrow #endif #endif /* __nothrow */ #ifndef __hidden #if defined(__GNUC__) || __has_attribute(__visibility__) #define __hidden __attribute__((__visibility__("hidden"))) #else #define __hidden #endif #endif /* __hidden */ #ifndef __optimize #if defined(__OPTIMIZE__) #if (defined(__GNUC__) && !defined(__clang__)) || __has_attribute(__optimize__) #define __optimize(ops) __attribute__((__optimize__(ops))) #else #define __optimize(ops) #endif #else #define __optimize(ops) #endif #endif /* __optimize */ #ifndef __hot #if defined(__OPTIMIZE__) #if defined(__clang__) && !__has_attribute(__hot__) && \ __has_attribute(__section__) && \ (defined(__linux__) || defined(__gnu_linux__)) /* just put frequently used functions in separate section */ #define __hot __attribute__((__section__("text.hot"))) __optimize("O3") #elif defined(__GNUC__) || __has_attribute(__hot__) #define __hot __attribute__((__hot__)) #else #define __hot __optimize("O3") #endif #else #define __hot #endif #endif /* __hot */ #ifndef __cold #if defined(__OPTIMIZE__) #if defined(__clang__) && !__has_attribute(__cold__) && \ __has_attribute(__section__) && \ (defined(__linux__) || defined(__gnu_linux__)) /* just put infrequently used functions in separate section */ #define __cold __attribute__((__section__("text.unlikely"))) __optimize("Os") #elif defined(__GNUC__) || __has_attribute(__cold__) #define __cold __attribute__((__cold__)) #else #define __cold __optimize("Os") #endif #else #define __cold #endif #endif /* __cold */ #ifndef __flatten #if defined(__OPTIMIZE__) && (defined(__GNUC__) || __has_attribute(__flatten__)) #define __flatten __attribute__((__flatten__)) #else #define __flatten #endif #endif /* __flatten */ #ifndef likely #if (defined(__GNUC__) || __has_builtin(__builtin_expect)) && \ !defined(__COVERITY__) #define likely(cond) __builtin_expect(!!(cond), 1) #else #define likely(x) (!!(x)) #endif #endif /* likely */ #ifndef unlikely #if (defined(__GNUC__) || __has_builtin(__builtin_expect)) && \ !defined(__COVERITY__) #define unlikely(cond) __builtin_expect(!!(cond), 0) #else #define unlikely(x) (!!(x)) #endif #endif /* unlikely */ #ifndef __anonymous_struct_extension__ #if defined(__GNUC__) #define __anonymous_struct_extension__ __extension__ #else #define __anonymous_struct_extension__ #endif #endif /* __anonymous_struct_extension__ */ #ifndef expect_with_probability #if defined(__builtin_expect_with_probability) || \ __has_builtin(__builtin_expect_with_probability) || __GNUC_PREREQ(9, 0) #define expect_with_probability(expr, value, prob) \ __builtin_expect_with_probability(expr, value, prob) #else #define expect_with_probability(expr, value, prob) (expr) #endif #endif /* expect_with_probability */ #ifndef MDBX_WEAK_IMPORT_ATTRIBUTE #ifdef WEAK_IMPORT_ATTRIBUTE #define MDBX_WEAK_IMPORT_ATTRIBUTE WEAK_IMPORT_ATTRIBUTE #elif __has_attribute(__weak__) && __has_attribute(__weak_import__) #define MDBX_WEAK_IMPORT_ATTRIBUTE __attribute__((__weak__, __weak_import__)) #elif __has_attribute(__weak__) || \ (defined(__GNUC__) && __GNUC__ >= 4 && defined(__ELF__)) #define MDBX_WEAK_IMPORT_ATTRIBUTE __attribute__((__weak__)) #else #define MDBX_WEAK_IMPORT_ATTRIBUTE #endif #endif /* MDBX_WEAK_IMPORT_ATTRIBUTE */ #ifndef MDBX_GOOFY_MSVC_STATIC_ANALYZER #ifdef _PREFAST_ #define MDBX_GOOFY_MSVC_STATIC_ANALYZER 1 #else #define MDBX_GOOFY_MSVC_STATIC_ANALYZER 0 #endif #endif /* MDBX_GOOFY_MSVC_STATIC_ANALYZER */ #if MDBX_GOOFY_MSVC_STATIC_ANALYZER || (defined(_MSC_VER) && _MSC_VER > 1919) #define MDBX_ANALYSIS_ASSUME(expr) __analysis_assume(expr) #ifdef _PREFAST_ #define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id) \ __pragma(prefast(suppress : warn_id)) #else #define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id) \ __pragma(warning(suppress : warn_id)) #endif #else #define MDBX_ANALYSIS_ASSUME(expr) assert(expr) #define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id) #endif /* MDBX_GOOFY_MSVC_STATIC_ANALYZER */ /*----------------------------------------------------------------------------*/ #if defined(ENABLE_MEMCHECK) #include #ifndef VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE /* LY: available since Valgrind 3.10 */ #define VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(a, s) #define VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(a, s) #endif #elif !defined(RUNNING_ON_VALGRIND) #define VALGRIND_CREATE_MEMPOOL(h, r, z) #define VALGRIND_DESTROY_MEMPOOL(h) #define VALGRIND_MEMPOOL_TRIM(h, a, s) #define VALGRIND_MEMPOOL_ALLOC(h, a, s) #define VALGRIND_MEMPOOL_FREE(h, a) #define VALGRIND_MEMPOOL_CHANGE(h, a, b, s) #define VALGRIND_MAKE_MEM_NOACCESS(a, s) #define VALGRIND_MAKE_MEM_DEFINED(a, s) #define VALGRIND_MAKE_MEM_UNDEFINED(a, s) #define VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(a, s) #define VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(a, s) #define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a, s) (0) #define VALGRIND_CHECK_MEM_IS_DEFINED(a, s) (0) #define RUNNING_ON_VALGRIND (0) #endif /* ENABLE_MEMCHECK */ #ifdef __SANITIZE_ADDRESS__ #include #elif !defined(ASAN_POISON_MEMORY_REGION) #define ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size)) #define ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size)) #endif /* __SANITIZE_ADDRESS__ */ /*----------------------------------------------------------------------------*/ #ifndef ARRAY_LENGTH #ifdef __cplusplus template char (&__ArraySizeHelper(T (&array)[N]))[N]; #define ARRAY_LENGTH(array) (sizeof(::__ArraySizeHelper(array))) #else #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0])) #endif #endif /* ARRAY_LENGTH */ #ifndef ARRAY_END #define ARRAY_END(array) (&array[ARRAY_LENGTH(array)]) #endif /* ARRAY_END */ #define CONCAT(a, b) a##b #define XCONCAT(a, b) CONCAT(a, b) #define MDBX_TETRAD(a, b, c, d) \ ((uint32_t)(a) << 24 | (uint32_t)(b) << 16 | (uint32_t)(c) << 8 | (d)) #define MDBX_STRING_TETRAD(str) MDBX_TETRAD(str[0], str[1], str[2], str[3]) #define FIXME "FIXME: " __FILE__ ", " MDBX_STRINGIFY(__LINE__) #ifndef STATIC_ASSERT_MSG #if defined(static_assert) #define STATIC_ASSERT_MSG(expr, msg) static_assert(expr, msg) #elif defined(_STATIC_ASSERT) #define STATIC_ASSERT_MSG(expr, msg) _STATIC_ASSERT(expr) #elif defined(_MSC_VER) #include #define STATIC_ASSERT_MSG(expr, msg) _STATIC_ASSERT(expr) #elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ __has_feature(c_static_assert) #define STATIC_ASSERT_MSG(expr, msg) _Static_assert(expr, msg) #else #define STATIC_ASSERT_MSG(expr, msg) \ switch (0) { \ case 0: \ case (expr):; \ } #endif #endif /* STATIC_ASSERT */ #ifndef STATIC_ASSERT #define STATIC_ASSERT(expr) STATIC_ASSERT_MSG(expr, #expr) #endif #ifndef __Wpedantic_format_voidptr MDBX_MAYBE_UNUSED MDBX_PURE_FUNCTION static __inline const void * __Wpedantic_format_voidptr(const void *ptr) { return ptr; } #define __Wpedantic_format_voidptr(ARG) __Wpedantic_format_voidptr(ARG) #endif /* __Wpedantic_format_voidptr */