diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index d948369f3e..a4b53b33cd 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -957,7 +957,15 @@ PostmasterMain(int argc, char *argv[]) */ CreateDataDirLockFile(true); - /* read control file (error checking and contains config) */ + /* + * Read the control file (for error checking and config info). + * + * Since we verify the control file's CRC, this has a useful side effect + * on machines where we need a run-time test for CRC support instructions. + * The postmaster will do the test once at startup, and then its child + * processes will inherit the correct function pointer and not need to + * repeat the test. + */ LocalProcessControlFile(false); /* diff --git a/src/port/pg_crc32c_armv8_choose.c b/src/port/pg_crc32c_armv8_choose.c index d0d3a3da78..c339af7f16 100644 --- a/src/port/pg_crc32c_armv8_choose.c +++ b/src/port/pg_crc32c_armv8_choose.c @@ -18,11 +18,15 @@ *------------------------------------------------------------------------- */ -#include "c.h" +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif #include +#include -#include "libpq/pqsignal.h" #include "port/pg_crc32c.h" @@ -33,7 +37,7 @@ static sigjmp_buf illegal_instruction_jump; * isn't available, we expect to get SIGILL, which we can trap. */ static void -illegal_instruction_handler(int signo) +illegal_instruction_handler(SIGNAL_ARGS) { siglongjmp(illegal_instruction_jump, 1); } @@ -42,16 +46,35 @@ static bool pg_crc32c_armv8_available(void) { uint64 data = 42; - bool result; + int result; + /* + * Be careful not to do anything that might throw an error while we have + * the SIGILL handler set to a nonstandard value. + */ pqsignal(SIGILL, illegal_instruction_handler); if (sigsetjmp(illegal_instruction_jump, 1) == 0) - result = (pg_comp_crc32c_armv8(0, &data, sizeof(data)) == 0xdd439b0d); + { + /* Rather than hard-wiring an expected result, compare to SB8 code */ + result = (pg_comp_crc32c_armv8(0, &data, sizeof(data)) == + pg_comp_crc32c_sb8(0, &data, sizeof(data))); + } else - result = false; + { + /* We got the SIGILL trap */ + result = -1; + } pqsignal(SIGILL, SIG_DFL); - return result; +#ifndef FRONTEND + /* We don't expect this case, so complain loudly */ + if (result == 0) + elog(ERROR, "crc32 hardware and software results disagree"); + + elog(DEBUG1, "using armv8 crc32 hardware = %d", (result > 0)); +#endif + + return (result > 0); } /*