wstream: Memory allocation improvements

- Rename WriteData to WRequest
- Inline uv_write_t into WRequest, avoiding an extra allocation
- Manage WBuffer/WRequest instances using klib memory pools
This commit is contained in:
Thiago de Arruda 2014-11-01 10:54:41 -03:00
parent 0ffeb140a4
commit d4f032a133
2 changed files with 27 additions and 13 deletions

View File

@ -14,6 +14,7 @@
#include "nvim/os/provider.h" #include "nvim/os/provider.h"
#include "nvim/os/signal.h" #include "nvim/os/signal.h"
#include "nvim/os/rstream.h" #include "nvim/os/rstream.h"
#include "nvim/os/wstream.h"
#include "nvim/os/job.h" #include "nvim/os/job.h"
#include "nvim/vim.h" #include "nvim/vim.h"
#include "nvim/memory.h" #include "nvim/memory.h"
@ -43,6 +44,7 @@ void event_init(void)
msgpack_rpc_helpers_init(); msgpack_rpc_helpers_init();
// Initialize the event queues // Initialize the event queues
pending_events = kl_init(Event); pending_events = kl_init(Event);
wstream_init();
// Initialize input events // Initialize input events
input_init(); input_init();
// Timer to wake the event loop if a timeout argument is passed to // Timer to wake the event loop if a timeout argument is passed to

View File

@ -5,6 +5,8 @@
#include <uv.h> #include <uv.h>
#include "nvim/lib/klist.h"
#include "nvim/os/uv_helpers.h" #include "nvim/os/uv_helpers.h"
#include "nvim/os/wstream.h" #include "nvim/os/wstream.h"
#include "nvim/os/wstream_defs.h" #include "nvim/os/wstream_defs.h"
@ -36,13 +38,27 @@ struct wbuffer {
typedef struct { typedef struct {
WStream *wstream; WStream *wstream;
WBuffer *buffer; WBuffer *buffer;
} WriteData; uv_write_t uv_req;
} WRequest;
#define WRequestFreer(x)
KMEMPOOL_INIT(WRequestPool, WRequest, WRequestFreer)
kmempool_t(WRequestPool) *wrequest_pool = NULL;
#define WBufferFreer(x)
KMEMPOOL_INIT(WBufferPool, WBuffer, WBufferFreer)
kmempool_t(WBufferPool) *wbuffer_pool = NULL;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/wstream.c.generated.h" # include "os/wstream.c.generated.h"
#endif #endif
/// Initialize pools for reusing commonly created objects
void wstream_init(void)
{
wrequest_pool = kmp_init(WRequestPool);
wbuffer_pool = kmp_init(WBufferPool);
}
/// Creates a new WStream instance. A WStream encapsulates all the boilerplate /// Creates a new WStream instance. A WStream encapsulates all the boilerplate
/// necessary for writing to a libuv stream. /// necessary for writing to a libuv stream.
/// ///
@ -148,20 +164,17 @@ bool wstream_write(WStream *wstream, WBuffer *buffer)
wstream->curmem += buffer->size; wstream->curmem += buffer->size;
WriteData *data = xmalloc(sizeof(WriteData)); WRequest *data = kmp_alloc(WRequestPool, wrequest_pool);
data->wstream = wstream; data->wstream = wstream;
data->buffer = buffer; data->buffer = buffer;
data->uv_req.data = data;
uv_write_t *req = xmalloc(sizeof(uv_write_t));
req->data = data;
uv_buf_t uvbuf; uv_buf_t uvbuf;
uvbuf.base = buffer->data; uvbuf.base = buffer->data;
uvbuf.len = buffer->size; uvbuf.len = buffer->size;
if (uv_write(req, wstream->stream, &uvbuf, 1, write_cb)) { if (uv_write(&data->uv_req, wstream->stream, &uvbuf, 1, write_cb)) {
free(data); kmp_free(WRequestPool, wrequest_pool, data);
free(req);
goto err; goto err;
} }
@ -190,7 +203,7 @@ WBuffer *wstream_new_buffer(char *data,
size_t refcount, size_t refcount,
wbuffer_data_finalizer cb) wbuffer_data_finalizer cb)
{ {
WBuffer *rv = xmalloc(sizeof(WBuffer)); WBuffer *rv = kmp_alloc(WBufferPool, wbuffer_pool);
rv->size = size; rv->size = size;
rv->refcount = refcount; rv->refcount = refcount;
rv->cb = cb; rv->cb = cb;
@ -201,9 +214,8 @@ WBuffer *wstream_new_buffer(char *data,
static void write_cb(uv_write_t *req, int status) static void write_cb(uv_write_t *req, int status)
{ {
WriteData *data = req->data; WRequest *data = req->data;
free(req);
data->wstream->curmem -= data->buffer->size; data->wstream->curmem -= data->buffer->size;
release_wbuffer(data->buffer); release_wbuffer(data->buffer);
@ -221,7 +233,7 @@ static void write_cb(uv_write_t *req, int status)
free(data->wstream); free(data->wstream);
} }
free(data); kmp_free(WRequestPool, wrequest_pool, data);
} }
static void release_wbuffer(WBuffer *buffer) static void release_wbuffer(WBuffer *buffer)
@ -231,7 +243,7 @@ static void release_wbuffer(WBuffer *buffer)
buffer->cb(buffer->data); buffer->cb(buffer->data);
} }
free(buffer); kmp_free(WBufferPool, wbuffer_pool, buffer);
} }
} }