From: Willy Tarreau Date: Mon, 31 Aug 2026 12:14:16 +0000 (+0200) Subject: IMPORT: slz: get rid of the bogus USE_64BIT_QUEUE and check siezof(long) instead X-Git-Tag: v3.5-dev6~33 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=818cd155e990042e19a4c63f39923f1661ffdc3c;p=haproxy.git IMPORT: slz: get rid of the bogus USE_64BIT_QUEUE and check siezof(long) instead 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 --- diff --git a/include/import/slz-prv.h b/include/import/slz-prv.h index 1e9bb832c..d4b4c840d 100644 --- a/include/import/slz-prv.h +++ b/include/import/slz-prv.h @@ -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 diff --git a/include/import/slz.h b/include/import/slz.h index 5c2d2e3ef..06ce35c45 100644 --- a/include/import/slz.h +++ b/include/import/slz.h @@ -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() */ diff --git a/src/slz.c b/src/slz.c index f10e84753..4855bf1dc 100644 --- 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 bits (LSB aligned, at most 24) and copy complete * 32-bit words into output buffer. X must not contain non-zero bits above