diff options
author | Pierce Lopez <pierce.lopez@gmail.com> | 2021-09-16 23:21:26 -0400 |
---|---|---|
committer | Pierce Lopez <pierce.lopez@gmail.com> | 2021-09-16 23:21:26 -0400 |
commit | fd0ce993e92e581023f640f37ecaa2a10c75059b (patch) | |
tree | 79a0a830b901a7853a04f35f82753d4ff9e070e1 /buffer.c | |
parent | fabbf3b31074ed74b9f0657299836fe40e4e365a (diff) | |
download | libevent-fd0ce993e92e581023f640f37ecaa2a10c75059b.tar.gz |
buffer: do not round up allocation for reference-type chain objects
Skip rounding up memory allocations for:
* evbuffer_add_reference()
* evbuffer_add_buffer_reference()
* evbuffer_add_file_segment()
These chain objects only store small structs with references to
other things, and these small structs do not themselves grow, so
bumping up the allocation to MIN_BUFFER_SIZE (512 bytes) is wasteful.
Diffstat (limited to 'buffer.c')
-rw-r--r-- | buffer.c | 64 |
1 files changed, 37 insertions, 27 deletions
@@ -158,17 +158,7 @@ evbuffer_chain_new(size_t size) if (size > EVBUFFER_CHAIN_MAX - EVBUFFER_CHAIN_SIZE) return (NULL); - size += EVBUFFER_CHAIN_SIZE; - - /* get the next largest memory that can hold the buffer */ - if (size < EVBUFFER_CHAIN_MAX / 2) { - to_alloc = MIN_BUFFER_SIZE; - while (to_alloc < size) { - to_alloc <<= 1; - } - } else { - to_alloc = size; - } + to_alloc = size + EVBUFFER_CHAIN_SIZE; /* we get everything in one chunk */ if ((chain = mm_malloc(to_alloc)) == NULL) @@ -188,6 +178,29 @@ evbuffer_chain_new(size_t size) return (chain); } +static struct evbuffer_chain * +evbuffer_chain_new_membuf(size_t size) +{ + size_t to_alloc; + + if (size > EVBUFFER_CHAIN_MAX - EVBUFFER_CHAIN_SIZE) + return (NULL); + + size += EVBUFFER_CHAIN_SIZE; + + /* get the next largest memory that can hold the buffer */ + if (size < EVBUFFER_CHAIN_MAX / 2) { + to_alloc = MIN_BUFFER_SIZE; + while (to_alloc < size) { + to_alloc <<= 1; + } + } else { + to_alloc = size; + } + + return evbuffer_chain_new(to_alloc - EVBUFFER_CHAIN_SIZE); +} + static inline void evbuffer_chain_free(struct evbuffer_chain *chain) { @@ -326,7 +339,7 @@ static inline struct evbuffer_chain * evbuffer_chain_insert_new(struct evbuffer *buf, size_t datlen) { struct evbuffer_chain *chain; - if ((chain = evbuffer_chain_new(datlen)) == NULL) + if ((chain = evbuffer_chain_new_membuf(datlen)) == NULL) return NULL; evbuffer_chain_insert(buf, chain); return chain; @@ -849,7 +862,7 @@ PRESERVE_PINNED(struct evbuffer *src, struct evbuffer_chain **first, struct evbuffer_chain *tmp; EVUTIL_ASSERT(pinned == src->last_with_datap); - tmp = evbuffer_chain_new(chain->off); + tmp = evbuffer_chain_new_membuf(chain->off); if (!tmp) return -1; memcpy(tmp->buffer, chain->buffer + chain->misalign, @@ -1418,7 +1431,7 @@ evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size) size -= old_off; chain = chain->next; } else { - if ((tmp = evbuffer_chain_new(size)) == NULL) { + if ((tmp = evbuffer_chain_new_membuf(size)) == NULL) { event_warn("%s: out of memory", __func__); goto done; } @@ -1766,10 +1779,9 @@ evbuffer_add(struct evbuffer *buf, const void *data_in, size_t datlen) /* If there are no chains allocated for this buffer, allocate one * big enough to hold all the data. */ if (chain == NULL) { - chain = evbuffer_chain_new(datlen); + chain = evbuffer_chain_insert_new(buf, datlen); if (!chain) goto done; - evbuffer_chain_insert(buf, chain); } if ((chain->flags & EVBUFFER_IMMUTABLE) == 0) { @@ -1808,7 +1820,7 @@ evbuffer_add(struct evbuffer *buf, const void *data_in, size_t datlen) to_alloc <<= 1; if (datlen > to_alloc) to_alloc = datlen; - tmp = evbuffer_chain_new(to_alloc); + tmp = evbuffer_chain_new_membuf(to_alloc); if (tmp == NULL) goto done; @@ -1858,10 +1870,9 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen) chain = buf->first; if (chain == NULL) { - chain = evbuffer_chain_new(datlen); + chain = evbuffer_chain_insert_new(buf, datlen); if (!chain) goto done; - evbuffer_chain_insert(buf, chain); } /* we cannot touch immutable buffers */ @@ -1898,7 +1909,7 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen) } /* we need to add another chain */ - if ((tmp = evbuffer_chain_new(datlen)) == NULL) + if ((tmp = evbuffer_chain_new_membuf(datlen)) == NULL) goto done; buf->first = tmp; if (buf->last_with_datap == &buf->first && chain->off) @@ -2027,7 +2038,7 @@ evbuffer_expand_singlechain(struct evbuffer *buf, size_t datlen) * MAX_TO_COPY_IN_EXPAND bytes. */ /* figure out how much space we need */ size_t length = chain->off + datlen; - struct evbuffer_chain *tmp = evbuffer_chain_new(length); + struct evbuffer_chain *tmp = evbuffer_chain_new_membuf(length); if (tmp == NULL) goto err; @@ -2073,12 +2084,11 @@ evbuffer_expand_fast_(struct evbuffer *buf, size_t datlen, int n) if (chain == NULL || (chain->flags & EVBUFFER_IMMUTABLE)) { /* There is no last chunk, or we can't touch the last chunk. * Just add a new chunk. */ - chain = evbuffer_chain_new(datlen); + chain = evbuffer_chain_insert_new(buf, datlen); if (chain == NULL) return (-1); - - evbuffer_chain_insert(buf, chain); - return (0); + else + return (0); } used = 0; /* number of chains we're using space in. */ @@ -2116,7 +2126,7 @@ evbuffer_expand_fast_(struct evbuffer *buf, size_t datlen, int n) * chains; we can add another. */ EVUTIL_ASSERT(chain == NULL); - tmp = evbuffer_chain_new(datlen - avail); + tmp = evbuffer_chain_new_membuf(datlen - avail); if (tmp == NULL) return (-1); @@ -2148,7 +2158,7 @@ evbuffer_expand_fast_(struct evbuffer *buf, size_t datlen, int n) evbuffer_chain_free(chain); } EVUTIL_ASSERT(datlen >= avail); - tmp = evbuffer_chain_new(datlen - avail); + tmp = evbuffer_chain_new_membuf(datlen - avail); if (tmp == NULL) { if (rmv_all) { ZERO_CHAIN(buf); |