libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit a50b4d566f089ae46402a6f38096a0ff9c50eae2
parent 9998ca76905bb3b922c147281e13f4718bf72fe3
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Fri, 19 Apr 2019 22:07:37 +0300

mhd_bithelpers.h: use bytes swap instead of individual bytes
assignment when endianess is known to significantly speedup MD5 and
SHA256 calculations.
Use built-in bytes swap when available.

Diffstat:
Mconfigure.ac | 14++++++++++++++
Msrc/microhttpd/mhd_bithelpers.h | 78+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
2 files changed, 77 insertions(+), 15 deletions(-)

diff --git a/configure.ac b/configure.ac @@ -662,6 +662,20 @@ AX_CHECK_LINK_FLAG([-fno-strict-aliasing], AC_C_BIGENDIAN AC_C_VARARRAYS +AC_CACHE_CHECK([[whether __builtin_bswap32() is available]], + [[mhd_cv_func___builtin_bswap32_avail]], [dnl + AC_TRY_LINK([#include<stdint.h>],[uint32_t a = 1; uint32_t b = __builtin_bswap32(a); a = b;], + [[mhd_cv_func___builtin_bswap32_avail="yes"]], [[mhd_cv_func___builtin_bswap32_avail="no"]]) +]) +AS_IF([[test "x$mhd_cv_func___builtin_bswap32_avail" = "xyes"]], + [AC_DEFINE([[MHD_HAVE___BUILTIN_BSWAP32]], [[1]], [Define to 1 if you have __builtin_bswap32() builtin function])]) +AC_CACHE_CHECK([[whether __builtin_bswap64() is available]], + [[mhd_cv_func___builtin_bswap64_avail]], [dnl + AC_TRY_LINK([#include<stdint.h>],[uint64_t a = 1; uint32_t b = __builtin_bswap64(a); a = b;], + [[mhd_cv_func___builtin_bswap64_avail="yes"]], [[mhd_cv_func___builtin_bswap64_avail="no"]]) +]) +AS_IF([[test "x$mhd_cv_func___builtin_bswap64_avail" = "xyes"]], + [AC_DEFINE([[MHD_HAVE___BUILTIN_BSWAP64]], [[1]], [Define to 1 if you have __builtin_bswap64() builtin function])]) AC_CHECK_PROG([HAVE_CURL_BINARY],[curl],[yes],[no]) AM_CONDITIONAL([HAVE_CURL_BINARY],[test "x$HAVE_CURL_BINARY" = "xyes"]) diff --git a/src/microhttpd/mhd_bithelpers.h b/src/microhttpd/mhd_bithelpers.h @@ -29,6 +29,34 @@ #include "mhd_byteorder.h" #include <stdint.h> + +#ifdef MHD_HAVE___BUILTIN_BSWAP32 +#define _MHD_BYTES_SWAP32(value32) \ + ((uint32_t)__builtin_bswap32((uint32_t)value32)) +#else /* ! MHD_HAVE___BUILTIN_BSWAP32 */ +#define _MHD_BYTES_SWAP32(value32) \ + ( (((uint32_t)(value32)) << 24) | \ + ((((uint32_t)(value32)) & ((uint32_t)0x0000FF00)) << 8) | \ + ((((uint32_t)(value32)) & ((uint32_t)0x00FF0000)) >> 8) | \ + (((uint32_t)(value32)) >> 24) ) +#endif /* ! MHD_HAVE___BUILTIN_BSWAP32 */ + + +#ifdef MHD_HAVE___BUILTIN_BSWAP64 +#define _MHD_BYTES_SWAP64(value64) \ + ((uint64_t)__builtin_bswap64((uint64_t)value64)) +#else /* ! MHD_HAVE___BUILTIN_BSWAP64 */ +#define _MHD_BYTES_SWAP64(value64) \ + ( (((uint64_t)(value64)) << 56) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x000000000000FF00)) << 40) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x0000000000FF0000)) << 24) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x00000000FF000000)) << 8) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x000000FF00000000)) >> 8) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x0000FF0000000000)) >> 24) | \ + ((((uint64_t)(value64)) & ((uint64_t)0x00FF000000000000)) >> 40) | \ + (((uint64_t)(value64)) >> 56) ) +#endif /* ! MHD_HAVE___BUILTIN_BSWAP64 */ + /* _MHD_PUT_64BIT_LE (addr, value64) * put native-endian 64-bit value64 to addr * in little-endian mode. @@ -36,8 +64,12 @@ #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN #define _MHD_PUT_64BIT_LE(addr, value64) \ ((*(uint64_t*)(addr)) = (uint64_t)(value64)) -#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ -#define _MHD_PUT_64BIT_LE(addr, value64) do { \ +#elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN +#define _MHD_PUT_64BIT_LE(addr, value64) \ + ((*(uint64_t*)(addr)) = _MHD_BYTES_SWAP64(value64)) +#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ +#define _MHD_PUT_64BIT_LE(addr, value64) do { \ ((uint8_t*)(addr))[0] = (uint8_t)((uint64_t)(value64)); \ ((uint8_t*)(addr))[1] = (uint8_t)(((uint64_t)(value64)) >> 8); \ ((uint8_t*)(addr))[2] = (uint8_t)(((uint64_t)(value64)) >> 16); \ @@ -47,23 +79,27 @@ ((uint8_t*)(addr))[6] = (uint8_t)(((uint64_t)(value64)) >> 48); \ ((uint8_t*)(addr))[7] = (uint8_t)(((uint64_t)(value64)) >> 56); \ } while (0) -#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ /* _MHD_PUT_32BIT_LE (addr, value32) * put native-endian 32-bit value32 to addr * in little-endian mode. */ #if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN -#define _MHD_PUT_32BIT_LE(addr, value32) \ +#define _MHD_PUT_32BIT_LE(addr,value32) \ ((*(uint32_t*)(addr)) = (uint32_t)(value32)) -#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ -#define _MHD_PUT_32BIT_LE(addr, value32) do { \ +#elif _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN +#define _MHD_PUT_32BIT_LE(addr, value32) \ + ((*(uint32_t*)(addr)) = _MHD_BYTES_SWAP32(value32)) +#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ +#define _MHD_PUT_32BIT_LE(addr, value32) do { \ ((uint8_t*)(addr))[0] = (uint8_t)((uint32_t)(value32)); \ ((uint8_t*)(addr))[1] = (uint8_t)(((uint32_t)(value32)) >> 8); \ ((uint8_t*)(addr))[2] = (uint8_t)(((uint32_t)(value32)) >> 16); \ ((uint8_t*)(addr))[3] = (uint8_t)(((uint32_t)(value32)) >> 24); \ } while (0) -#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ /* _MHD_PUT_64BIT_BE (addr, value64) @@ -73,8 +109,12 @@ #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN #define _MHD_PUT_64BIT_BE(addr, value64) \ ((*(uint64_t*)(addr)) = (uint64_t)(value64)) -#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ -#define _MHD_PUT_64BIT_BE(addr, value64) do { \ +#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN +#define _MHD_PUT_64BIT_BE(addr, value64) \ + ((*(uint64_t*)(addr)) = _MHD_BYTES_SWAP64(value64)) +#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ +#define _MHD_PUT_64BIT_BE(addr, value64) do { \ ((uint8_t*)(addr))[7] = (uint8_t)((uint64_t)(value64)); \ ((uint8_t*)(addr))[6] = (uint8_t)(((uint64_t)(value64)) >> 8); \ ((uint8_t*)(addr))[5] = (uint8_t)(((uint64_t)(value64)) >> 16); \ @@ -84,7 +124,7 @@ ((uint8_t*)(addr))[1] = (uint8_t)(((uint64_t)(value64)) >> 48); \ ((uint8_t*)(addr))[0] = (uint8_t)(((uint64_t)(value64)) >> 56); \ } while (0) -#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ /* _MHD_PUT_32BIT_BE (addr, value32) * put native-endian 32-bit value32 to addr @@ -93,14 +133,18 @@ #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN #define _MHD_PUT_32BIT_BE(addr, value32) \ ((*(uint32_t*)(addr)) = (uint32_t)(value32)) -#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ -#define _MHD_PUT_32BIT_BE(addr, value32) do { \ +#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN +#define _MHD_PUT_32BIT_BE(addr, value32) \ + ((*(uint32_t*)(addr)) = _MHD_BYTES_SWAP32(value32)) +#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ +#define _MHD_PUT_32BIT_BE(addr, value32) do { \ ((uint8_t*)(addr))[3] = (uint8_t)((uint32_t)(value32)); \ ((uint8_t*)(addr))[2] = (uint8_t)(((uint32_t)(value32)) >> 8); \ ((uint8_t*)(addr))[1] = (uint8_t)(((uint32_t)(value32)) >> 16); \ ((uint8_t*)(addr))[0] = (uint8_t)(((uint32_t)(value32)) >> 24); \ } while (0) -#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ /* _MHD_GET_32BIT_BE (addr) * get big-endian 32-bit value storied at addr @@ -109,13 +153,17 @@ #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN #define _MHD_GET_32BIT_BE(addr) \ (*(uint32_t*)(addr)) -#else /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN +#define _MHD_GET_32BIT_BE(addr) \ + _MHD_BYTES_SWAP32(*(uint32_t*)(addr)) +#else /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ +/* Endianess was not detected or non-standard like PDP-endian */ #define _MHD_GET_32BIT_BE(addr) \ ( (((uint32_t)(((uint8_t*)addr)[0])) << 24) | \ (((uint32_t)(((uint8_t*)addr)[1])) << 16) | \ (((uint32_t)(((uint8_t*)addr)[2])) << 8) | \ ((uint32_t) (((uint8_t*)addr)[3])) ) -#endif /* _MHD_BYTE_ORDER != _MHD_BIG_ENDIAN */ +#endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */ /** * Rotate right 32-bit value by number of bits.