mirror of
https://github.com/neovim/neovim.git
synced 2025-09-25 04:28:33 +00:00
memory: Replace klib memory pools by malloc/free
Klib pools were used to improve allocation efficiency for some small objects, but it is not a thread-safe approach. Thread safety in allocations will be required for implementing #2371).
This commit is contained in:
@@ -21,8 +21,6 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include "nvim/lib/klist.h"
|
|
||||||
|
|
||||||
#include "nvim/assert.h"
|
#include "nvim/assert.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
@@ -469,9 +467,6 @@ typedef struct {
|
|||||||
list_T *received;
|
list_T *received;
|
||||||
int status;
|
int status;
|
||||||
} JobEvent;
|
} JobEvent;
|
||||||
#define JobEventFreer(x)
|
|
||||||
KMEMPOOL_INIT(JobEventPool, JobEvent, JobEventFreer)
|
|
||||||
static kmempool_t(JobEventPool) *job_event_pool = NULL;
|
|
||||||
static int disable_job_defer = 0;
|
static int disable_job_defer = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -508,8 +503,6 @@ void eval_init(void)
|
|||||||
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
|
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
|
||||||
set_vim_var_nr(VV_HLSEARCH, 1L);
|
set_vim_var_nr(VV_HLSEARCH, 1L);
|
||||||
set_reg_var(0); /* default for v:register is not 0 but '"' */
|
set_reg_var(0); /* default for v:register is not 0 but '"' */
|
||||||
|
|
||||||
job_event_pool = kmp_init(JobEventPool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(EXITFREE)
|
#if defined(EXITFREE)
|
||||||
@@ -20149,7 +20142,7 @@ static inline bool is_user_job(Job *job)
|
|||||||
static inline void push_job_event(Job *job, ufunc_T *callback,
|
static inline void push_job_event(Job *job, ufunc_T *callback,
|
||||||
const char *type, char *data, size_t count, int status)
|
const char *type, char *data, size_t count, int status)
|
||||||
{
|
{
|
||||||
JobEvent *event_data = kmp_alloc(JobEventPool, job_event_pool);
|
JobEvent *event_data = xmalloc(sizeof(JobEvent));
|
||||||
event_data->received = NULL;
|
event_data->received = NULL;
|
||||||
if (data) {
|
if (data) {
|
||||||
event_data->received = list_alloc();
|
event_data->received = list_alloc();
|
||||||
@@ -20317,7 +20310,7 @@ end:
|
|||||||
// exit event, safe to free job data now
|
// exit event, safe to free job data now
|
||||||
term_job_data_decref(ev->data);
|
term_job_data_decref(ev->data);
|
||||||
}
|
}
|
||||||
kmp_free(JobEventPool, job_event_pool, ev);
|
free(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
|
static void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
|
||||||
|
@@ -5,8 +5,6 @@
|
|||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
#include <msgpack.h>
|
#include <msgpack.h>
|
||||||
|
|
||||||
#include "nvim/lib/klist.h"
|
|
||||||
|
|
||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/api/vim.h"
|
#include "nvim/api/vim.h"
|
||||||
#include "nvim/msgpack_rpc/channel.h"
|
#include "nvim/msgpack_rpc/channel.h"
|
||||||
@@ -69,10 +67,6 @@ typedef struct {
|
|||||||
uint64_t request_id;
|
uint64_t request_id;
|
||||||
} RequestEvent;
|
} RequestEvent;
|
||||||
|
|
||||||
#define _noop(x)
|
|
||||||
KMEMPOOL_INIT(RequestEventPool, RequestEvent, _noop)
|
|
||||||
static kmempool_t(RequestEventPool) *request_event_pool = NULL;
|
|
||||||
|
|
||||||
static uint64_t next_id = 1;
|
static uint64_t next_id = 1;
|
||||||
static PMap(uint64_t) *channels = NULL;
|
static PMap(uint64_t) *channels = NULL;
|
||||||
static PMap(cstr_t) *event_strings = NULL;
|
static PMap(cstr_t) *event_strings = NULL;
|
||||||
@@ -85,7 +79,6 @@ static msgpack_sbuffer out_buffer;
|
|||||||
/// Initializes the module
|
/// Initializes the module
|
||||||
void channel_init(void)
|
void channel_init(void)
|
||||||
{
|
{
|
||||||
request_event_pool = kmp_init(RequestEventPool);
|
|
||||||
channels = pmap_new(uint64_t)();
|
channels = pmap_new(uint64_t)();
|
||||||
event_strings = pmap_new(cstr_t)();
|
event_strings = pmap_new(cstr_t)();
|
||||||
msgpack_sbuffer_init(&out_buffer);
|
msgpack_sbuffer_init(&out_buffer);
|
||||||
@@ -455,7 +448,7 @@ static void handle_request(Channel *channel, msgpack_object *request)
|
|||||||
Array args = ARRAY_DICT_INIT;
|
Array args = ARRAY_DICT_INIT;
|
||||||
msgpack_rpc_to_array(request->via.array.ptr + 3, &args);
|
msgpack_rpc_to_array(request->via.array.ptr + 3, &args);
|
||||||
bool defer = (!kv_size(channel->call_stack) && handler.defer);
|
bool defer = (!kv_size(channel->call_stack) && handler.defer);
|
||||||
RequestEvent *event_data = kmp_alloc(RequestEventPool, request_event_pool);
|
RequestEvent *event_data = xmalloc(sizeof(RequestEvent));
|
||||||
event_data->channel = channel;
|
event_data->channel = channel;
|
||||||
event_data->handler = handler;
|
event_data->handler = handler;
|
||||||
event_data->args = args;
|
event_data->args = args;
|
||||||
@@ -487,7 +480,7 @@ static void on_request_event(Event event)
|
|||||||
// All arguments were freed already, but we still need to free the array
|
// All arguments were freed already, but we still need to free the array
|
||||||
free(args.items);
|
free(args.items);
|
||||||
decref(channel);
|
decref(channel);
|
||||||
kmp_free(RequestEventPool, request_event_pool, e);
|
free(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool channel_write(Channel *channel, WBuffer *buffer)
|
static bool channel_write(Channel *channel, WBuffer *buffer)
|
||||||
|
@@ -46,7 +46,6 @@ void event_init(void)
|
|||||||
// early msgpack-rpc initialization
|
// early msgpack-rpc initialization
|
||||||
msgpack_rpc_init_method_table();
|
msgpack_rpc_init_method_table();
|
||||||
msgpack_rpc_helpers_init();
|
msgpack_rpc_helpers_init();
|
||||||
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
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
|
||||||
#include "nvim/lib/klist.h"
|
|
||||||
|
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/globals.h"
|
#include "nvim/globals.h"
|
||||||
@@ -15,10 +14,6 @@
|
|||||||
#include "nvim/os/signal.h"
|
#include "nvim/os/signal.h"
|
||||||
#include "nvim/os/event.h"
|
#include "nvim/os/event.h"
|
||||||
|
|
||||||
#define SignalEventFreer(x)
|
|
||||||
KMEMPOOL_INIT(SignalEventPool, int, SignalEventFreer)
|
|
||||||
kmempool_t(SignalEventPool) *signal_event_pool = NULL;
|
|
||||||
|
|
||||||
static uv_signal_t spipe, shup, squit, sterm;
|
static uv_signal_t spipe, shup, squit, sterm;
|
||||||
#ifdef SIGPWR
|
#ifdef SIGPWR
|
||||||
static uv_signal_t spwr;
|
static uv_signal_t spwr;
|
||||||
@@ -32,7 +27,6 @@ static bool rejecting_deadly;
|
|||||||
|
|
||||||
void signal_init(void)
|
void signal_init(void)
|
||||||
{
|
{
|
||||||
signal_event_pool = kmp_init(SignalEventPool);
|
|
||||||
uv_signal_init(uv_default_loop(), &spipe);
|
uv_signal_init(uv_default_loop(), &spipe);
|
||||||
uv_signal_init(uv_default_loop(), &shup);
|
uv_signal_init(uv_default_loop(), &shup);
|
||||||
uv_signal_init(uv_default_loop(), &squit);
|
uv_signal_init(uv_default_loop(), &squit);
|
||||||
@@ -119,18 +113,16 @@ static void deadly_signal(int signum)
|
|||||||
|
|
||||||
static void signal_cb(uv_signal_t *handle, int signum)
|
static void signal_cb(uv_signal_t *handle, int signum)
|
||||||
{
|
{
|
||||||
int *n = kmp_alloc(SignalEventPool, signal_event_pool);
|
assert(signum >= 0);
|
||||||
*n = signum;
|
|
||||||
event_push((Event) {
|
event_push((Event) {
|
||||||
.handler = on_signal_event,
|
.handler = on_signal_event,
|
||||||
.data = n
|
.data = (void *)(uintptr_t)signum
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_signal_event(Event event)
|
static void on_signal_event(Event event)
|
||||||
{
|
{
|
||||||
int signum = *((int *)event.data);
|
int signum = (int)(uintptr_t)event.data;
|
||||||
kmp_free(SignalEventPool, signal_event_pool, event.data);
|
|
||||||
|
|
||||||
switch (signum) {
|
switch (signum) {
|
||||||
#ifdef SIGPWR
|
#ifdef SIGPWR
|
||||||
|
@@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
#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"
|
||||||
@@ -41,24 +39,10 @@ typedef struct {
|
|||||||
uv_write_t uv_req;
|
uv_write_t uv_req;
|
||||||
} WRequest;
|
} 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.
|
||||||
///
|
///
|
||||||
@@ -163,7 +147,7 @@ bool wstream_write(WStream *wstream, WBuffer *buffer)
|
|||||||
|
|
||||||
wstream->curmem += buffer->size;
|
wstream->curmem += buffer->size;
|
||||||
|
|
||||||
WRequest *data = kmp_alloc(WRequestPool, wrequest_pool);
|
WRequest *data = xmalloc(sizeof(WRequest));
|
||||||
data->wstream = wstream;
|
data->wstream = wstream;
|
||||||
data->buffer = buffer;
|
data->buffer = buffer;
|
||||||
data->uv_req.data = data;
|
data->uv_req.data = data;
|
||||||
@@ -173,7 +157,7 @@ bool wstream_write(WStream *wstream, WBuffer *buffer)
|
|||||||
uvbuf.len = buffer->size;
|
uvbuf.len = buffer->size;
|
||||||
|
|
||||||
if (uv_write(&data->uv_req, wstream->stream, &uvbuf, 1, write_cb)) {
|
if (uv_write(&data->uv_req, wstream->stream, &uvbuf, 1, write_cb)) {
|
||||||
kmp_free(WRequestPool, wrequest_pool, data);
|
free(data);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +186,7 @@ WBuffer *wstream_new_buffer(char *data,
|
|||||||
size_t refcount,
|
size_t refcount,
|
||||||
wbuffer_data_finalizer cb)
|
wbuffer_data_finalizer cb)
|
||||||
{
|
{
|
||||||
WBuffer *rv = kmp_alloc(WBufferPool, wbuffer_pool);
|
WBuffer *rv = xmalloc(sizeof(WBuffer));
|
||||||
rv->size = size;
|
rv->size = size;
|
||||||
rv->refcount = refcount;
|
rv->refcount = refcount;
|
||||||
rv->cb = cb;
|
rv->cb = cb;
|
||||||
@@ -236,7 +220,7 @@ static void write_cb(uv_write_t *req, int status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kmp_free(WRequestPool, wrequest_pool, data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wstream_release_wbuffer(WBuffer *buffer)
|
void wstream_release_wbuffer(WBuffer *buffer)
|
||||||
@@ -246,7 +230,7 @@ void wstream_release_wbuffer(WBuffer *buffer)
|
|||||||
buffer->cb(buffer->data);
|
buffer->cb(buffer->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
kmp_free(WBufferPool, wbuffer_pool, buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user