mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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:
parent
0ffeb140a4
commit
d4f032a133
@ -14,6 +14,7 @@
|
||||
#include "nvim/os/provider.h"
|
||||
#include "nvim/os/signal.h"
|
||||
#include "nvim/os/rstream.h"
|
||||
#include "nvim/os/wstream.h"
|
||||
#include "nvim/os/job.h"
|
||||
#include "nvim/vim.h"
|
||||
#include "nvim/memory.h"
|
||||
@ -43,6 +44,7 @@ void event_init(void)
|
||||
msgpack_rpc_helpers_init();
|
||||
// Initialize the event queues
|
||||
pending_events = kl_init(Event);
|
||||
wstream_init();
|
||||
// Initialize input events
|
||||
input_init();
|
||||
// Timer to wake the event loop if a timeout argument is passed to
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include "nvim/lib/klist.h"
|
||||
|
||||
#include "nvim/os/uv_helpers.h"
|
||||
#include "nvim/os/wstream.h"
|
||||
#include "nvim/os/wstream_defs.h"
|
||||
@ -36,13 +38,27 @@ struct wbuffer {
|
||||
typedef struct {
|
||||
WStream *wstream;
|
||||
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
|
||||
# include "os/wstream.c.generated.h"
|
||||
#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
|
||||
/// necessary for writing to a libuv stream.
|
||||
///
|
||||
@ -148,20 +164,17 @@ bool wstream_write(WStream *wstream, WBuffer *buffer)
|
||||
|
||||
wstream->curmem += buffer->size;
|
||||
|
||||
WriteData *data = xmalloc(sizeof(WriteData));
|
||||
WRequest *data = kmp_alloc(WRequestPool, wrequest_pool);
|
||||
data->wstream = wstream;
|
||||
data->buffer = buffer;
|
||||
|
||||
uv_write_t *req = xmalloc(sizeof(uv_write_t));
|
||||
req->data = data;
|
||||
data->uv_req.data = data;
|
||||
|
||||
uv_buf_t uvbuf;
|
||||
uvbuf.base = buffer->data;
|
||||
uvbuf.len = buffer->size;
|
||||
|
||||
if (uv_write(req, wstream->stream, &uvbuf, 1, write_cb)) {
|
||||
free(data);
|
||||
free(req);
|
||||
if (uv_write(&data->uv_req, wstream->stream, &uvbuf, 1, write_cb)) {
|
||||
kmp_free(WRequestPool, wrequest_pool, data);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -190,7 +203,7 @@ WBuffer *wstream_new_buffer(char *data,
|
||||
size_t refcount,
|
||||
wbuffer_data_finalizer cb)
|
||||
{
|
||||
WBuffer *rv = xmalloc(sizeof(WBuffer));
|
||||
WBuffer *rv = kmp_alloc(WBufferPool, wbuffer_pool);
|
||||
rv->size = size;
|
||||
rv->refcount = refcount;
|
||||
rv->cb = cb;
|
||||
@ -201,9 +214,8 @@ WBuffer *wstream_new_buffer(char *data,
|
||||
|
||||
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;
|
||||
|
||||
release_wbuffer(data->buffer);
|
||||
@ -221,7 +233,7 @@ static void write_cb(uv_write_t *req, int status)
|
||||
free(data->wstream);
|
||||
}
|
||||
|
||||
free(data);
|
||||
kmp_free(WRequestPool, wrequest_pool, data);
|
||||
}
|
||||
|
||||
static void release_wbuffer(WBuffer *buffer)
|
||||
@ -231,7 +243,7 @@ static void release_wbuffer(WBuffer *buffer)
|
||||
buffer->cb(buffer->data);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
kmp_free(WBufferPool, wbuffer_pool, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user