From 34ebad09dcc990cb025cd05e2795a1f218af6db1 Mon Sep 17 00:00:00 2001 From: Luke Chen Date: Tue, 11 Jan 2022 16:22:25 +1100 Subject: Import wiredtiger: 9347af9cb5271855cbea7719f1b57bfe94621912 from branch mongodb-5.2 ref: df8173e949..9347af9cb5 for: 5.2.0-rc5 WT-7236 Cache the result of the wiredtiger_crc32c_func() return value --- src/third_party/wiredtiger/import.data | 2 +- .../wiredtiger/src/checksum/arm64/crc32-arm64.c | 19 +++++++++++++---- .../wiredtiger/src/checksum/x86/crc32-x86.c | 24 ++++++++++++++++------ .../wiredtiger/src/checksum/zseries/crc32-s390x.c | 19 +++++++++++++---- .../wiredtiger/src/include/wiredtiger.in | 8 ++++---- 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index e531f95769b..e4df97c78ba 100644 --- a/src/third_party/wiredtiger/import.data +++ b/src/third_party/wiredtiger/import.data @@ -2,5 +2,5 @@ "vendor": "wiredtiger", "github": "wiredtiger/wiredtiger.git", "branch": "mongodb-5.2", - "commit": "df8173e94998ddd53638f68e9f6fb858f25f5648" + "commit": "9347af9cb5271855cbea7719f1b57bfe94621912" } diff --git a/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c b/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c index 3ca1dfed4ba..de13cd6878b 100644 --- a/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c +++ b/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c @@ -100,13 +100,24 @@ extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t); */ uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t) { + static uint32_t (*crc32c_func)(const void *, size_t); #if defined(__linux__) && !defined(HAVE_NO_CRC32_HARDWARE) - unsigned long caps = getauxval(AT_HWCAP); + unsigned long caps; +#endif + + /* + * This function calls slow hardware functions; if the application doesn't realize that, they + * may call it repeatedly rather than caching the result. + */ + if (crc32c_func != NULL) + return (crc32c_func); +#if defined(__linux__) && !defined(HAVE_NO_CRC32_HARDWARE) + caps = getauxval(AT_HWCAP); if (caps & HWCAP_CRC32) - return (__wt_checksum_hw); - return (__wt_checksum_sw); + return (crc32c_func = __wt_checksum_hw); + return (crc32c_func = __wt_checksum_sw); #else - return (__wt_checksum_sw); + return (crc32c_func = __wt_checksum_sw); #endif } diff --git a/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c b/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c index 266f56d4cc3..a96b793cee3 100644 --- a/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c +++ b/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c @@ -124,16 +124,28 @@ extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t); */ uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t) { + static uint32_t (*crc32c_func)(const void *, size_t); #if !defined(HAVE_NO_CRC32_HARDWARE) #if (defined(__amd64) || defined(__x86_64)) unsigned int eax, ebx, ecx, edx; +#endif +#endif + + /* + * This function calls slow hardware functions; if the application doesn't realize that, they + * may call it repeatedly rather than caching the result. + */ + if (crc32c_func != NULL) + return (crc32c_func); +#if !defined(HAVE_NO_CRC32_HARDWARE) +#if (defined(__amd64) || defined(__x86_64)) __asm__ __volatile__("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1)); #define CPUID_ECX_HAS_SSE42 (1 << 20) if (ecx & CPUID_ECX_HAS_SSE42) - return (__wt_checksum_hw); - return (__wt_checksum_sw); + return (crc32c_func = __wt_checksum_hw); + return (crc32c_func = __wt_checksum_sw); #elif defined(_M_AMD64) int cpuInfo[4]; @@ -142,12 +154,12 @@ uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t) #define CPUID_ECX_HAS_SSE42 (1 << 20) if (cpuInfo[2] & CPUID_ECX_HAS_SSE42) - return (__wt_checksum_hw); - return (__wt_checksum_sw); + return (crc32c_func = __wt_checksum_hw); + return (crc32c_func = __wt_checksum_sw); #else - return (__wt_checksum_sw); + return (crc32c_func = __wt_checksum_sw); #endif #else - return (__wt_checksum_sw); + return (crc32c_func = __wt_checksum_sw); #endif } diff --git a/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c index dfa1d9e03b2..8db4b254366 100644 --- a/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c +++ b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c @@ -106,14 +106,25 @@ extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t); */ uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t) { + static uint32_t (*crc32c_func)(const void *, size_t); #if defined(__linux__) && !defined(HAVE_NO_CRC32_HARDWARE) - unsigned long caps = getauxval(AT_HWCAP); + unsigned long caps; +#endif + + /* + * This function calls slow hardware functions; if the application doesn't realize that, they + * may call it on every request. + */ + if (crc32c_func != NULL) + return (crc32c_func); +#if defined(__linux__) && !defined(HAVE_NO_CRC32_HARDWARE) + caps = getauxval(AT_HWCAP); if (caps & HWCAP_S390_VX) - return (__wt_checksum_hw); + return (crc32c_func = __wt_checksum_hw); else - return (__wt_checksum_sw); + return (crc32c_func = __wt_checksum_sw); #else - return (__wt_checksum_sw); + return (crc32c_func = __wt_checksum_sw); #endif } diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in index f3223141e77..b8ac1cbbfdc 100644 --- a/src/third_party/wiredtiger/src/include/wiredtiger.in +++ b/src/third_party/wiredtiger/src/include/wiredtiger.in @@ -3663,13 +3663,13 @@ struct __wt_config_parser { /*! * Return a pointer to a function that calculates a CRC32C checksum. * - * The WiredTiger library CRC32C checksum function uses hardware support where - * available, else it falls back to a software implementation. + * The WiredTiger library CRC32C checksum function uses hardware support where available, else it + * falls back to a software implementation. Selecting a CRC32C checksum function can be slow, the + * return value should be cached by the caller for repeated use. * * @snippet ex_all.c Checksum a buffer * - * @returns a pointer to a function that takes a buffer and length and returns - * the CRC32C checksum + * @returns a pointer to a function that takes a buffer and length and returns the CRC32C checksum */ uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t) WT_ATTRIBUTE_LIBRARY_VISIBLE; -- cgit v1.2.1