[core] realloc buffer power-2 size + 1 for '\0'
realloc buffer power-2 size + 1 for '\0' to avoid power-2 allocation doubling buffer size for sole reason of storing '\0' at end of blockpersonal/stbuehler/tests-path
parent
715699ba50
commit
ee9352b1bb
|
@ -67,6 +67,7 @@ static char* buffer_realloc(buffer * const restrict b, const size_t len) {
|
|||
const size_t psz = sz;
|
||||
for (sz = 256; sz < psz; sz <<= 1) ;
|
||||
}
|
||||
sz |= 1; /*(extra +1 for '\0' when needed buffer size is exact power-2)*/
|
||||
|
||||
b->size = sz;
|
||||
b->ptr = realloc(b->ptr, sz);
|
||||
|
@ -86,7 +87,8 @@ static char* buffer_alloc_replace(buffer * const restrict b, const size_t size)
|
|||
b->ptr = NULL;
|
||||
}
|
||||
/*(note: if size larger than one lshift, use size instead of power-2)*/
|
||||
return buffer_realloc(b, (b->size << 1) > size ? (b->size << 1)-1 : size);
|
||||
const size_t bsize2x = (b->size & ~1uL) << 1;
|
||||
return buffer_realloc(b, bsize2x > size ? bsize2x-1 : size);
|
||||
}
|
||||
|
||||
char* buffer_string_prepare_copy(buffer * const b, const size_t size) {
|
||||
|
@ -109,8 +111,9 @@ static char* buffer_string_prepare_append_resize(buffer * const restrict b, cons
|
|||
|
||||
/* not empty, b->used already includes a terminating 0 */
|
||||
/*(note: if size larger than one lshift, use size instead of power-2)*/
|
||||
const size_t req_size = ((b->size << 1) - b->used > size)
|
||||
? (b->size << 1)-1
|
||||
const size_t bsize2x = (b->size & ~1uL) << 1;
|
||||
const size_t req_size = (bsize2x - b->used > size)
|
||||
? bsize2x-1
|
||||
: b->used + size;
|
||||
|
||||
/* check for overflow: unsigned overflow is defined to wrap around */
|
||||
|
|
|
@ -147,7 +147,7 @@ __attribute_returns_nonnull__
|
|||
static buffer * chunk_buffer_acquire_sz(size_t sz) {
|
||||
chunk *c;
|
||||
buffer *b;
|
||||
if (sz <= chunk_buf_sz) {
|
||||
if (sz <= (chunk_buf_sz|1)) {
|
||||
if (chunks) {
|
||||
c = chunks;
|
||||
chunks = c->next;
|
||||
|
@ -183,7 +183,7 @@ void chunk_buffer_release(buffer *b) {
|
|||
chunk_buffers = c->next;
|
||||
c->mem = b;
|
||||
buffer_clear(b);
|
||||
if (b->size == chunk_buf_sz) {
|
||||
if (b->size == (chunk_buf_sz|1)) {
|
||||
c->next = chunks;
|
||||
chunks = c;
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ size_t chunk_buffer_prepare_append(buffer * const b, size_t sz) {
|
|||
|
||||
__attribute_returns_nonnull__
|
||||
static chunk * chunk_acquire(size_t sz) {
|
||||
if (sz <= chunk_buf_sz) {
|
||||
if (sz <= (chunk_buf_sz|1)) {
|
||||
if (chunks) {
|
||||
chunk *c = chunks;
|
||||
chunks = c->next;
|
||||
|
@ -235,7 +235,7 @@ static chunk * chunk_acquire(size_t sz) {
|
|||
|
||||
static void chunk_release(chunk *c) {
|
||||
const size_t sz = c->mem->size;
|
||||
if (sz == chunk_buf_sz) {
|
||||
if (sz == (chunk_buf_sz|1)) {
|
||||
chunk_reset(c);
|
||||
c->next = chunks;
|
||||
chunks = c;
|
||||
|
|
Loading…
Reference in New Issue