uint-bset: add slot0 member

Add a fixed slot0 member for uint32_bset to have no allocations for
sizes < 64. This is a common use case for curl_easy_perform().

Closes #22561
This commit is contained in:
Stefan Eissing 2026-08-12 15:49:39 +02:00 committed by Daniel Stenberg
parent 507ee5d792
commit 743096a496
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 23 additions and 6 deletions

View file

@ -432,6 +432,8 @@ static CURLMcode multi_xfers_add(struct Curl_multi *multi,
/* make it a 64 multiple, since our bitsets grow by that and
* small (easy_multi) grows to at least 64 on first resize. */
new_size = (((used + min_unused) + 63) / 64) * 64;
if(new_size < 256) /* don't be too shy about it */
new_size = 256;
}
}
}

View file

@ -44,14 +44,22 @@ CURLcode Curl_uint32_bset_resize(struct uint32_bset *bset, uint32_t nmax)
DEBUGASSERT(bset->init == CURL_UINT32_BSET_MAGIC);
if(nslots != bset->nslots) {
uint64_t *slots = curlx_calloc(nslots, sizeof(uint64_t));
if(!slots)
return CURLE_OUT_OF_MEMORY;
uint64_t *slots;
if(nslots > 1) {
slots = curlx_calloc(nslots, sizeof(uint64_t));
if(!slots)
return CURLE_OUT_OF_MEMORY;
}
else {
bset->slot0 = 0;
slots = &bset->slot0;
}
if(bset->slots) {
if((bset->slots != slots) && nslots && bset->nslots) {
memcpy(slots, bset->slots,
(CURLMIN(nslots, bset->nslots) * sizeof(uint64_t)));
curlx_free(bset->slots);
if(bset->slots != &bset->slot0)
curlx_free(bset->slots);
}
bset->slots = slots;
bset->nslots = nslots;
@ -63,7 +71,8 @@ CURLcode Curl_uint32_bset_resize(struct uint32_bset *bset, uint32_t nmax)
void Curl_uint32_bset_destroy(struct uint32_bset *bset)
{
DEBUGASSERT(bset->init == CURL_UINT32_BSET_MAGIC);
curlx_free(bset->slots);
if(bset->slots != &bset->slot0)
curlx_free(bset->slots);
memset(bset, 0, sizeof(*bset));
}

View file

@ -39,6 +39,7 @@
struct uint32_bset {
uint64_t *slots;
uint64_t slot0;
uint32_t nslots;
uint32_t first_slot_used;
#ifdef DEBUGBUILD

View file

@ -126,6 +126,10 @@ static CURLcode test_unit3211(const char *arg)
{
UNITTEST_BEGIN_SIMPLE
static const uint32_t s0[] = {
/* spread numbers, some at slot edges */
0, 1, 4, 5, 8, 13, 17, 23, 24, 63,
};
static const uint32_t s1[] = {
/* spread numbers, some at slot edges */
0, 1, 4, 17, 63, 64, 65, 66, 90, 99,
@ -142,6 +146,7 @@ static CURLcode test_unit3211(const char *arg)
120, 121, 122, 123, 124, 125, 126, 127,
};
check_set("s0", 64, s0, CURL_ARRAYSIZE(s1));
check_set("s1", 100, s1, CURL_ARRAYSIZE(s1));
check_set("s2", 1000, s2, CURL_ARRAYSIZE(s2));