mirror of
https://github.com/isar/libmdbx.git
synced 2025-08-23 21:14:28 +08:00
mdbx: temporary workaround for Elbrus's libc bug.
https://bugs.mcst.ru/bugzilla/show_bug.cgi?id=2820
This commit is contained in:
111
src/mdbx.c
111
src/mdbx.c
@@ -37,6 +37,117 @@
|
||||
|
||||
#include "./bits.h"
|
||||
|
||||
/* LY: temporary workaround for Elbrus's memcmp() bug. */
|
||||
#if defined(__e2k__) && !__GLIBC_PREREQ(2, 24)
|
||||
int __hot mdbx_e2k_memcmp_bug_workaround(const void *s1, const void *s2,
|
||||
size_t n) {
|
||||
if (unlikely(n > 42
|
||||
/* LY: align followed access if reasonable possible */ &&
|
||||
(((uintptr_t)s1) & 7) != 0 &&
|
||||
(((uintptr_t)s1) & 7) == (((uintptr_t)s2) & 7))) {
|
||||
if (((uintptr_t)s1) & 1) {
|
||||
const int diff = *(uint8_t *)s1 - *(uint8_t *)s2;
|
||||
if (diff)
|
||||
return diff;
|
||||
s1 = (char *)s1 + 1;
|
||||
s2 = (char *)s2 + 1;
|
||||
n -= 1;
|
||||
}
|
||||
|
||||
if (((uintptr_t)s1) & 2) {
|
||||
const uint16_t a = *(uint16_t *)s1;
|
||||
const uint16_t b = *(uint16_t *)s2;
|
||||
if (likely(a != b))
|
||||
return (__builtin_bswap16(a) > __builtin_bswap16(b)) ? 1 : -1;
|
||||
s1 = (char *)s1 + 2;
|
||||
s2 = (char *)s2 + 2;
|
||||
n -= 2;
|
||||
}
|
||||
|
||||
if (((uintptr_t)s1) & 4) {
|
||||
const uint32_t a = *(uint32_t *)s1;
|
||||
const uint32_t b = *(uint32_t *)s2;
|
||||
if (likely(a != b))
|
||||
return (__builtin_bswap32(a) > __builtin_bswap32(b)) ? 1 : -1;
|
||||
s1 = (char *)s1 + 4;
|
||||
s2 = (char *)s2 + 4;
|
||||
n -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
while (n >= 8) {
|
||||
const uint64_t a = *(uint64_t *)s1;
|
||||
const uint64_t b = *(uint64_t *)s2;
|
||||
if (likely(a != b))
|
||||
return (__builtin_bswap64(a) > __builtin_bswap64(b)) ? 1 : -1;
|
||||
s1 = (char *)s1 + 8;
|
||||
s2 = (char *)s2 + 8;
|
||||
n -= 8;
|
||||
}
|
||||
|
||||
if (n & 4) {
|
||||
const uint32_t a = *(uint32_t *)s1;
|
||||
const uint32_t b = *(uint32_t *)s2;
|
||||
if (likely(a != b))
|
||||
return (__builtin_bswap32(a) > __builtin_bswap32(b)) ? 1 : -1;
|
||||
s1 = (char *)s1 + 4;
|
||||
s2 = (char *)s2 + 4;
|
||||
}
|
||||
|
||||
if (n & 2) {
|
||||
const uint16_t a = *(uint16_t *)s1;
|
||||
const uint16_t b = *(uint16_t *)s2;
|
||||
if (likely(a != b))
|
||||
return (__builtin_bswap16(a) > __builtin_bswap16(b)) ? 1 : -1;
|
||||
s1 = (char *)s1 + 2;
|
||||
s2 = (char *)s2 + 2;
|
||||
}
|
||||
|
||||
return (n & 1) ? *(uint8_t *)s1 - *(uint8_t *)s2 : 0;
|
||||
}
|
||||
|
||||
int __hot mdbx_e2k_strcmp_bug_workaround(const char *s1, const char *s2) {
|
||||
while (true) {
|
||||
int diff = *(uint8_t *)s1 - *(uint8_t *)s2;
|
||||
if (likely(diff != 0) || *s1 == '\0')
|
||||
return diff;
|
||||
s1 += 1;
|
||||
s2 += 1;
|
||||
}
|
||||
}
|
||||
|
||||
int __hot mdbx_e2k_strncmp_bug_workaround(const char *s1, const char *s2,
|
||||
size_t n) {
|
||||
while (n > 0) {
|
||||
int diff = *(uint8_t *)s1 - *(uint8_t *)s2;
|
||||
if (likely(diff != 0) || *s1 == '\0')
|
||||
return diff;
|
||||
s1 += 1;
|
||||
s2 += 1;
|
||||
n -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t __hot mdbx_e2k_strlen_bug_workaround(const char *s) {
|
||||
size_t n = 0;
|
||||
while (*s) {
|
||||
s += 1;
|
||||
n += 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t __hot mdbx_e2k_strnlen_bug_workaround(const char *s, size_t maxlen) {
|
||||
size_t n = 0;
|
||||
while (maxlen > n && *s) {
|
||||
s += 1;
|
||||
n += 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
#endif /* Elbrus's memcmp() bug. */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* rthc (tls keys and destructors) */
|
||||
|
||||
|
Reference in New Issue
Block a user