diff -r f024313c08f1 -r 95b094472e9a src/buffer.c --- a/src/buffer.c Wed Nov 26 23:22:03 2025 +0100 +++ b/src/buffer.c Wed Nov 26 23:35:25 2025 +0100 @@ -261,32 +261,35 @@ } } +static size_t cx_buffer_calculate_minimum_capacity(size_t mincap) { + unsigned long pagesize = system_page_size(); + // if page size is larger than 64 KB - for some reason - truncate to 64 KB + if (pagesize > 65536) pagesize = 65536; + if (mincap < pagesize) { + // when smaller as one page, map to the next power of two + mincap--; + mincap |= mincap >> 1; + mincap |= mincap >> 2; + mincap |= mincap >> 4; + // last operation only needed for pages larger 4096 bytes + // but if/else would be more expensive than just doing this + mincap |= mincap >> 8; + mincap++; + } else { + // otherwise, map to a multiple of the page size + mincap -= mincap % pagesize; + mincap += pagesize; + // note: if newcap is already page aligned, + // this gives a full additional page (which is good) + } + return mincap; +} + int cxBufferMinimumCapacity(CxBuffer *buffer, size_t newcap) { if (newcap <= buffer->capacity) { return 0; } - - unsigned long pagesize = system_page_size(); - // if page size is larger than 64 KB - for some reason - truncate to 64 KB - if (pagesize > 65536) pagesize = 65536; - if (newcap < pagesize) { - // when smaller as one page, map to the next power of two - newcap--; - newcap |= newcap >> 1; - newcap |= newcap >> 2; - newcap |= newcap >> 4; - // last operation only needed for pages larger 4096 bytes - // but if/else would be more expensive than just doing this - newcap |= newcap >> 8; - newcap++; - } else { - // otherwise, map to a multiple of the page size - newcap -= newcap % pagesize; - newcap += pagesize; - // note: if newcap is already page aligned, - // this gives a full additional page (which is good) - } - + newcap = cx_buffer_calculate_minimum_capacity(newcap); return cxBufferReserve(buffer, newcap); } @@ -392,8 +395,17 @@ bool perform_flush = false; if (required > buffer->capacity) { if (buffer->flags & CX_BUFFER_AUTO_EXTEND) { - if (buffer->flush != NULL && required > buffer->flush->threshold) { - perform_flush = true; + if (buffer->flush != NULL) { + size_t newcap = cx_buffer_calculate_minimum_capacity(required); + if (newcap > buffer->flush->threshold) { + newcap = buffer->flush->threshold; + } + if (cxBufferReserve(buffer, newcap)) { + return total_flushed; // LCOV_EXCL_LINE + } + if (required > newcap) { + perform_flush = true; + } } else { if (cxBufferMinimumCapacity(buffer, required)) { return total_flushed; // LCOV_EXCL_LINE