]> git.kaiwu.me - haproxy.git/commitdiff
IMPORT: slz: get rid of the bogus USE_64BIT_QUEUE and check siezof(long) instead
authorWilly Tarreau <w@1wt.eu>
Mon, 31 Aug 2026 12:14:16 +0000 (14:14 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Tue, 1 Sep 2026 11:47:07 +0000 (13:47 +0200)
The USE_64BIT_QUEUE was set when it was suggested to rely on 64-bit
operations on the queue and dump 32 bits at once (thus never keeping
more than 32 bits in the queue). It was also used to decide whether
the queue was stored as u32 or u64. However, this check in the public
part (slz.h) depends on a definition in the private part (slz-prv.h)
that cannot be seen by application code. Luckily, slz.c includes its
headers in the wrong order so it gets the public part before the private
one, and uses the same layout, which is why it was not detected earlier.

Let's just get rid of this USE_64BIT_QUEUE definition. It's not accurate
and cannot be matched between public and private code. Let's instead rely
on __SIZEOF_LONG__ which conveys the info we need: is the CPU efficient
when working on 64-bit integers.

The comments were adjusted to explain the difference and why it's not
dramatic to fall back to the 32-bit queue (in effect it's around a 1%
perf loss).

This must be backported to 1.3.

This is libslz upstream commit 54cf477a1736b3e747af14ce1ec38d7c28b34cfc

include/import/slz-prv.h
include/import/slz.h
src/slz.c

index 1e9bb832c97631bab478d83689e4fda691fa92a1..d4b4c840d9073dca0249ab75197367acb534e66f 100644 (file)
@@ -35,7 +35,6 @@
 #if defined(__x86_64__)
 #define UNALIGNED_LE_OK
 #define UNALIGNED_FASTER
-#define USE_64BIT_QUEUE
 #define HAVE_FAST_MULT
 #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
 #define UNALIGNED_LE_OK
index 5c2d2e3ef7a1059322e3b270e4c2223161df439c..06ce35c453cbd7e9f71f62ebb873c2a4bca3681e 100644 (file)
@@ -67,10 +67,15 @@ enum {
 };
 
 struct slz_stream {
-#ifdef USE_64BIT_QUEUE
-       uint64_t queue; /* last pending bits, LSB first */
+#if defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ - 0 > 4)
+       /* Note below: the queue never contains more than 32 bits for the
+        * 64-bit one, or 8 bits for the 32-bit one since contents are dumped
+        * as soon as they're large enough (32b for the 64-bit one, 8b-24b for
+        * the 32-bit one).
+        */
+       uint64_t queue; /* last pending bits, LSB first, faster on 64-bit archs */
 #else
-       uint32_t queue; /* last pending bits, LSB first */
+       uint32_t queue; /* last pending bits, LSB first, faster on 32-bit archs */
 #endif
        uint32_t qbits; /* number of bits in queue, < 8 on 32-bit, < 32 on 64-bit */
        unsigned char *outbuf; /* set by encode() */
index f10e8475356e529468ac816df7ded9fb88c3ba79..4855bf1dcaf5401dc84b245a1132c31de15c5047 100644 (file)
--- a/src/slz.c
+++ b/src/slz.c
@@ -171,7 +171,7 @@ union ref {
        uint64_t by64;
 };
 
-#if defined(USE_64BIT_QUEUE) && defined(UNALIGNED_LE_OK)
+#if defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ - 0 > 4) && defined(UNALIGNED_LE_OK)
 
 /* enqueue code x of <xbits> bits (LSB aligned, at most 24) and copy complete
  * 32-bit words into output buffer. X must not contain non-zero bits above