]> granicus.if.org Git - postgresql/blob - src/port/pg_crc32c_choose.c
Don't dump core when destroying an unused ParallelContext.
[postgresql] / src / port / pg_crc32c_choose.c
1 /*-------------------------------------------------------------------------
2  *
3  * pg_crc32c_choose.c
4  *        Choose which CRC-32C implementation to use, at runtime.
5  *
6  * Try to the special CRC instructions introduced in Intel SSE 4.2,
7  * if available on the platform we're running on, but fall back to the
8  * slicing-by-8 implementation otherwise.
9  *
10  * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
11  * Portions Copyright (c) 1994, Regents of the University of California
12  *
13  *
14  * IDENTIFICATION
15  *        src/port/pg_crc32c_choose.c
16  *
17  *-------------------------------------------------------------------------
18  */
19
20 #include "c.h"
21
22 #ifdef HAVE__GET_CPUID
23 #include <cpuid.h>
24 #endif
25
26 #ifdef HAVE__CPUID
27 #include <intrin.h>
28 #endif
29
30 #include "port/pg_crc32c.h"
31
32 static bool
33 pg_crc32c_sse42_available(void)
34 {
35         unsigned int exx[4] = {0, 0, 0, 0};
36
37 #if defined(HAVE__GET_CPUID)
38         __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
39 #elif defined(HAVE__CPUID)
40         __cpuid(exx, 1);
41 #else
42 #error cpuid instruction not available
43 #endif
44
45         return (exx[2] & (1 << 20)) != 0;       /* SSE 4.2 */
46 }
47
48 /*
49  * This gets called on the first call. It replaces the function pointer
50  * so that subsequent calls are routed directly to the chosen implementation.
51  */
52 static pg_crc32c
53 pg_comp_crc32c_choose(pg_crc32c crc, const void *data, size_t len)
54 {
55         if (pg_crc32c_sse42_available())
56                 pg_comp_crc32c = pg_comp_crc32c_sse42;
57         else
58                 pg_comp_crc32c = pg_comp_crc32c_sb8;
59
60         return pg_comp_crc32c(crc, data, len);
61 }
62
63 pg_crc32c       (*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len) = pg_comp_crc32c_choose;