Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 510b8cb

Browse files
committed
Extend & revamp pg_bswap.h infrastructure.
Upcoming patches are going to address performance issues that involve slow system provided ntohs/htons etc. To address that expand pg_bswap.h to provide pg_ntoh{16,32,64}, pg_hton{16,32,64} and optimize their respective implementations by using compiler intrinsics for gcc compatible compilers and msvc. Fall back to manual implementations using shifts etc otherwise. Additionally remove multiple evaluation hazards from the existing BSWAP32/64 macros, by replacing them with inline functions when necessary. In the course of that the naming scheme is changed to pg_bswap16/32/64. Author: Andres Freund Discussion: https://postgr.es/m/20170927172019.gheidqy6xvlxb325@alap3.anarazel.de
1 parent 0008a10 commit 510b8cb

File tree

8 files changed

+159
-27
lines changed

8 files changed

+159
-27
lines changed

config/c-compiler.m4

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,23 @@ AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1,
224224
fi])# PGAC_C_TYPES_COMPATIBLE
225225

226226

227+
# PGAC_C_BUILTIN_BSWAP16
228+
# -------------------------
229+
# Check if the C compiler understands __builtin_bswap16(),
230+
# and define HAVE__BUILTIN_BSWAP16 if so.
231+
AC_DEFUN([PGAC_C_BUILTIN_BSWAP16],
232+
[AC_CACHE_CHECK(for __builtin_bswap16, pgac_cv__builtin_bswap16,
233+
[AC_COMPILE_IFELSE([AC_LANG_SOURCE(
234+
[static unsigned long int x = __builtin_bswap16(0xaabb);]
235+
)],
236+
[pgac_cv__builtin_bswap16=yes],
237+
[pgac_cv__builtin_bswap16=no])])
238+
if test x"$pgac_cv__builtin_bswap16" = xyes ; then
239+
AC_DEFINE(HAVE__BUILTIN_BSWAP16, 1,
240+
[Define to 1 if your compiler understands __builtin_bswap16.])
241+
fi])# PGAC_C_BUILTIN_BSWAP16
242+
243+
227244

228245
# PGAC_C_BUILTIN_BSWAP32
229246
# -------------------------

configure

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11816,6 +11816,30 @@ if test x"$pgac_cv__types_compatible" = xyes ; then
1181611816

1181711817
$as_echo "#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1" >>confdefs.h
1181811818

11819+
fi
11820+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap16" >&5
11821+
$as_echo_n "checking for __builtin_bswap16... " >&6; }
11822+
if ${pgac_cv__builtin_bswap16+:} false; then :
11823+
$as_echo_n "(cached) " >&6
11824+
else
11825+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
11826+
/* end confdefs.h. */
11827+
static unsigned long int x = __builtin_bswap16(0xaabb);
11828+
11829+
_ACEOF
11830+
if ac_fn_c_try_compile "$LINENO"; then :
11831+
pgac_cv__builtin_bswap16=yes
11832+
else
11833+
pgac_cv__builtin_bswap16=no
11834+
fi
11835+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
11836+
fi
11837+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap16" >&5
11838+
$as_echo "$pgac_cv__builtin_bswap16" >&6; }
11839+
if test x"$pgac_cv__builtin_bswap16" = xyes ; then
11840+
11841+
$as_echo "#define HAVE__BUILTIN_BSWAP16 1" >>confdefs.h
11842+
1181911843
fi
1182011844
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5
1182111845
$as_echo_n "checking for __builtin_bswap32... " >&6; }

configure.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,7 @@ PGAC_C_FUNCNAME_SUPPORT
13061306
PGAC_C_STATIC_ASSERT
13071307
PGAC_C_TYPEOF
13081308
PGAC_C_TYPES_COMPATIBLE
1309+
PGAC_C_BUILTIN_BSWAP16
13091310
PGAC_C_BUILTIN_BSWAP32
13101311
PGAC_C_BUILTIN_BSWAP64
13111312
PGAC_C_BUILTIN_CONSTANT_P

contrib/btree_gist/btree_uuid.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ uuid_2_double(const pg_uuid_t *u)
182182
* machine, byte-swap each half so we can use native uint64 arithmetic.
183183
*/
184184
#ifndef WORDS_BIGENDIAN
185-
uu[0] = BSWAP64(uu[0]);
186-
uu[1] = BSWAP64(uu[1]);
185+
uu[0] = pg_bswap64(uu[0]);
186+
uu[1] = pg_bswap64(uu[1]);
187187
#endif
188188

189189
/*

src/include/pg_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,9 @@
668668
/* Define to 1 if you have the <winldap.h> header file. */
669669
#undef HAVE_WINLDAP_H
670670

671+
/* Define to 1 if your compiler understands __builtin_bswap16. */
672+
#undef HAVE__BUILTIN_BSWAP16
673+
671674
/* Define to 1 if your compiler understands __builtin_bswap32. */
672675
#undef HAVE__BUILTIN_BSWAP32
673676

src/include/pg_config.h.win32

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@
493493
/* Define to 1 if you have the <winldap.h> header file. */
494494
/* #undef HAVE_WINLDAP_H */
495495

496+
/* Define to 1 if your compiler understands __builtin_bswap16. */
497+
/* #undef HAVE__BUILTIN_BSWAP16 */
498+
496499
/* Define to 1 if your compiler understands __builtin_bswap32. */
497500
/* #undef HAVE__BUILTIN_BSWAP32 */
498501

src/include/port/pg_bswap.h

Lines changed: 108 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@
33
* pg_bswap.h
44
* Byte swapping.
55
*
6-
* Macros for reversing the byte order of 32-bit and 64-bit unsigned integers.
6+
* Macros for reversing the byte order of 16, 32 and 64-bit unsigned integers.
77
* For example, 0xAABBCCDD becomes 0xDDCCBBAA. These are just wrappers for
88
* built-in functions provided by the compiler where support exists.
9-
* Elsewhere, beware of multiple evaluations of the arguments!
109
*
11-
* Note that the GCC built-in functions __builtin_bswap32() and
12-
* __builtin_bswap64() are documented as accepting single arguments of type
13-
* uint32_t and uint64_t respectively (these are also the respective return
14-
* types). Use caution when using these wrapper macros with signed integers.
10+
* Note that all of these functions accept unsigned integers as arguments and
11+
* return the same. Use caution when using these wrapper macros with signed
12+
* integers.
1513
*
1614
* Copyright (c) 2015-2017, PostgreSQL Global Development Group
1715
*
@@ -22,28 +20,114 @@
2220
#ifndef PG_BSWAP_H
2321
#define PG_BSWAP_H
2422

25-
#ifdef HAVE__BUILTIN_BSWAP32
26-
#define BSWAP32(x) __builtin_bswap32(x)
23+
24+
/* In all supported versions msvc provides _byteswap_* functions in stdlib.h */
25+
#ifdef _MSC_VER
26+
#include <stdlib.h>
27+
#endif
28+
29+
30+
/* implementation of uint16 pg_bswap16(uint16) */
31+
#if defined(HAVE__BUILTIN_BSWAP16)
32+
33+
#define pg_bswap16(x) __builtin_bswap16(x)
34+
35+
#elif defined(_MSC_VER)
36+
37+
#define pg_bswap16(x) _byteswap_ushort(x)
38+
39+
#else
40+
41+
static inline uint16
42+
pg_bswap16(uint16 x)
43+
{
44+
return
45+
((x << 8) & 0xff00) |
46+
((x >> 8) & 0x00ff);
47+
}
48+
49+
#endif /* HAVE__BUILTIN_BSWAP16 */
50+
51+
52+
/* implementation of uint32 pg_bswap32(uint32) */
53+
#if defined(HAVE__BUILTIN_BSWAP32)
54+
55+
#define pg_bswap32(x) __builtin_bswap32(x)
56+
57+
#elif defined(_MSC_VER)
58+
59+
#define pg_bswap32(x) _byteswap_ulong(x)
60+
2761
#else
28-
#define BSWAP32(x) ((((x) << 24) & 0xff000000) | \
29-
(((x) << 8) & 0x00ff0000) | \
30-
(((x) >> 8) & 0x0000ff00) | \
31-
(((x) >> 24) & 0x000000ff))
62+
63+
static inline uint32
64+
pg_bswap32(uint32 x)
65+
{
66+
return
67+
((x << 24) & 0xff000000) |
68+
((x << 8) & 0x00ff0000) |
69+
((x >> 8) & 0x0000ff00) |
70+
((x >> 24) & 0x000000ff);
71+
}
72+
3273
#endif /* HAVE__BUILTIN_BSWAP32 */
3374

34-
#ifdef HAVE__BUILTIN_BSWAP64
35-
#define BSWAP64(x) __builtin_bswap64(x)
75+
76+
/* implementation of uint64 pg_bswap64(uint64) */
77+
#if defined(HAVE__BUILTIN_BSWAP64)
78+
79+
#define pg_bswap64(x) __builtin_bswap64(x)
80+
81+
82+
#elif defined(_MSC_VER)
83+
84+
#define pg_bswap64(x) _byteswap_uint64(x)
85+
3686
#else
37-
#define BSWAP64(x) ((((x) << 56) & UINT64CONST(0xff00000000000000)) | \
38-
(((x) << 40) & UINT64CONST(0x00ff000000000000)) | \
39-
(((x) << 24) & UINT64CONST(0x0000ff0000000000)) | \
40-
(((x) << 8) & UINT64CONST(0x000000ff00000000)) | \
41-
(((x) >> 8) & UINT64CONST(0x00000000ff000000)) | \
42-
(((x) >> 24) & UINT64CONST(0x0000000000ff0000)) | \
43-
(((x) >> 40) & UINT64CONST(0x000000000000ff00)) | \
44-
(((x) >> 56) & UINT64CONST(0x00000000000000ff)))
87+
88+
static inline uint16
89+
pg_bswap64(uint16 x)
90+
{
91+
return
92+
((x << 56) & UINT64CONST(0xff00000000000000)) |
93+
((x << 40) & UINT64CONST(0x00ff000000000000)) |
94+
((x << 24) & UINT64CONST(0x0000ff0000000000)) |
95+
((x << 8) & UINT64CONST(0x000000ff00000000)) |
96+
((x >> 8) & UINT64CONST(0x00000000ff000000)) |
97+
((x >> 24) & UINT64CONST(0x0000000000ff0000)) |
98+
((x >> 40) & UINT64CONST(0x000000000000ff00)) |
99+
((x >> 56) & UINT64CONST(0x00000000000000ff));
100+
}
45101
#endif /* HAVE__BUILTIN_BSWAP64 */
46102

103+
104+
/*
105+
* Portable and fast equivalents for for ntohs, ntohl, htons, htonl,
106+
* additionally extended to 64 bits.
107+
*/
108+
#ifdef WORDS_BIGENDIAN
109+
110+
#define pg_hton16(x) (x)
111+
#define pg_hton32(x) (x)
112+
#define pg_hton64(x) (x)
113+
114+
#define pg_ntoh16(x) (x)
115+
#define pg_ntoh32(x) (x)
116+
#define pg_ntoh64(x) (x)
117+
118+
#else
119+
120+
#define pg_hton16(x) pg_bswap16(x)
121+
#define pg_hton32(x) pg_bswap32(x)
122+
#define pg_hton64(x) pg_bswap64(x)
123+
124+
#define pg_ntoh16(x) pg_bswap16(x)
125+
#define pg_ntoh32(x) pg_bswap32(x)
126+
#define pg_ntoh64(x) pg_bswap64(x)
127+
128+
#endif /* WORDS_BIGENDIAN */
129+
130+
47131
/*
48132
* Rearrange the bytes of a Datum from big-endian order into the native byte
49133
* order. On big-endian machines, this does nothing at all. Note that the C
@@ -60,9 +144,9 @@
60144
#define DatumBigEndianToNative(x) (x)
61145
#else /* !WORDS_BIGENDIAN */
62146
#if SIZEOF_DATUM == 8
63-
#define DatumBigEndianToNative(x) BSWAP64(x)
147+
#define DatumBigEndianToNative(x) pg_bswap64(x)
64148
#else /* SIZEOF_DATUM != 8 */
65-
#define DatumBigEndianToNative(x) BSWAP32(x)
149+
#define DatumBigEndianToNative(x) pg_bswap32(x)
66150
#endif /* SIZEOF_DATUM == 8 */
67151
#endif /* WORDS_BIGENDIAN */
68152

src/include/port/pg_crc32c.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ extern pg_crc32c (*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len)
7373
#define COMP_CRC32C(crc, data, len) \
7474
((crc) = pg_comp_crc32c_sb8((crc), (data), (len)))
7575
#ifdef WORDS_BIGENDIAN
76-
#define FIN_CRC32C(crc) ((crc) = BSWAP32(crc) ^ 0xFFFFFFFF)
76+
#define FIN_CRC32C(crc) ((crc) = pg_bswap32(crc) ^ 0xFFFFFFFF)
7777
#else
7878
#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
7979
#endif

0 commit comments

Comments
 (0)