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/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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user