summaryrefslogtreecommitdiff
path: root/buffer.c
diff options
context:
space:
mode:
authorPierce Lopez <pierce.lopez@gmail.com>2021-09-16 23:21:26 -0400
committerPierce Lopez <pierce.lopez@gmail.com>2021-09-16 23:21:26 -0400
commitfd0ce993e92e581023f640f37ecaa2a10c75059b (patch)
tree79a0a830b901a7853a04f35f82753d4ff9e070e1 /buffer.c
parentfabbf3b31074ed74b9f0657299836fe40e4e365a (diff)
downloadlibevent-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.c64
1 files changed, 37 insertions, 27 deletions
diff --git a/buffer.c b/buffer.c
index 822d97a5..6c96f054 100644
--- a/buffer.c
+++ b/buffer.c
@@ -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);