2024-05-19 22:07:58 +03:00
|
|
|
|
/// \copyright SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2024
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
/* Undefine the NDEBUG if debugging is enforced by MDBX_DEBUG */
|
|
|
|
|
#if (defined(MDBX_DEBUG) && MDBX_DEBUG > 0) || \
|
|
|
|
|
(defined(MDBX_FORCE_ASSERTIONS) && MDBX_FORCE_ASSERTIONS)
|
|
|
|
|
#undef NDEBUG
|
2024-11-04 20:42:39 +03:00
|
|
|
|
#ifndef MDBX_DEBUG
|
|
|
|
|
/* Чтобы избежать включения отладки только из-за включения assert-проверок */
|
|
|
|
|
#define MDBX_DEBUG 0
|
|
|
|
|
#endif
|
2024-05-19 22:07:58 +03:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/** Disables using GNU/Linux libc extensions.
|
|
|
|
|
* \ingroup build_option
|
|
|
|
|
* \note This option couldn't be moved to the options.h since dependent
|
|
|
|
|
* control macros/defined should be prepared before include the options.h */
|
|
|
|
|
#ifndef MDBX_DISABLE_GNU_SOURCE
|
|
|
|
|
#define MDBX_DISABLE_GNU_SOURCE 0
|
|
|
|
|
#endif
|
|
|
|
|
#if MDBX_DISABLE_GNU_SOURCE
|
|
|
|
|
#undef _GNU_SOURCE
|
|
|
|
|
#elif (defined(__linux__) || defined(__gnu_linux__)) && !defined(_GNU_SOURCE)
|
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
#endif /* MDBX_DISABLE_GNU_SOURCE */
|
|
|
|
|
|
|
|
|
|
/* Should be defined before any includes */
|
|
|
|
|
#if !defined(_FILE_OFFSET_BITS) && !defined(__ANDROID_API__) && \
|
|
|
|
|
!defined(ANDROID)
|
|
|
|
|
#define _FILE_OFFSET_BITS 64
|
|
|
|
|
#endif /* _FILE_OFFSET_BITS */
|
|
|
|
|
|
|
|
|
|
#if defined(__APPLE__) && !defined(_DARWIN_C_SOURCE)
|
|
|
|
|
#define _DARWIN_C_SOURCE
|
|
|
|
|
#endif /* _DARWIN_C_SOURCE */
|
|
|
|
|
|
|
|
|
|
#if (defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)) && \
|
|
|
|
|
!defined(__USE_MINGW_ANSI_STDIO)
|
|
|
|
|
#define __USE_MINGW_ANSI_STDIO 1
|
|
|
|
|
#endif /* MinGW */
|
|
|
|
|
|
|
|
|
|
#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32_WINNT
|
|
|
|
|
#define _WIN32_WINNT 0x0601 /* Windows 7 */
|
|
|
|
|
#endif /* _WIN32_WINNT */
|
|
|
|
|
|
|
|
|
|
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
|
|
|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
|
|
|
#endif /* _CRT_SECURE_NO_WARNINGS */
|
|
|
|
|
#if !defined(UNICODE)
|
|
|
|
|
#define UNICODE
|
|
|
|
|
#endif /* UNICODE */
|
|
|
|
|
|
|
|
|
|
#if !defined(_NO_CRT_STDIO_INLINE) && MDBX_BUILD_SHARED_LIBRARY && \
|
|
|
|
|
!defined(xMDBX_TOOLS) && MDBX_WITHOUT_MSVC_CRT
|
|
|
|
|
#define _NO_CRT_STDIO_INLINE
|
|
|
|
|
#endif /* _NO_CRT_STDIO_INLINE */
|
|
|
|
|
|
|
|
|
|
#elif !defined(_POSIX_C_SOURCE)
|
|
|
|
|
#define _POSIX_C_SOURCE 200809L
|
|
|
|
|
#endif /* Windows */
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
|
|
|
|
|
#ifndef NOMINMAX
|
|
|
|
|
#define NOMINMAX
|
|
|
|
|
#endif /* NOMINMAX */
|
|
|
|
|
|
|
|
|
|
/* Workaround for modern libstdc++ with CLANG < 4.x */
|
|
|
|
|
#if defined(__SIZEOF_INT128__) && !defined(__GLIBCXX_TYPE_INT_N_0) && \
|
|
|
|
|
defined(__clang__) && __clang_major__ < 4
|
|
|
|
|
#define __GLIBCXX_BITSIZE_INT_N_0 128
|
|
|
|
|
#define __GLIBCXX_TYPE_INT_N_0 __int128
|
|
|
|
|
#endif /* Workaround for modern libstdc++ with CLANG < 4.x */
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
/* Workaround for MSVC' header `extern "C"` vs `std::` redefinition bug */
|
|
|
|
|
#if defined(__SANITIZE_ADDRESS__) && !defined(_DISABLE_VECTOR_ANNOTATION)
|
|
|
|
|
#define _DISABLE_VECTOR_ANNOTATION
|
|
|
|
|
#endif /* _DISABLE_VECTOR_ANNOTATION */
|
|
|
|
|
#endif /* _MSC_VER */
|
|
|
|
|
|
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
#if _MSC_FULL_VER < 190024234
|
|
|
|
|
/* Actually libmdbx was not tested with compilers older than 19.00.24234 (Visual
|
|
|
|
|
* Studio 2015 Update 3). But you could remove this #error and try to continue
|
|
|
|
|
* at your own risk. In such case please don't rise up an issues related ONLY to
|
|
|
|
|
* old compilers.
|
2022-06-02 18:59:58 +03:00
|
|
|
|
*
|
2024-05-19 22:07:58 +03:00
|
|
|
|
* NOTE:
|
|
|
|
|
* Unfortunately, there are several different builds of "Visual Studio" that
|
|
|
|
|
* are called "Visual Studio 2015 Update 3".
|
2022-06-02 18:59:58 +03:00
|
|
|
|
*
|
2024-05-19 22:07:58 +03:00
|
|
|
|
* The 190024234 is used here because it is minimal version of Visual Studio
|
|
|
|
|
* that was used for build and testing libmdbx in recent years. Soon this
|
|
|
|
|
* value will be increased to 19.0.24241.7, since build and testing using
|
|
|
|
|
* "Visual Studio 2015" will be performed only at https://ci.appveyor.com.
|
|
|
|
|
*
|
|
|
|
|
* Please ask Microsoft (but not us) for information about version differences
|
|
|
|
|
* and how to and where you can obtain the latest "Visual Studio 2015" build
|
|
|
|
|
* with all fixes.
|
2022-06-02 18:59:58 +03:00
|
|
|
|
*/
|
2024-05-19 22:07:58 +03:00
|
|
|
|
#error \
|
|
|
|
|
"At least \"Microsoft C/C++ Compiler\" version 19.00.24234 (Visual Studio 2015 Update 3) is required."
|
|
|
|
|
#endif
|
|
|
|
|
#if _MSC_VER > 1800
|
|
|
|
|
#pragma warning(disable : 4464) /* relative include path contains '..' */
|
|
|
|
|
#endif
|
|
|
|
|
#if _MSC_VER > 1913
|
|
|
|
|
#pragma warning(disable : 5045) /* will insert Spectre mitigation... */
|
|
|
|
|
#endif
|
|
|
|
|
#if _MSC_VER > 1914
|
|
|
|
|
#pragma warning( \
|
|
|
|
|
disable : 5105) /* winbase.h(9531): warning C5105: macro expansion \
|
|
|
|
|
producing 'defined' has undefined behavior */
|
|
|
|
|
#endif
|
|
|
|
|
#if _MSC_VER < 1920
|
|
|
|
|
/* avoid "error C2219: syntax error: type qualifier must be after '*'" */
|
|
|
|
|
#define __restrict
|
|
|
|
|
#endif
|
|
|
|
|
#if _MSC_VER > 1930
|
|
|
|
|
#pragma warning(disable : 6235) /* <expression> is always a constant */
|
|
|
|
|
#pragma warning(disable : 6237) /* <expression> is never evaluated and might \
|
|
|
|
|
have side effects */
|
|
|
|
|
#endif
|
|
|
|
|
#pragma warning(disable : 4710) /* 'xyz': function not inlined */
|
|
|
|
|
#pragma warning(disable : 4711) /* function 'xyz' selected for automatic \
|
|
|
|
|
inline expansion */
|
|
|
|
|
#pragma warning(disable : 4201) /* nonstandard extension used: nameless \
|
|
|
|
|
struct/union */
|
|
|
|
|
#pragma warning(disable : 4702) /* unreachable code */
|
|
|
|
|
#pragma warning(disable : 4706) /* assignment within conditional expression */
|
|
|
|
|
#pragma warning(disable : 4127) /* conditional expression is constant */
|
|
|
|
|
#pragma warning(disable : 4324) /* 'xyz': structure was padded due to \
|
|
|
|
|
alignment specifier */
|
|
|
|
|
#pragma warning(disable : 4310) /* cast truncates constant value */
|
|
|
|
|
#pragma warning(disable : 4820) /* bytes padding added after data member for \
|
|
|
|
|
alignment */
|
|
|
|
|
#pragma warning(disable : 4548) /* expression before comma has no effect; \
|
|
|
|
|
expected expression with side - effect */
|
|
|
|
|
#pragma warning(disable : 4366) /* the result of the unary '&' operator may be \
|
|
|
|
|
unaligned */
|
|
|
|
|
#pragma warning(disable : 4200) /* nonstandard extension used: zero-sized \
|
|
|
|
|
array in struct/union */
|
|
|
|
|
#pragma warning(disable : 4204) /* nonstandard extension used: non-constant \
|
|
|
|
|
aggregate initializer */
|
|
|
|
|
#pragma warning( \
|
|
|
|
|
disable : 4505) /* unreferenced local function has been removed */
|
|
|
|
|
#endif /* _MSC_VER (warnings) */
|
|
|
|
|
|
|
|
|
|
#if defined(__GNUC__) && __GNUC__ < 9
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wattributes"
|
|
|
|
|
#endif /* GCC < 9 */
|
|
|
|
|
|
|
|
|
|
#include "../mdbx.h"
|
2022-06-02 18:59:58 +03:00
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* 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) */
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* basic C99 includes */
|
2024-05-19 22:07:58 +03:00
|
|
|
|
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
#include <assert.h>
|
2023-04-24 20:59:18 +03:00
|
|
|
|
#include <ctype.h>
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* feature testing */
|
|
|
|
|
|
|
|
|
|
#ifndef __has_warning
|
|
|
|
|
#define __has_warning(x) (0)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef __has_include
|
|
|
|
|
#define __has_include(x) (0)
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-05-19 22:07:58 +03:00
|
|
|
|
#ifndef __has_attribute
|
|
|
|
|
#define __has_attribute(x) (0)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef __has_cpp_attribute
|
|
|
|
|
#define __has_cpp_attribute(x) 0
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#ifndef __has_feature
|
|
|
|
|
#define __has_feature(x) (0)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef __has_extension
|
|
|
|
|
#define __has_extension(x) (0)
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-05-19 22:07:58 +03:00
|
|
|
|
#ifndef __has_builtin
|
|
|
|
|
#define __has_builtin(x) (0)
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#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 */
|
|
|
|
|
|
2024-05-19 22:07:58 +03:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* pre-requirements */
|
|
|
|
|
|
|
|
|
|
#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 defined(__GNUC__) && !__GNUC_PREREQ(4, 2)
|
|
|
|
|
/* Actually libmdbx was not tested with compilers older than GCC 4.2.
|
|
|
|
|
* But you could ignore this warning at your own risk.
|
|
|
|
|
* In such case please don't rise up an issues related ONLY to old compilers.
|
|
|
|
|
*/
|
|
|
|
|
#warning "libmdbx required GCC >= 4.2"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined(__clang__) && !__CLANG_PREREQ(3, 8)
|
|
|
|
|
/* Actually libmdbx was not tested with CLANG older than 3.8.
|
|
|
|
|
* But you could ignore this warning at your own risk.
|
|
|
|
|
* In such case please don't rise up an issues related ONLY to old compilers.
|
|
|
|
|
*/
|
|
|
|
|
#warning "libmdbx required CLANG >= 3.8"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined(__GLIBC__) && !__GLIBC_PREREQ(2, 12)
|
|
|
|
|
/* Actually libmdbx was not tested with something older than glibc 2.12.
|
|
|
|
|
* But you could ignore this warning at your own risk.
|
|
|
|
|
* In such case please don't rise up an issues related ONLY to old systems.
|
|
|
|
|
*/
|
|
|
|
|
#warning "libmdbx was only tested with GLIBC >= 2.12."
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef __SANITIZE_THREAD__
|
|
|
|
|
#warning \
|
|
|
|
|
"libmdbx don't compatible with ThreadSanitizer, you will get a lot of false-positive issues."
|
|
|
|
|
#endif /* __SANITIZE_THREAD__ */
|
|
|
|
|
|
2022-06-02 18:59:58 +03:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* C11' alignas() */
|
|
|
|
|
|
|
|
|
|
#if __has_include(<stdalign.h>)
|
|
|
|
|
#include <stdalign.h>
|
|
|
|
|
#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
|
|
|
|
|
|
2022-08-08 15:08:18 +03:00
|
|
|
|
#if defined(__APPLE__) || defined(_DARWIN_C_SOURCE)
|
2022-07-19 18:35:19 +02:00
|
|
|
|
#include <AvailabilityMacros.h>
|
2022-08-08 15:08:18 +03:00
|
|
|
|
#include <TargetConditionals.h>
|
2022-06-11 17:39:36 +03:00
|
|
|
|
#ifndef MAC_OS_X_VERSION_MIN_REQUIRED
|
|
|
|
|
#define MAC_OS_X_VERSION_MIN_REQUIRED 1070 /* Mac OS X 10.7, 2011 */
|
|
|
|
|
#endif
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#endif /* Apple OSX & iOS */
|
|
|
|
|
|
|
|
|
|
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
|
|
|
|
|
defined(__BSD__) || defined(__bsdi__) || defined(__DragonFly__) || \
|
|
|
|
|
defined(__APPLE__) || defined(__MACH__)
|
|
|
|
|
#include <sys/cdefs.h>
|
|
|
|
|
#include <sys/mount.h>
|
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
|
|
|
|
#include <vm/vm_param.h>
|
|
|
|
|
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
|
|
|
#include <uvm/uvm_param.h>
|
|
|
|
|
#else
|
|
|
|
|
#define SYSCTL_LEGACY_NONCONST_MIB
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef __MACH__
|
|
|
|
|
#include <sys/vmmeter.h>
|
|
|
|
|
#endif
|
|
|
|
|
#else
|
|
|
|
|
#include <malloc.h>
|
|
|
|
|
#if !(defined(__sun) || defined(__SVR4) || defined(__svr4__) || \
|
|
|
|
|
defined(_WIN32) || defined(_WIN64))
|
|
|
|
|
#include <mntent.h>
|
|
|
|
|
#endif /* !Solaris */
|
|
|
|
|
#endif /* !xBSD */
|
|
|
|
|
|
|
|
|
|
#if defined(__FreeBSD__) || __has_include(<malloc_np.h>)
|
|
|
|
|
#include <malloc_np.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined(__APPLE__) || defined(__MACH__) || __has_include(<malloc/malloc.h>)
|
|
|
|
|
#include <malloc/malloc.h>
|
|
|
|
|
#endif /* MacOS */
|
|
|
|
|
|
|
|
|
|
#if defined(__MACH__)
|
|
|
|
|
#include <mach/host_info.h>
|
|
|
|
|
#include <mach/mach_host.h>
|
|
|
|
|
#include <mach/mach_port.h>
|
|
|
|
|
#include <uuid/uuid.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined(__linux__) || defined(__gnu_linux__)
|
|
|
|
|
#include <sched.h>
|
|
|
|
|
#include <sys/sendfile.h>
|
|
|
|
|
#include <sys/statfs.h>
|
|
|
|
|
#endif /* Linux */
|
|
|
|
|
|
|
|
|
|
#ifndef _XOPEN_SOURCE
|
|
|
|
|
#define _XOPEN_SOURCE 0
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef _XOPEN_SOURCE_EXTENDED
|
|
|
|
|
#define _XOPEN_SOURCE_EXTENDED 0
|
|
|
|
|
#else
|
|
|
|
|
#include <utmpx.h>
|
|
|
|
|
#endif /* _XOPEN_SOURCE_EXTENDED */
|
|
|
|
|
|
|
|
|
|
#if defined(__sun) || defined(__SVR4) || defined(__svr4__)
|
|
|
|
|
#include <kstat.h>
|
|
|
|
|
#include <sys/mnttab.h>
|
|
|
|
|
/* 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 <windows.h>
|
|
|
|
|
#include <winnt.h>
|
|
|
|
|
#include <winternl.h>
|
|
|
|
|
|
2024-05-19 22:07:58 +03:00
|
|
|
|
/* После подгрузки windows.h, чтобы избежать проблем со сборкой MINGW и т.п. */
|
|
|
|
|
#include <excpt.h>
|
|
|
|
|
#include <tlhelp32.h>
|
|
|
|
|
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#else /*----------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#if !defined(_POSIX_MAPPED_FILES) || _POSIX_MAPPED_FILES < 1
|
|
|
|
|
#error "libmdbx requires the _POSIX_MAPPED_FILES feature"
|
|
|
|
|
#endif /* _POSIX_MAPPED_FILES */
|
|
|
|
|
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#include <semaphore.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <sys/file.h>
|
|
|
|
|
#include <sys/ipc.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#include <sys/param.h>
|
2022-10-24 01:02:38 +03:00
|
|
|
|
#include <sys/resource.h>
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/statvfs.h>
|
2022-10-24 01:02:38 +03:00
|
|
|
|
#include <sys/time.h>
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#include <sys/uio.h>
|
|
|
|
|
|
|
|
|
|
#endif /*---------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#if defined(__ANDROID_API__) || defined(ANDROID)
|
|
|
|
|
#include <android/log.h>
|
|
|
|
|
#if __ANDROID_API__ >= 21
|
|
|
|
|
#include <sys/sendfile.h>
|
|
|
|
|
#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(<sys/stat.h>)
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_SYS_TYPES_H) || __has_include(<sys/types.h>)
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_SYS_FILE_H) || __has_include(<sys/file.h>)
|
|
|
|
|
#include <sys/file.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* Byteorder */
|
|
|
|
|
|
|
|
|
|
#if defined(i386) || defined(__386) || defined(__i386) || defined(__i386__) || \
|
2022-11-14 18:03:20 +03:00
|
|
|
|
defined(i486) || defined(__i486) || defined(__i486__) || defined(i586) || \
|
|
|
|
|
defined(__i586) || defined(__i586__) || defined(i686) || \
|
2022-06-02 18:59:58 +03:00
|
|
|
|
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__ */
|
2022-07-26 14:29:22 +03:00
|
|
|
|
#if !defined(__amd64__) && \
|
|
|
|
|
(defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || \
|
|
|
|
|
defined(_M_X64) || defined(_M_AMD64))
|
2022-06-02 18:59:58 +03:00
|
|
|
|
/* 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(<endian.h>)
|
|
|
|
|
#include <endian.h>
|
|
|
|
|
#elif defined(__APPLE__) || defined(__MACH__) || defined(__OpenBSD__) || \
|
|
|
|
|
defined(HAVE_MACHINE_ENDIAN_H) || __has_include(<machine/endian.h>)
|
|
|
|
|
#include <machine/endian.h>
|
|
|
|
|
#elif defined(HAVE_SYS_ISA_DEFS_H) || __has_include(<sys/isa_defs.h>)
|
|
|
|
|
#include <sys/isa_defs.h>
|
|
|
|
|
#elif (defined(HAVE_SYS_TYPES_H) && defined(HAVE_SYS_ENDIAN_H)) || \
|
|
|
|
|
(__has_include(<sys/types.h>) && __has_include(<sys/endian.h>))
|
|
|
|
|
#include <sys/endian.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#elif defined(__bsdi__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
|
|
|
|
|
defined(__NetBSD__) || defined(HAVE_SYS_PARAM_H) || __has_include(<sys/param.h>)
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
|
#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__ */
|
|
|
|
|
|
2022-07-24 17:31:38 +03:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* 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 */
|
|
|
|
|
|
2022-06-02 18:59:58 +03:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* Compiler's includes for builtins/intrinsics */
|
|
|
|
|
|
|
|
|
|
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
|
|
|
|
#include <intrin.h>
|
|
|
|
|
#elif __GNUC_PREREQ(4, 4) || defined(__clang__)
|
2022-07-26 14:38:03 +03:00
|
|
|
|
#if defined(__e2k__)
|
|
|
|
|
#include <e2kintrin.h>
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#include <x86intrin.h>
|
2022-07-26 14:38:03 +03:00
|
|
|
|
#endif /* __e2k__ */
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#if defined(__ia32__)
|
|
|
|
|
#include <cpuid.h>
|
2022-07-26 14:38:03 +03:00
|
|
|
|
#include <x86intrin.h>
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#endif /* __ia32__ */
|
2022-08-18 01:10:27 +03:00
|
|
|
|
#ifdef __ARM_NEON
|
|
|
|
|
#include <arm_neon.h>
|
|
|
|
|
#endif
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#elif defined(__SUNPRO_C) || defined(__sun) || defined(sun)
|
|
|
|
|
#include <mbarrier.h>
|
|
|
|
|
#elif (defined(_HPUX_SOURCE) || defined(__hpux) || defined(__HP_aCC)) && \
|
|
|
|
|
(defined(HP_IA64) || defined(__ia64))
|
|
|
|
|
#include <machine/sys/inline.h>
|
|
|
|
|
#elif defined(__IBMC__) && defined(__powerpc)
|
|
|
|
|
#include <atomic.h>
|
|
|
|
|
#elif defined(_AIX)
|
|
|
|
|
#include <builtins.h>
|
|
|
|
|
#include <sys/atomic_op.h>
|
|
|
|
|
#elif (defined(__osf__) && defined(__DECC)) || defined(__alpha)
|
|
|
|
|
#include <c_asm.h>
|
|
|
|
|
#include <machine/builtins.h>
|
|
|
|
|
#elif defined(__MWERKS__)
|
|
|
|
|
/* CodeWarrior - troubles ? */
|
|
|
|
|
#pragma gcc_extensions
|
|
|
|
|
#elif defined(__SNC__)
|
|
|
|
|
/* Sony PS3 - troubles ? */
|
|
|
|
|
#elif defined(__hppa__) || defined(__hppa)
|
|
|
|
|
#include <machine/inline.h>
|
|
|
|
|
#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) \
|
2024-05-19 22:07:58 +03:00
|
|
|
|
((type *)((char *)(ptr) - offsetof(type, member)))
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#endif /* container_of */
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
2024-05-19 22:07:58 +03:00
|
|
|
|
/* useful attributes */
|
2022-06-02 18:59:58 +03:00
|
|
|
|
|
|
|
|
|
#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
|
2024-05-19 22:07:58 +03:00
|
|
|
|
#define __always_inline __inline
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#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__)
|
2023-02-13 16:24:52 +03:00
|
|
|
|
#if defined(__clang__) && !__has_attribute(__hot__) && \
|
2022-06-02 18:59:58 +03:00
|
|
|
|
__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__)
|
2023-02-13 16:24:52 +03:00
|
|
|
|
#define __hot __attribute__((__hot__))
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#else
|
|
|
|
|
#define __hot __optimize("O3")
|
|
|
|
|
#endif
|
|
|
|
|
#else
|
|
|
|
|
#define __hot
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* __hot */
|
|
|
|
|
|
|
|
|
|
#ifndef __cold
|
|
|
|
|
#if defined(__OPTIMIZE__)
|
2023-02-13 16:24:52 +03:00
|
|
|
|
#if defined(__clang__) && !__has_attribute(__cold__) && \
|
2022-06-02 18:59:58 +03:00
|
|
|
|
__has_attribute(__section__) && \
|
|
|
|
|
(defined(__linux__) || defined(__gnu_linux__))
|
|
|
|
|
/* just put infrequently used functions in separate section */
|
|
|
|
|
#define __cold __attribute__((__section__("text.unlikely"))) __optimize("Os")
|
2023-02-13 16:24:52 +03:00
|
|
|
|
#elif defined(__GNUC__) || __has_attribute(__cold__)
|
|
|
|
|
#define __cold __attribute__((__cold__))
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#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__ */
|
|
|
|
|
|
2022-08-08 15:06:27 +03:00
|
|
|
|
#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 */
|
|
|
|
|
|
2024-05-19 22:07:58 +03:00
|
|
|
|
#if !defined(__thread) && (defined(_MSC_VER) || defined(__DMC__))
|
|
|
|
|
#define __thread __declspec(thread)
|
|
|
|
|
#endif /* __thread */
|
|
|
|
|
|
|
|
|
|
#ifndef MDBX_EXCLUDE_FOR_GPROF
|
|
|
|
|
#ifdef ENABLE_GPROF
|
|
|
|
|
#define MDBX_EXCLUDE_FOR_GPROF \
|
|
|
|
|
__attribute__((__no_instrument_function__, \
|
|
|
|
|
__no_profile_instrument_function__))
|
|
|
|
|
#else
|
|
|
|
|
#define MDBX_EXCLUDE_FOR_GPROF
|
|
|
|
|
#endif /* ENABLE_GPROF */
|
|
|
|
|
#endif /* MDBX_EXCLUDE_FOR_GPROF */
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#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 */
|
|
|
|
|
|
2023-02-11 00:25:14 +03:00
|
|
|
|
#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 */
|
|
|
|
|
|
2023-02-22 17:48:05 +03:00
|
|
|
|
#if MDBX_GOOFY_MSVC_STATIC_ANALYZER || (defined(_MSC_VER) && _MSC_VER > 1919)
|
2023-02-11 00:25:14 +03:00
|
|
|
|
#define MDBX_ANALYSIS_ASSUME(expr) __analysis_assume(expr)
|
2023-02-22 17:48:05 +03:00
|
|
|
|
#ifdef _PREFAST_
|
|
|
|
|
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id) \
|
|
|
|
|
__pragma(prefast(suppress : warn_id))
|
2023-02-11 00:25:14 +03:00
|
|
|
|
#else
|
2023-02-22 17:48:05 +03:00
|
|
|
|
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id) \
|
|
|
|
|
__pragma(warning(suppress : warn_id))
|
2023-02-11 00:25:14 +03:00
|
|
|
|
#endif
|
2023-02-22 17:48:05 +03:00
|
|
|
|
#else
|
|
|
|
|
#define MDBX_ANALYSIS_ASSUME(expr) assert(expr)
|
|
|
|
|
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id)
|
|
|
|
|
#endif /* MDBX_GOOFY_MSVC_STATIC_ANALYZER */
|
2023-02-11 00:25:14 +03:00
|
|
|
|
|
2024-05-19 22:07:58 +03:00
|
|
|
|
#ifndef FLEXIBLE_ARRAY_MEMBERS
|
|
|
|
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
|
|
|
|
|
(!defined(__cplusplus) && defined(_MSC_VER))
|
|
|
|
|
#define FLEXIBLE_ARRAY_MEMBERS 1
|
|
|
|
|
#else
|
|
|
|
|
#define FLEXIBLE_ARRAY_MEMBERS 0
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* FLEXIBLE_ARRAY_MEMBERS */
|
|
|
|
|
|
2022-06-02 18:59:58 +03:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
2024-05-19 22:07:58 +03:00
|
|
|
|
/* Valgrind and Address Sanitizer */
|
2022-06-02 18:59:58 +03:00
|
|
|
|
|
2023-11-02 16:54:32 +03:00
|
|
|
|
#if defined(ENABLE_MEMCHECK)
|
2022-06-02 18:59:58 +03:00
|
|
|
|
#include <valgrind/memcheck.h>
|
|
|
|
|
#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)
|
2023-11-02 16:54:32 +03:00
|
|
|
|
#endif /* ENABLE_MEMCHECK */
|
2022-06-02 18:59:58 +03:00
|
|
|
|
|
|
|
|
|
#ifdef __SANITIZE_ADDRESS__
|
|
|
|
|
#include <sanitizer/asan_interface.h>
|
|
|
|
|
#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 <typename T, size_t N> 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 <crtdbg.h>
|
|
|
|
|
#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
|
|
|
|
|
|
2024-05-19 22:07:58 +03:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
|
|
|
|
/* LY: MSVC 2015/2017/2019 has buggy/inconsistent PRIuPTR/PRIxPTR macros
|
|
|
|
|
* for internal format-args checker. */
|
|
|
|
|
#undef PRIuPTR
|
|
|
|
|
#undef PRIiPTR
|
|
|
|
|
#undef PRIdPTR
|
|
|
|
|
#undef PRIxPTR
|
|
|
|
|
#define PRIuPTR "Iu"
|
|
|
|
|
#define PRIiPTR "Ii"
|
|
|
|
|
#define PRIdPTR "Id"
|
|
|
|
|
#define PRIxPTR "Ix"
|
|
|
|
|
#define PRIuSIZE "zu"
|
|
|
|
|
#define PRIiSIZE "zi"
|
|
|
|
|
#define PRIdSIZE "zd"
|
|
|
|
|
#define PRIxSIZE "zx"
|
|
|
|
|
#endif /* fix PRI*PTR for _MSC_VER */
|
|
|
|
|
|
|
|
|
|
#ifndef PRIuSIZE
|
|
|
|
|
#define PRIuSIZE PRIuPTR
|
|
|
|
|
#define PRIiSIZE PRIiPTR
|
|
|
|
|
#define PRIdSIZE PRIdPTR
|
|
|
|
|
#define PRIxSIZE PRIxPTR
|
|
|
|
|
#endif /* PRI*SIZE macros for MSVC */
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
#pragma warning(pop)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#if __has_warning("-Wnested-anon-types")
|
|
|
|
|
#if defined(__clang__)
|
|
|
|
|
#pragma clang diagnostic ignored "-Wnested-anon-types"
|
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wnested-anon-types"
|
|
|
|
|
#else
|
|
|
|
|
#pragma warning disable "nested-anon-types"
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* -Wnested-anon-types */
|
|
|
|
|
|
|
|
|
|
#if __has_warning("-Wconstant-logical-operand")
|
|
|
|
|
#if defined(__clang__)
|
|
|
|
|
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
|
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wconstant-logical-operand"
|
|
|
|
|
#else
|
|
|
|
|
#pragma warning disable "constant-logical-operand"
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* -Wconstant-logical-operand */
|
|
|
|
|
|
|
|
|
|
#if defined(__LCC__) && (__LCC__ <= 121)
|
|
|
|
|
/* bug #2798 */
|
|
|
|
|
#pragma diag_suppress alignment_reduction_ignored
|
|
|
|
|
#elif defined(__ICC)
|
|
|
|
|
#pragma warning(disable : 3453 1366)
|
|
|
|
|
#elif __has_warning("-Walignment-reduction-ignored")
|
|
|
|
|
#if defined(__clang__)
|
|
|
|
|
#pragma clang diagnostic ignored "-Walignment-reduction-ignored"
|
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
|
#pragma GCC diagnostic ignored "-Walignment-reduction-ignored"
|
|
|
|
|
#else
|
|
|
|
|
#pragma warning disable "alignment-reduction-ignored"
|
|
|
|
|
#endif
|
|
|
|
|
#endif /* -Walignment-reduction-ignored */
|