diff options
Diffstat (limited to 'libs/libmdbx/src')
| -rw-r--r-- | libs/libmdbx/src/Makefile | 19 | ||||
| -rw-r--r-- | libs/libmdbx/src/mdbx.h | 4 | ||||
| -rw-r--r-- | libs/libmdbx/src/src/lck-posix.c | 4 | ||||
| -rw-r--r-- | libs/libmdbx/src/src/lck-windows.c | 5 | ||||
| -rw-r--r-- | libs/libmdbx/src/src/mdbx.c | 26 | ||||
| -rw-r--r-- | libs/libmdbx/src/src/osal.c | 20 | ||||
| -rw-r--r-- | libs/libmdbx/src/src/osal.h | 6 | ||||
| -rw-r--r-- | libs/libmdbx/src/test/main.cc | 4 | ||||
| -rw-r--r-- | libs/libmdbx/src/test/utils.cc | 47 | 
9 files changed, 94 insertions, 41 deletions
diff --git a/libs/libmdbx/src/Makefile b/libs/libmdbx/src/Makefile index 11a6140f58..4faaaae525 100644 --- a/libs/libmdbx/src/Makefile +++ b/libs/libmdbx/src/Makefile @@ -86,7 +86,7 @@ check:	all  	&& ./mdbx_chk -vvn $(TESTDB) && ./mdbx_chk -vvn $(TESTDB)-copy  check-singleprocess:	all -	rm -f $(TESTDB) $(TESTLOG) && (set -o pipefail; ./mdbx_test --pathname=$(TESTDB) --dont-cleanup-after --hill | tee -a $(TESTLOG) | tail -n 42) \ +	rm -f $(TESTDB) $(TESTLOG) && (set -o pipefail; ./mdbx_test --pathname=$(TESTDB) --dont-cleanup-after --hill --copy | tee -a $(TESTLOG) | tail -n 42) \  	&& ./mdbx_chk -vvn $(TESTDB) && ./mdbx_chk -vvn $(TESTDB)-copy  check-fault:	all @@ -188,7 +188,7 @@ ci:  ############################################################################### -CROSS_LIST = alpha-linux-gnu-gcc mips-linux-gnu-gcc \ +CROSS_LIST = mips-linux-gnu-gcc \  	powerpc64-linux-gnu-gcc powerpc-linux-gnu-gcc \  	arm-linux-gnueabihf-gcc aarch64-linux-gnu-gcc @@ -197,12 +197,15 @@ CROSS_LIST = alpha-linux-gnu-gcc mips-linux-gnu-gcc \  # sh4-linux-gnu-gcc		- qemu troubles (pread syscall, etc)  # mips64-linux-gnuabi64-gcc	- qemu troubles (pread syscall, etc)  # sparc64-linux-gnu-gcc		- qemu troubles (fcntl for F_SETLK/F_GETLK) +# alpha-linux-gnu-gcc		- qemu (or gcc) troubles (coredump) +  CROSS_LIST_NOQEMU = hppa-linux-gnu-gcc s390x-linux-gnu-gcc \ -	sh4-linux-gnu-gcc mips64-linux-gnuabi64-gcc sparc64-linux-gnu-gcc +	sh4-linux-gnu-gcc mips64-linux-gnuabi64-gcc \ +	sparc64-linux-gnu-gcc alpha-linux-gnu-gcc  cross-gcc:  	@echo "CORRESPONDING CROSS-COMPILERs ARE REQUIRED." -	@echo "FOR INSTANCE: apt install g++-aarch64-linux-gnu g++-alpha-linux-gnu g++-arm-linux-gnueabihf g++-hppa-linux-gnu g++-mips-linux-gnu g++-mips64-linux-gnuabi64 g++-powerpc-linux-gnu g++-powerpc64-linux-gnu g++-s390x-linux-gnu g++-sh4-linux-gnu" +	@echo "FOR INSTANCE: apt install g++-aarch64-linux-gnu g++-alpha-linux-gnu g++-arm-linux-gnueabihf g++-hppa-linux-gnu g++-mips-linux-gnu g++-mips64-linux-gnuabi64 g++-powerpc-linux-gnu g++-powerpc64-linux-gnu g++-s390x-linux-gnu g++-sh4-linux-gnu g++-sparc64-linux-gnu"  	@for CC in $(CROSS_LIST_NOQEMU) $(CROSS_LIST); do \  		echo "===================== $$CC"; \  		$(MAKE) clean && CC=$$CC CXX=$$(echo $$CC | sed 's/-gcc/-g++/') EXE_LDFLAGS=-static $(MAKE) all || exit $$?; \ @@ -213,8 +216,12 @@ cross-gcc:  # Therefore it is impossible to run full multi-process tests.  cross-qemu:  	@echo "CORRESPONDING CROSS-COMPILERs AND QEMUs ARE REQUIRED." -	@echo "FOR INSTANCE: apt install binfmt-support qemu-user-static qemu-user qemu-system-arm qemu-system-mips qemu-system-misc qemu-system-ppc qemu-system-sparc g++-aarch64-linux-gnu g++-alpha-linux-gnu g++-arm-linux-gnueabihf g++-hppa-linux-gnu g++-mips-linux-gnu g++-mips64-linux-gnuabi64 g++-powerpc-linux-gnu g++-powerpc64-linux-gnu g++-s390x-linux-gnu g++-sh4-linux-gnu" +	@echo "FOR INSTANCE: " +	@echo "	1) apt install g++-aarch64-linux-gnu g++-alpha-linux-gnu g++-arm-linux-gnueabihf g++-hppa-linux-gnu g++-mips-linux-gnu g++-mips64-linux-gnuabi64 g++-powerpc-linux-gnu g++-powerpc64-linux-gnu g++-s390x-linux-gnu g++-sh4-linux-gnu g++-sparc64-linux-gnu" +	@echo "	2) apt install binfmt-support qemu-user-static qemu-user qemu-system-arm qemu-system-mips qemu-system-misc qemu-system-ppc qemu-system-sparc"  	@for CC in $(CROSS_LIST); do \  		echo "===================== $$CC + qemu"; \ -		$(MAKE) clean && CC=$$CC CXX=$$(echo $$CC | sed 's/-gcc/-g++/') EXE_LDFLAGS=-static $(MAKE) check-singleprocess || exit $$?; \ +		$(MAKE) clean && \ +			CC=$$CC CXX=$$(echo $$CC | sed 's/-gcc/-g++/') EXE_LDFLAGS=-static XCFLAGS="-DMDBX_SAFE4QEMU $(XCFLAGS)" \ +			$(MAKE) check-singleprocess || exit $$?; \  	done diff --git a/libs/libmdbx/src/mdbx.h b/libs/libmdbx/src/mdbx.h index 120d6847e4..c42f62aafa 100644 --- a/libs/libmdbx/src/mdbx.h +++ b/libs/libmdbx/src/mdbx.h @@ -1,4 +1,4 @@ -/* LICENSE AND COPYRUSTING ***************************************************** +/* LICENSE AND COPYRUSTING *****************************************************   *   * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru>   * and other libmdbx authors: please see AUTHORS file. @@ -1606,7 +1606,7 @@ LIBMDBX_API int mdbx_env_set_syncbytes(MDBX_env *env, size_t bytes);   * [out] percent  Percentage of page allocation in the database.   *   * Returns Number of transactions committed after the given was started for - * read, or -1 on failure. */ + * read, or negative value on failure. */  LIBMDBX_API int mdbx_txn_straggler(MDBX_txn *txn, int *percent);  /* A callback function for killing a laggard readers, diff --git a/libs/libmdbx/src/src/lck-posix.c b/libs/libmdbx/src/src/lck-posix.c index 9743955311..2633d44791 100644 --- a/libs/libmdbx/src/src/lck-posix.c +++ b/libs/libmdbx/src/src/lck-posix.c @@ -1,4 +1,4 @@ -/* +/*   * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru>   * and other libmdbx authors: please see AUTHORS file.   * All rights reserved. @@ -149,7 +149,7 @@ int __cold mdbx_lck_init(MDBX_env *env) {      goto bailout;  #endif /* MDBX_USE_ROBUST */ -#if _POSIX_C_SOURCE >= 199506L +#if _POSIX_C_SOURCE >= 199506L && !defined(MDBX_SAFE4QEMU)    rc = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT);    if (rc == ENOTSUP)      rc = pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_NONE); diff --git a/libs/libmdbx/src/src/lck-windows.c b/libs/libmdbx/src/src/lck-windows.c index c019a6d547..24fa09965c 100644 --- a/libs/libmdbx/src/src/lck-windows.c +++ b/libs/libmdbx/src/src/lck-windows.c @@ -663,6 +663,7 @@ MDBX_srwlock_function mdbx_srwlock_Init, mdbx_srwlock_AcquireShared,  MDBX_GetFileInformationByHandleEx mdbx_GetFileInformationByHandleEx;  MDBX_GetVolumeInformationByHandleW mdbx_GetVolumeInformationByHandleW;  MDBX_GetFinalPathNameByHandleW mdbx_GetFinalPathNameByHandleW; +MDBX_SetFileInformationByHandle mdbx_SetFileInformationByHandle;  MDBX_NtFsControlFile mdbx_NtFsControlFile;  static void mdbx_winnt_import(void) { @@ -699,6 +700,10 @@ static void mdbx_winnt_import(void) {        (MDBX_GetFinalPathNameByHandleW)GetProcAddress(            hKernel32dll, "GetFinalPathNameByHandleW"); +  mdbx_SetFileInformationByHandle = +      (MDBX_SetFileInformationByHandle)GetProcAddress( +          hKernel32dll, "SetFileInformationByHandle"); +    const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");    mdbx_NtFsControlFile =        (MDBX_NtFsControlFile)GetProcAddress(hNtdll, "NtFsControlFile"); diff --git a/libs/libmdbx/src/src/mdbx.c b/libs/libmdbx/src/src/mdbx.c index 926f9092d8..3203d30a30 100644 --- a/libs/libmdbx/src/src/mdbx.c +++ b/libs/libmdbx/src/src/mdbx.c @@ -1,4 +1,4 @@ -/* +/*   * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru>   * and other libmdbx authors: please see AUTHORS file.   * All rights reserved. @@ -1360,10 +1360,8 @@ const char *__cold mdbx_strerror(int errnum) {          FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,          errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer,          sizeof(buffer), NULL); -    if (size) { -      CharToOemBuffA(buffer, buffer, (DWORD)size); +    if (size)        msg = buffer; -    }  #else      if (errnum < 0) {        static char buffer[32]; @@ -5498,7 +5496,7 @@ fail:  int __cold mdbx_env_get_maxkeysize(MDBX_env *env) {    if (!env || env->me_signature != MDBX_ME_SIGNATURE || !env->me_maxkey_limit) -    return -MDBX_EINVAL; +    return (MDBX_EINVAL > 0) ? -MDBX_EINVAL : MDBX_EINVAL;    return env->me_maxkey_limit;  } @@ -7197,13 +7195,13 @@ static int mdbx_page_search(MDBX_cursor *mc, MDBX_val *key, int flags) {        return rc;      rc = mdbx_page_search(&mc2, &mc->mc_dbx->md_name, 0);      if (unlikely(rc != MDBX_SUCCESS)) -      return rc; +      return (rc == MDBX_NOTFOUND) ? MDBX_BAD_DBI : rc;      {        MDBX_val data;        int exact = 0;        MDBX_node *leaf = mdbx_node_search(&mc2, &mc->mc_dbx->md_name, &exact);        if (!exact) -        return MDBX_NOTFOUND; +        return MDBX_BAD_DBI;        if (unlikely((leaf->mn_flags & (F_DUPDATA | F_SUBDATA)) != F_SUBDATA))          return MDBX_INCOMPATIBLE; /* not a named DB */        rc = mdbx_node_read(&mc2, leaf, &data); @@ -12468,7 +12466,7 @@ int __cold mdbx_reader_list(MDBX_env *env, MDBX_msg_func *func, void *ctx) {    int rc = 0, first = 1;    if (unlikely(!env || !func)) -    return -MDBX_EINVAL; +    return (MDBX_EINVAL > 0) ? -MDBX_EINVAL : MDBX_EINVAL;    if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))      return MDBX_EBADSIGN; @@ -12798,7 +12796,7 @@ __attribute__((no_sanitize_thread, noinline))  int mdbx_txn_straggler(MDBX_txn *txn, int *percent)  {    if (unlikely(!txn)) -    return -MDBX_EINVAL; +    return (MDBX_EINVAL > 0) ? -MDBX_EINVAL : MDBX_EINVAL;    if (unlikely(txn->mt_signature != MDBX_MT_SIGNATURE))      return MDBX_EBADSIGN; @@ -12812,7 +12810,7 @@ int mdbx_txn_straggler(MDBX_txn *txn, int *percent)        *percent =            (int)((txn->mt_next_pgno * UINT64_C(100) + txn->mt_end_pgno / 2) /                  txn->mt_end_pgno); -    return -1; +    return 0;    }    txnid_t recent; @@ -13517,7 +13515,7 @@ __cold intptr_t mdbx_limits_keysize_max(intptr_t pagesize) {    else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||                      pagesize > (intptr_t)MAX_PAGESIZE ||                      !mdbx_is_power2((size_t)pagesize))) -    return -MDBX_EINVAL; +    return (MDBX_EINVAL > 0) ? -MDBX_EINVAL : MDBX_EINVAL;    return mdbx_maxkey(mdbx_nodemax(pagesize));  } @@ -13532,7 +13530,7 @@ __cold intptr_t mdbx_limits_dbsize_min(intptr_t pagesize) {    else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||                      pagesize > (intptr_t)MAX_PAGESIZE ||                      !mdbx_is_power2((size_t)pagesize))) -    return -MDBX_EINVAL; +    return (MDBX_EINVAL > 0) ? -MDBX_EINVAL : MDBX_EINVAL;    return MIN_PAGENO * pagesize;  } @@ -13543,7 +13541,7 @@ __cold intptr_t mdbx_limits_dbsize_max(intptr_t pagesize) {    else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||                      pagesize > (intptr_t)MAX_PAGESIZE ||                      !mdbx_is_power2((size_t)pagesize))) -    return -MDBX_EINVAL; +    return (MDBX_EINVAL > 0) ? -MDBX_EINVAL : MDBX_EINVAL;    const uint64_t limit = MAX_PAGENO * (uint64_t)pagesize;    return (limit < (intptr_t)MAX_MAPSIZE) ? (intptr_t)limit @@ -13556,7 +13554,7 @@ __cold intptr_t mdbx_limits_txnsize_max(intptr_t pagesize) {    else if (unlikely(pagesize < (intptr_t)MIN_PAGESIZE ||                      pagesize > (intptr_t)MAX_PAGESIZE ||                      !mdbx_is_power2((size_t)pagesize))) -    return -MDBX_EINVAL; +    return (MDBX_EINVAL > 0) ? -MDBX_EINVAL : MDBX_EINVAL;    return pagesize * (MDBX_DPL_TXNFULL - 1);  } diff --git a/libs/libmdbx/src/src/osal.c b/libs/libmdbx/src/src/osal.c index e5a1e69cb6..4650519348 100644 --- a/libs/libmdbx/src/src/osal.c +++ b/libs/libmdbx/src/src/osal.c @@ -741,11 +741,21 @@ int mdbx_filesize(mdbx_filehandle_t fd, uint64_t *length) {  int mdbx_ftruncate(mdbx_filehandle_t fd, uint64_t length) {  #if defined(_WIN32) || defined(_WIN64) -  LARGE_INTEGER li; -  li.QuadPart = length; -  return (SetFilePointerEx(fd, li, NULL, FILE_BEGIN) && SetEndOfFile(fd)) -             ? MDBX_SUCCESS -             : GetLastError(); +  if (mdbx_SetFileInformationByHandle) { +    FILE_END_OF_FILE_INFO EndOfFileInfo; +    EndOfFileInfo.EndOfFile.QuadPart = length; +    return mdbx_SetFileInformationByHandle(fd, FileEndOfFileInfo, +                                           &EndOfFileInfo, +                                           sizeof(FILE_END_OF_FILE_INFO)) +               ? MDBX_SUCCESS +               : GetLastError(); +  } else { +    LARGE_INTEGER li; +    li.QuadPart = length; +    return (SetFilePointerEx(fd, li, NULL, FILE_BEGIN) && SetEndOfFile(fd)) +               ? MDBX_SUCCESS +               : GetLastError(); +  }  #else    STATIC_ASSERT_MSG(sizeof(off_t) >= sizeof(size_t),                      "libmdbx requires 64-bit file I/O on 64-bit systems"); diff --git a/libs/libmdbx/src/src/osal.h b/libs/libmdbx/src/src/osal.h index 9f9d1a4429..101605be05 100644 --- a/libs/libmdbx/src/src/osal.h +++ b/libs/libmdbx/src/src/osal.h @@ -627,6 +627,12 @@ typedef DWORD(WINAPI *MDBX_GetFinalPathNameByHandleW)(_In_ HANDLE hFile,                                                        _In_ DWORD dwFlags);  extern MDBX_GetFinalPathNameByHandleW mdbx_GetFinalPathNameByHandleW; +typedef BOOL(WINAPI *MDBX_SetFileInformationByHandle)( +    _In_ HANDLE hFile, _In_ FILE_INFO_BY_HANDLE_CLASS FileInformationClass, +    _Out_ LPVOID lpFileInformation, _In_ DWORD dwBufferSize); + +extern MDBX_SetFileInformationByHandle mdbx_SetFileInformationByHandle; +  typedef NTSTATUS(NTAPI *MDBX_NtFsControlFile)(      IN HANDLE FileHandle, IN OUT HANDLE Event,      IN OUT PVOID /* PIO_APC_ROUTINE */ ApcRoutine, IN OUT PVOID ApcContext, diff --git a/libs/libmdbx/src/test/main.cc b/libs/libmdbx/src/test/main.cc index 275b7b136b..749d48f07d 100644 --- a/libs/libmdbx/src/test/main.cc +++ b/libs/libmdbx/src/test/main.cc @@ -376,6 +376,10 @@ int main(int argc, char *const argv[]) {    if (global::config::cleanup_before)      cleanup(); +  log_trace(">> probe entropy_ticks()"); +  entropy_ticks(); +  log_trace("<< probe entropy_ticks()"); +    if (global::actors.size() == 1) {      logging::setup("main");      global::singlemode = true; diff --git a/libs/libmdbx/src/test/utils.cc b/libs/libmdbx/src/test/utils.cc index 5a5290f057..622c4d09bd 100644 --- a/libs/libmdbx/src/test/utils.cc +++ b/libs/libmdbx/src/test/utils.cc @@ -1,4 +1,4 @@ -/* +/*   * Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>   * and other libmdbx authors: please see AUTHORS file.   * All rights reserved. @@ -186,14 +186,39 @@ uint64_t entropy_ticks(void) {    ticks |= low & /* zeroes if high part has changed */             ~(high_before - high_after);  #endif -#elif defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH > 7) +#elif (defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH > 7)) &&     \ +    !defined(MDBX_SAFE4QEMU)    uint64_t virtual_timer;    __asm __volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer));    return virtual_timer; -#elif defined(__ARM_ARCH) && __ARM_ARCH > 5 && __ARM_ARCH < 8 -  unsigned long pmccntr; -  __asm __volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr)); -  return pmccntr; +#elif (defined(__ARM_ARCH) && __ARM_ARCH > 5 && __ARM_ARCH < 8) ||             \ +    defined(_M_ARM) +  static uint32_t pmcntenset = 0x00425B00; +  if (unlikely(pmcntenset == 0x00425B00)) { +    uint32_t pmuseren; +#ifdef _M_ARM +    pmuseren = _MoveFromCoprocessor(15, 0, 9, 14, 0); +#else +    __asm("mrc p15, 0, %0, c9, c14, 0" : "=r"(pmuseren)); +#endif +    if (1 & pmuseren /* Is it allowed for user mode code? */) { +#ifdef _M_ARM +      pmcntenset = _MoveFromCoprocessor(15, 0, 9, 12, 1); +#else +      __asm("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcntenset)); +#endif +    } else +      pmcntenset = 0; +  } +  if (pmcntenset & 0x80000000ul /* Is it counting? */) { +#ifdef _M_ARM +    return __rdpmccntr64(); +#else +    uint32_t pmccntr; +    __asm __volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr)); +    return pmccntr; +#endif +  }  #elif defined(__mips__) || defined(__mips) || defined(_R4000)    unsigned count;    __asm __volatile("rdhwr %0, $2" : "=r"(count)); @@ -203,8 +228,6 @@ uint64_t entropy_ticks(void) {  #if defined(__e2k__) || defined(__ia32__)    return __rdtsc(); -#elif defined(_M_ARM) -  return __rdpmccntr64();  #elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)    LARGE_INTEGER PerformanceCount;    if (QueryPerformanceCounter(&PerformanceCount)) @@ -213,13 +236,13 @@ uint64_t entropy_ticks(void) {  #else    struct timespec ts;  #if defined(CLOCK_MONOTONIC_COARSE) -  clockid_t clock = CLOCK_MONOTONIC_COARSE; +  clockid_t clk_id = CLOCK_MONOTONIC_COARSE;  #elif defined(CLOCK_MONOTONIC_RAW) -  clockid_t clock = CLOCK_MONOTONIC_RAW; +  clockid_t clk_id = CLOCK_MONOTONIC_RAW;  #else -  clockid_t clock = CLOCK_MONOTONIC; +  clockid_t clk_id = CLOCK_MONOTONIC;  #endif -  int rc = clock_gettime(clock, &ts); +  int rc = clock_gettime(clk_id, &ts);    if (unlikely(rc))      failure_perror("clock_gettime()", rc);  | 
