PostgreSQL Source Code  git master
pg_crc32c_sse42_choose.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_crc32c_sse42_choose.c
4  * Choose between Intel SSE 4.2 and software CRC-32C implementation.
5  *
6  * On first call, checks if the CPU we're running on supports Intel SSE
7  * 4.2. If it does, use the special SSE instructions for CRC-32C
8  * computation. Otherwise, fall back to the pure software implementation
9  * (slicing-by-8).
10  *
11  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
12  * Portions Copyright (c) 1994, Regents of the University of California
13  *
14  *
15  * IDENTIFICATION
16  * src/port/pg_crc32c_sse42_choose.c
17  *
18  *-------------------------------------------------------------------------
19  */
20 
21 #include "c.h"
22 
23 #ifdef HAVE__GET_CPUID
24 #include <cpuid.h>
25 #endif
26 
27 #ifdef HAVE__CPUID
28 #include <intrin.h>
29 #endif
30 
31 #include "port/pg_crc32c.h"
32 
33 static bool
35 {
36  unsigned int exx[4] = {0, 0, 0, 0};
37 
38 #if defined(HAVE__GET_CPUID)
39  __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
40 #elif defined(HAVE__CPUID)
41  __cpuid(exx, 1);
42 #else
43 #error cpuid instruction not available
44 #endif
45 
46  return (exx[2] & (1 << 20)) != 0; /* SSE 4.2 */
47 }
48 
49 /*
50  * This gets called on the first call. It replaces the function pointer
51  * so that subsequent calls are routed directly to the chosen implementation.
52  */
53 static pg_crc32c
55 {
57  pg_comp_crc32c = pg_comp_crc32c_sse42;
58  else
60 
61  return pg_comp_crc32c(crc, data, len);
62 }
63 
uint32 pg_crc32c
Definition: pg_crc32c.h:38
pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len)
Definition: pg_crc32c_sb8.c:35
const void size_t len
const void * data
return crc
pg_crc32c(* pg_comp_crc32c)(pg_crc32c crc, const void *data, size_t len)
static bool pg_crc32c_sse42_available(void)
static pg_crc32c pg_comp_crc32c_choose(pg_crc32c crc, const void *data, size_t len)