mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-17 19:30:00 +08:00
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
This commit is contained in:
parent
40f52b16dd
commit
1c72ec6f49
45
configure
vendored
45
configure
vendored
@ -17344,46 +17344,6 @@ fi
|
||||
fi
|
||||
|
||||
|
||||
# In order to detect at runtime, if the ARM CRC Extension is available,
|
||||
# we will do "getauxval(AT_HWCAP) & HWCAP_CRC32". Check if we have
|
||||
# everything we need for that.
|
||||
for ac_func in getauxval
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "getauxval" "ac_cv_func_getauxval"
|
||||
if test "x$ac_cv_func_getauxval" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_GETAUXVAL 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <sys/auxv.h>
|
||||
#include <asm/hwcap.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
#ifndef AT_HWCAP
|
||||
#error AT_HWCAP not defined
|
||||
#endif
|
||||
#ifndef HWCAP_CRC32
|
||||
#error HWCAP_CRC32 not defined
|
||||
#endif
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
HAVE_HWCAP_CRC32=1
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
# Select CRC-32C implementation.
|
||||
#
|
||||
# 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"" &&
|
||||
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then
|
||||
USE_ARMV8_CRC32C=1
|
||||
else
|
||||
# ARM CRC Extension, with runtime check? The getauxval() function and
|
||||
# HWCAP_CRC32 are needed for the runtime check.
|
||||
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
|
||||
# ARM CRC Extension, with runtime check?
|
||||
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes"; then
|
||||
USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK=1
|
||||
else
|
||||
# fall back to slicing-by-8 algorithm, which doesn't require any
|
||||
|
21
configure.in
21
configure.in
@ -2014,22 +2014,6 @@ if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then
|
||||
fi
|
||||
AC_SUBST(CFLAGS_ARMV8_CRC32C)
|
||||
|
||||
# In order to detect at runtime, if the ARM CRC Extension is available,
|
||||
# we will do "getauxval(AT_HWCAP) & HWCAP_CRC32". Check if we have
|
||||
# everything we need for that.
|
||||
AC_CHECK_FUNCS([getauxval])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <sys/auxv.h>
|
||||
#include <asm/hwcap.h>
|
||||
], [
|
||||
#ifndef AT_HWCAP
|
||||
#error AT_HWCAP not defined
|
||||
#endif
|
||||
#ifndef HWCAP_CRC32
|
||||
#error HWCAP_CRC32 not defined
|
||||
#endif
|
||||
])], [HAVE_HWCAP_CRC32=1])
|
||||
|
||||
# Select CRC-32C implementation.
|
||||
#
|
||||
# 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"" &&
|
||||
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then
|
||||
USE_ARMV8_CRC32C=1
|
||||
else
|
||||
# ARM CRC Extension, with runtime check? The getauxval() function and
|
||||
# HWCAP_CRC32 are needed for the runtime check.
|
||||
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
|
||||
# ARM CRC Extension, with runtime check?
|
||||
if test x"$pgac_armv8_crc32c_intrinsics" = x"yes"; then
|
||||
USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK=1
|
||||
else
|
||||
# fall back to slicing-by-8 algorithm, which doesn't require any
|
||||
|
@ -239,9 +239,6 @@
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the `getauxval' function. */
|
||||
#undef HAVE_GETAUXVAL
|
||||
|
||||
/* Define to 1 if you have the `gethostbyname_r' function. */
|
||||
#undef HAVE_GETHOSTBYNAME_R
|
||||
|
||||
|
@ -8,10 +8,6 @@
|
||||
* computation. Otherwise, fall back to the pure software implementation
|
||||
* (slicing-by-8).
|
||||
*
|
||||
* XXX: The glibc-specific getauxval() function, with the HWCAP_CRC32
|
||||
* flag, is used to determine if the CRC Extension is available on the
|
||||
* current platform. Is there a more portable way to determine that?
|
||||
*
|
||||
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
@ -24,17 +20,38 @@
|
||||
|
||||
#include "c.h"
|
||||
|
||||
#include <sys/auxv.h>
|
||||
#include <asm/hwcap.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "port/pg_crc32c.h"
|
||||
|
||||
|
||||
static sigjmp_buf illegal_instruction_jump;
|
||||
|
||||
/*
|
||||
* Probe by trying to execute pg_comp_crc32c_armv8(). If the instruction
|
||||
* isn't available, we expect to get SIGILL, which we can trap.
|
||||
*/
|
||||
static void
|
||||
illegal_instruction_handler(int signo)
|
||||
{
|
||||
siglongjmp(illegal_instruction_jump, 1);
|
||||
}
|
||||
|
||||
static bool
|
||||
pg_crc32c_armv8_available(void)
|
||||
{
|
||||
unsigned long auxv = getauxval(AT_HWCAP);
|
||||
uint64 data = 42;
|
||||
bool result;
|
||||
|
||||
return (auxv & HWCAP_CRC32) != 0;
|
||||
pqsignal(SIGILL, illegal_instruction_handler);
|
||||
if (sigsetjmp(illegal_instruction_jump, 1) == 0)
|
||||
result = (pg_comp_crc32c_armv8(0, &data, sizeof(data)) == 0xdd439b0d);
|
||||
else
|
||||
result = false;
|
||||
pqsignal(SIGILL, SIG_DFL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user