Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1c72ec6

Browse files
committed
Improve our method for probing the availability of ARM CRC instructions.
Instead of depending on glibc's getauxval() function, just try to execute the CRC code, and trap SIGILL if that happens. Thomas Munro Discussion: https://postgr.es/m/HE1PR0801MB1323D171938EABC04FFE7FA9E3110@HE1PR0801MB1323.eurprd08.prod.outlook.com
1 parent 40f52b1 commit 1c72ec6

File tree

4 files changed

+29
-73
lines changed

4 files changed

+29
-73
lines changed

configure

+2-43
Original file line numberDiff line numberDiff line change
@@ -17344,46 +17344,6 @@ fi
1734417344
fi
1734517345

1734617346

17347-
# In order to detect at runtime, if the ARM CRC Extension is available,
17348-
# we will do "getauxval(AT_HWCAP) & HWCAP_CRC32". Check if we have
17349-
# everything we need for that.
17350-
for ac_func in getauxval
17351-
do :
17352-
ac_fn_c_check_func "$LINENO" "getauxval" "ac_cv_func_getauxval"
17353-
if test "x$ac_cv_func_getauxval" = xyes; then :
17354-
cat >>confdefs.h <<_ACEOF
17355-
#define HAVE_GETAUXVAL 1
17356-
_ACEOF
17357-
17358-
fi
17359-
done
17360-
17361-
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
17362-
/* end confdefs.h. */
17363-
17364-
#include <sys/auxv.h>
17365-
#include <asm/hwcap.h>
17366-
17367-
int
17368-
main ()
17369-
{
17370-
17371-
#ifndef AT_HWCAP
17372-
#error AT_HWCAP not defined
17373-
#endif
17374-
#ifndef HWCAP_CRC32
17375-
#error HWCAP_CRC32 not defined
17376-
#endif
17377-
17378-
;
17379-
return 0;
17380-
}
17381-
_ACEOF
17382-
if ac_fn_c_try_compile "$LINENO"; then :
17383-
HAVE_HWCAP_CRC32=1
17384-
fi
17385-
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
17386-
1738717347
# Select CRC-32C implementation.
1738817348
#
1738917349
# If we are targeting a processor that has Intel SSE 4.2 instructions, we can
@@ -17414,9 +17374,8 @@ if test x"$USE_SLICING_BY_8_CRC32C" = x"" && test x"$USE_SSE42_CRC32C" = x"" &&
1741417374
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then
1741517375
USE_ARMV8_CRC32C=1
1741617376
else
17417-
# ARM CRC Extension, with runtime check? The getauxval() function and
17418-
# HWCAP_CRC32 are needed for the runtime check.
17419-
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$ac_cv_func_getauxval" = x"yes" && test x"$HAVE_HWCAP_CRC32" = x"1"; then
17377+
# ARM CRC Extension, with runtime check?
17378+
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes"; then
1742017379
USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK=1
1742117380
else
1742217381
# fall back to slicing-by-8 algorithm, which doesn't require any

configure.in

+2-19
Original file line numberDiff line numberDiff line change
@@ -2014,22 +2014,6 @@ if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then
20142014
fi
20152015
AC_SUBST(CFLAGS_ARMV8_CRC32C)
20162016

2017-
# In order to detect at runtime, if the ARM CRC Extension is available,
2018-
# we will do "getauxval(AT_HWCAP) & HWCAP_CRC32". Check if we have
2019-
# everything we need for that.
2020-
AC_CHECK_FUNCS([getauxval])
2021-
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
2022-
#include <sys/auxv.h>
2023-
#include <asm/hwcap.h>
2024-
], [
2025-
#ifndef AT_HWCAP
2026-
#error AT_HWCAP not defined
2027-
#endif
2028-
#ifndef HWCAP_CRC32
2029-
#error HWCAP_CRC32 not defined
2030-
#endif
2031-
])], [HAVE_HWCAP_CRC32=1])
2032-
20332017
# Select CRC-32C implementation.
20342018
#
20352019
# If we are targeting a processor that has Intel SSE 4.2 instructions, we can
@@ -2060,9 +2044,8 @@ if test x"$USE_SLICING_BY_8_CRC32C" = x"" && test x"$USE_SSE42_CRC32C" = x"" &&
20602044
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then
20612045
USE_ARMV8_CRC32C=1
20622046
else
2063-
# ARM CRC Extension, with runtime check? The getauxval() function and
2064-
# HWCAP_CRC32 are needed for the runtime check.
2065-
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$ac_cv_func_getauxval" = x"yes" && test x"$HAVE_HWCAP_CRC32" = x"1"; then
2047+
# ARM CRC Extension, with runtime check?
2048+
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes"; then
20662049
USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK=1
20672050
else
20682051
# fall back to slicing-by-8 algorithm, which doesn't require any

src/include/pg_config.h.in

-3
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,6 @@
239239
/* Define to 1 if you have the `getaddrinfo' function. */
240240
#undef HAVE_GETADDRINFO
241241

242-
/* Define to 1 if you have the `getauxval' function. */
243-
#undef HAVE_GETAUXVAL
244-
245242
/* Define to 1 if you have the `gethostbyname_r' function. */
246243
#undef HAVE_GETHOSTBYNAME_R
247244

src/port/pg_crc32c_armv8_choose.c

+25-8
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88
* computation. Otherwise, fall back to the pure software implementation
99
* (slicing-by-8).
1010
*
11-
* XXX: The glibc-specific getauxval() function, with the HWCAP_CRC32
12-
* flag, is used to determine if the CRC Extension is available on the
13-
* current platform. Is there a more portable way to determine that?
14-
*
1511
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
1612
* Portions Copyright (c) 1994, Regents of the University of California
1713
*
@@ -24,17 +20,38 @@
2420

2521
#include "c.h"
2622

27-
#include <sys/auxv.h>
28-
#include <asm/hwcap.h>
23+
#include <setjmp.h>
2924

25+
#include "libpq/pqsignal.h"
3026
#include "port/pg_crc32c.h"
3127

28+
29+
static sigjmp_buf illegal_instruction_jump;
30+
31+
/*
32+
* Probe by trying to execute pg_comp_crc32c_armv8(). If the instruction
33+
* isn't available, we expect to get SIGILL, which we can trap.
34+
*/
35+
static void
36+
illegal_instruction_handler(int signo)
37+
{
38+
siglongjmp(illegal_instruction_jump, 1);
39+
}
40+
3241
static bool
3342
pg_crc32c_armv8_available(void)
3443
{
35-
unsigned long auxv = getauxval(AT_HWCAP);
44+
uint64 data = 42;
45+
bool result;
46+
47+
pqsignal(SIGILL, illegal_instruction_handler);
48+
if (sigsetjmp(illegal_instruction_jump, 1) == 0)
49+
result = (pg_comp_crc32c_armv8(0, &data, sizeof(data)) == 0xdd439b0d);
50+
else
51+
result = false;
52+
pqsignal(SIGILL, SIG_DFL);
3653

37-
return (auxv & HWCAP_CRC32) != 0;
54+
return result;
3855
}
3956

4057
/*

0 commit comments

Comments
 (0)