MySQL 8.0.33
Source Code Documentation
ut0crc32.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2011, 2023, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27/** @file include/ut0crc32.h
28 CRC32 implementation
29
30 Created Aug 10, 2011 Vasil Dimov
31 *******************************************************/
32
33#ifndef ut0crc32_h
34#define ut0crc32_h
35
36#include "univ.i"
37
38/*
39- 1. some things depend on the compiling environment
40 - is it a compiler for which we even know how to use intrinsics?
41 - is it x86, arm64, or mac-arm?
42- 2. some depend on runtime environment
43 - is it x86 which has crc32?
44 - is it x86 which has pcmul?
45 - is it arm which has crc32?
46 - is it arm which has pcmul?
47- 3. some depend on the runtime usage:
48 - is it 0.5kb redo buffer, 16kb page, or something else?
49 - do you need the variant with swapped byte order?
50*/
51
52#if defined(__GNUC__) && defined(__x86_64__) || defined(_WIN32)
53#define CRC32_x86_64
54#ifdef _WIN32
55#define CRC32_x86_64_WIN
56#else /* _WIN32 */
57#define CRC32_x86_64_DEFAULT
58#endif /* _WIN32 */
59#elif defined(__aarch64__) && defined(__GNUC__)
60#define CRC32_ARM64
61#ifdef APPLE_ARM
62#define CRC32_ARM64_APPLE
63#else /* APPLE_ARM */
64#define CRC32_ARM64_DEFAULT
65#endif /* APPLE_ARM */
66#else
67#define CRC32_DEFAULT
68#endif /* defined(__aarch64__) && defined(__GNUC__) */
69
70/* At this point we have classified the system statically into exactly one of
71the possible cases:
72
73CRC32_x86_64
74 An environment in which we can use `cpuid` instruction to detect if it has
75 support for crc32 and pclmul instructions, which (if available) can be used
76 via _mm_crc32_u64 and _mm_clmulepi64_si128 respectively exposed by
77 nmmintrin.h and wmmintrin.h.
78 This is narrowed further into one of:
79
80 CRC32_x86_64_WIN
81 An environment which seems to be like Visual Studio, so we expect
82 intrin.h header exposing `__cpuid`, which we can use instead of inline
83 assembly, which is good as Visual Studio dialect of asm is different.
84 Also, __attribute__(target(...)) probably doesn't work on it.
85 CRC32_x86_64_DEFAULT
86 An environment which seems to be like gcc or clang, and thus we can use
87 inline assembly to get `cpuid`.
88 Also, we can/have to use __attribute__(target(...)) on functions which
89 use intrinsics, and may need to use __attribute__(flatten) at top level
90 to ensure that the run-time selection of target-specific variant of the
91 function happens just once at the top, not in every leaf, which would
92 break inlining and optimizations.
93CRC32_ARM64
94 An environment in which it is probable that __crc32cd and vmull_p64 could be
95 used for hardware accelerated crc32 and polynomial multiplication
96 computations, respectively. However we might need to perform some runtime
97 checks via getauxval() to see if this particular processor on which we run
98 supports them.
99 This is narrowed further into one of:
100
101 CRC32_ARM64_APPLE
102 An environment which seems to be like Apple's M1 processor, and we don't
103 expect to find sys/auxv.h header which defines getauxval() on it, yet we
104 also expect the __crc32cd and vmull_p64 to "just work" on it, without
105 checking getauxval().
106
107 CRC32_ARM64_DEFAULT
108 An environment which seems to be like a "regular" ARM64. Note that this
109 is not very specific term, as there are ARMv7-A, ARMv8-A, and the later
110 has two execution states AArch32 and AArch64. FWIW we use __aarch64__ to
111 detect this case. We still need to call getauxval() to see if particular
112 instruction set is available. We assume we run in 64-bit execution state
113 thus we use AT_HWCAP (as opposed to AT_HWCAP2).
114CRC32_DEFAULT
115 An environment in which we don't even know how to ask if the hardware
116 supports crc32 or polynomial multiplication and even if it does we don't
117 know how to ask it to do it anyway. We use software implementation of crc32.
118*/
119
120/** Initializes the data structures used by ut_crc32*(). Does not do any
121 allocations, would not hurt if called twice, but would be pointless. */
122void ut_crc32_init();
123
124/** The CRC-32C polynomial without the implicit highest 1 at x^32 */
125constexpr uint32_t CRC32C_POLYNOMIAL{0x1EDC6F41};
126
127/** Calculates CRC32.
128 @param ptr - data over which to calculate CRC32.
129 @param len - data length in bytes.
130 @return calculated hash */
131typedef uint32_t (*ut_crc32_func_t)(const byte *ptr, size_t len);
132
133/** Pointer to standard-compliant CRC32-C (using the GF(2) primitive polynomial
1340x11EDC6F41) calculation function picked by ut_crc32_init() as the fastest
135implementation for the current environment. */
137
138/** Calculates CRC32 using legacy algorithm, which uses big-endian byte ordering
139when converting byte sequence to integers - flips each full aligned 8-byte chunk
140within the buf, but not the initial and trailing unaligned fragments.
141ut_crc32_init() needs to be called at least once before calling this function.
142@param[in] buf data over which to calculate CRC32
143@param[in] len data length
144@return calculated hash */
145uint32_t ut_crc32_legacy_big_endian(const byte *buf, size_t len);
146
147/** Flag that tells whether the CPU supports CRC32 or not. */
148extern bool ut_crc32_cpu_enabled;
149
150/** Flag that tells whether the CPU supports polynomial multiplication or not.*/
151extern bool ut_poly_mul_cpu_enabled;
152
153#endif /* ut0crc32_h */
Definition: buf0block_hint.cc:29
Version control for database, common definitions, and include files.
uint32_t(* ut_crc32_func_t)(const byte *ptr, size_t len)
Calculates CRC32.
Definition: ut0crc32.h:131
bool ut_crc32_cpu_enabled
Flag that tells whether the CPU supports CRC32 or not.
Definition: crc32.cc:130
uint32_t ut_crc32_legacy_big_endian(const byte *buf, size_t len)
Calculates CRC32 using legacy algorithm, which uses big-endian byte ordering when converting byte seq...
Definition: crc32.cc:314
ut_crc32_func_t ut_crc32
Pointer to standard-compliant CRC32-C (using the GF(2) primitive polynomial 0x11EDC6F41) calculation ...
Definition: crc32.cc:128
void ut_crc32_init()
Initializes the data structures used by ut_crc32*().
Definition: crc32.cc:812
bool ut_poly_mul_cpu_enabled
Flag that tells whether the CPU supports polynomial multiplication or not.
Definition: crc32.cc:131
constexpr uint32_t CRC32C_POLYNOMIAL
The CRC-32C polynomial without the implicit highest 1 at x^32.
Definition: ut0crc32.h:125