From b00964dc546b22b5dbaf9f5cd998f4bd355d58de Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Fri, 6 Oct 2017 15:13:29 +0300 Subject: [PATCH] Allocate shared buffer and its data in one chunk The GWBUF shared buffer and its data is now allocated in one chunk so that the data directly follows the shared buffer. That way, creating a GWBUF will involve 2 and not 3 calls to malloc and freeing one will involve 2 and not 3 calls to free. --- include/maxscale/buffer.h | 4 ++-- server/core/buffer.cc | 14 +++----------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/include/maxscale/buffer.h b/include/maxscale/buffer.h index dd2caf59b..2cd5abe80 100644 --- a/include/maxscale/buffer.h +++ b/include/maxscale/buffer.h @@ -105,10 +105,10 @@ struct buffer_object_st */ typedef struct { - unsigned char *data; /*< Physical memory that was allocated */ - int refcount; /*< Reference count on the buffer */ + int32_t refcount; /*< Reference count on the buffer */ buffer_object_t *bufobj; /*< List of objects referred to by GWBUF */ uint32_t info; /*< Info bits */ + unsigned char data[1]; /*< Actual memory that was allocated */ } SHARED_BUF; /** diff --git a/server/core/buffer.cc b/server/core/buffer.cc index 80d98a2f4..98d1ce829 100644 --- a/server/core/buffer.cc +++ b/server/core/buffer.cc @@ -55,6 +55,7 @@ gwbuf_alloc(unsigned int size) { GWBUF *rval; SHARED_BUF *sbuf; + size_t sbuf_size = sizeof(SHARED_BUF) + (size ? size - 1 : 0); /* Allocate the buffer header */ if ((rval = (GWBUF *)MXS_MALLOC(sizeof(GWBUF))) == NULL) @@ -63,27 +64,19 @@ gwbuf_alloc(unsigned int size) } /* Allocate the shared data buffer */ - if ((sbuf = (SHARED_BUF *)MXS_MALLOC(sizeof(SHARED_BUF))) == NULL) + if ((sbuf = (SHARED_BUF *)MXS_MALLOC(sbuf_size)) == NULL) { MXS_FREE(rval); rval = NULL; goto retblock; } - /* Allocate the space for the actual data */ - if ((sbuf->data = (unsigned char *)MXS_MALLOC(size)) == NULL) - { - MXS_FREE(rval); - MXS_FREE(sbuf); - rval = NULL; - goto retblock; - } sbuf->refcount = 1; sbuf->info = GWBUF_INFO_NONE; sbuf->bufobj = NULL; spinlock_init(&rval->gwbuf_lock); - rval->start = sbuf->data; + rval->start = &sbuf->data; rval->end = (void *)((char *)rval->start + size); rval->sbuf = sbuf; rval->next = NULL; @@ -262,7 +255,6 @@ gwbuf_free_one(GWBUF *buf) bo = gwbuf_remove_buffer_object(buf, bo); } - MXS_FREE(buf->sbuf->data); MXS_FREE(buf->sbuf); }