7#include <ascii-chat/network/crc32.h>
8#include <ascii-chat/platform/system.h>
14#if defined(__aarch64__)
17#elif defined(__x86_64__) && defined(HAVE_CRC32_HW)
28static bool crc32_hw_available =
false;
29static atomic_bool crc32_hw_checked =
false;
31static void check_crc32_hw_support(
void) {
33 if (atomic_load(&crc32_hw_checked)) {
38 bool expected =
false;
39 if (!atomic_compare_exchange_strong(&crc32_hw_checked, &expected,
true)) {
43 while (!atomic_load(&crc32_hw_checked)) {
45 if (spin_count > 100) {
61 crc32_hw_available =
true;
65 crc32_hw_available =
true;
68#elif defined(ARCH_X86_64)
74 crc32_hw_available = (cpu_info[2] & (1 << 20)) != 0;
76 unsigned int eax, ebx, ecx, edx;
77 if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
78 crc32_hw_available = (ecx & bit_SSE4_2) != 0;
80 crc32_hw_available =
false;
85 crc32_hw_available =
false;
101__attribute__((target(
"arch=armv8-a+crc"))) static uint32_t crc32_arm_hw(const
void *data,
size_t len) {
102 const uint8_t *bytes = (
const uint8_t *)data;
103 uint32_t crc = 0xFFFFFFFF;
107 for (
size_t i = 0; i < len; i++) {
108 crc = __crc32cb(crc, bytes[i]);
118static uint32_t crc32_intel_hw(
const void *data,
size_t len) {
119 const uint8_t *bytes = (
const uint8_t *)data;
120 uint32_t crc = 0xFFFFFFFF;
123 for (
size_t i = 0; i < len; i++) {
124 crc = _mm_crc32_u8(crc, bytes[i]);
133 check_crc32_hw_support();
135 if (!crc32_hw_available) {
137 static bool logged_fallback =
false;
138 if (!logged_fallback) {
139 log_debug(
"Using software CRC32 (no hardware acceleration)");
140 logged_fallback =
true;
146 static bool logged_arm =
false;
148 log_debug(
"Using ARM64 hardware CRC32");
151 return crc32_arm_hw(data, len);
152#elif defined(ARCH_X86_64)
153 static bool logged_intel =
false;
155 log_debug(
"Using Intel x86_64 hardware CRC32 (SSE4.2)");
158 return crc32_intel_hw(data, len);
165 check_crc32_hw_support();
166 return crc32_hw_available;
172 const uint8_t *bytes = (
const uint8_t *)data;
173 uint32_t crc = 0xFFFFFFFF;
177 for (
size_t i = 0; i < len; i++) {
179 for (
int j = 0; j < 8; j++) {
181 crc = (crc >> 1) ^ 0x82F63B78;
__attribute__((constructor))
Register fork handlers for common module.
bool crc32_hw_is_available(void)
uint32_t asciichat_crc32_sw(const void *data, size_t len)
uint32_t asciichat_crc32_hw(const void *data, size_t len)