greenplumn pg_crc32c_armv8_choose 源码

  • 2022-08-18
  • 浏览 (385)

greenplumn pg_crc32c_armv8_choose 代码

文件路径:/src/port/pg_crc32c_armv8_choose.c

/*-------------------------------------------------------------------------
 *
 * pg_crc32c_armv8_choose.c
 *	  Choose between ARMv8 and software CRC-32C implementation.
 *
 * On first call, checks if the CPU we're running on supports the ARMv8
 * CRC Extension. If it does, use the special instructions for CRC-32C
 * computation. Otherwise, fall back to the pure software implementation
 * (slicing-by-8).
 *
 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/port/pg_crc32c_armv8_choose.c
 *
 *-------------------------------------------------------------------------
 */

#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif

#include <setjmp.h>
#include <signal.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(SIGNAL_ARGS)
{
	siglongjmp(illegal_instruction_jump, 1);
}

static bool
pg_crc32c_armv8_available(void)
{
	uint64		data = 42;
	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)
	{
		/* 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
	{
		/* We got the SIGILL trap */
		result = -1;
	}
	pqsignal(SIGILL, SIG_DFL);

#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);
}

/*
 * This gets called on the first call. It replaces the function pointer
 * so that subsequent calls are routed directly to the chosen implementation.
 */
static pg_crc32c
pg_comp_crc32c_choose(pg_crc32c crc, const void *data, size_t len)
{
	if (pg_crc32c_armv8_available())
		pg_comp_crc32c = pg_comp_crc32c_armv8;
	else
		pg_comp_crc32c = pg_comp_crc32c_sb8;

	return pg_comp_crc32c(crc, data, len);
}

pg_crc32c	(*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len) = pg_comp_crc32c_choose;

相关信息

greenplumn 源码目录

相关文章

greenplumn chklocale 源码

greenplumn crypt 源码

greenplumn dirent 源码

greenplumn dirmod 源码

greenplumn dlopen 源码

greenplumn erand48 源码

greenplumn fls 源码

greenplumn fseeko 源码

greenplumn getaddrinfo 源码

greenplumn getopt 源码

0  赞