mirror of
https://github.com/neovim/neovim.git
synced 2025-09-28 22:18:33 +00:00
refactor(arena): use a shared block freelist
This is both simpler in client code and more effective (always reuse block hottest in cache)
This commit is contained in:
@@ -114,8 +114,6 @@ static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob");
|
|||||||
static char *e_invalwindow = N_("E957: Invalid window number");
|
static char *e_invalwindow = N_("E957: Invalid window number");
|
||||||
static char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value");
|
static char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value");
|
||||||
|
|
||||||
static ArenaMem eval_reuse_blk = NULL;
|
|
||||||
|
|
||||||
/// Dummy va_list for passing to vim_snprintf
|
/// Dummy va_list for passing to vim_snprintf
|
||||||
///
|
///
|
||||||
/// Used because:
|
/// Used because:
|
||||||
@@ -281,10 +279,6 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
|
|
||||||
Error err = ERROR_INIT;
|
Error err = ERROR_INIT;
|
||||||
Arena res_arena = ARENA_EMPTY;
|
Arena res_arena = ARENA_EMPTY;
|
||||||
if (handler.arena_return) {
|
|
||||||
// TODO(bfredl): also use arena for vim_to_object
|
|
||||||
arena_start(&res_arena, &eval_reuse_blk);
|
|
||||||
}
|
|
||||||
Object result = handler.fn(VIML_INTERNAL_CALL, args, &res_arena, &err);
|
Object result = handler.fn(VIML_INTERNAL_CALL, args, &res_arena, &err);
|
||||||
|
|
||||||
if (ERROR_SET(&err)) {
|
if (ERROR_SET(&err)) {
|
||||||
@@ -299,7 +293,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
end:
|
end:
|
||||||
api_free_array(args);
|
api_free_array(args);
|
||||||
if (handler.arena_return) {
|
if (handler.arena_return) {
|
||||||
arena_mem_free(arena_finish(&res_arena), &eval_reuse_blk);
|
arena_mem_free(arena_finish(&res_arena));
|
||||||
} else {
|
} else {
|
||||||
api_free_object(result);
|
api_free_object(result);
|
||||||
}
|
}
|
||||||
@@ -6885,7 +6879,6 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
uint64_t chan_id = (uint64_t)argvars[0].vval.v_number;
|
uint64_t chan_id = (uint64_t)argvars[0].vval.v_number;
|
||||||
const char *method = tv_get_string(&argvars[1]);
|
const char *method = tv_get_string(&argvars[1]);
|
||||||
|
|
||||||
// TODO: putta in eval_reuse_blk
|
|
||||||
ArenaMem res_mem = NULL;
|
ArenaMem res_mem = NULL;
|
||||||
Object result = rpc_send_call(chan_id, method, args, &res_mem, &err);
|
Object result = rpc_send_call(chan_id, method, args, &res_mem, &err);
|
||||||
|
|
||||||
@@ -6921,7 +6914,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
arena_mem_free(res_mem, &eval_reuse_blk);
|
arena_mem_free(res_mem);
|
||||||
api_clear_error(&err);
|
api_clear_error(&err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3154,7 +3154,6 @@ draw_cmdline_no_arabicshape:
|
|||||||
static void ui_ext_cmdline_show(CmdlineInfo *line)
|
static void ui_ext_cmdline_show(CmdlineInfo *line)
|
||||||
{
|
{
|
||||||
Arena arena = ARENA_EMPTY;
|
Arena arena = ARENA_EMPTY;
|
||||||
arena_start(&arena, &ui_ext_fixblk);
|
|
||||||
Array content;
|
Array content;
|
||||||
if (cmdline_star) {
|
if (cmdline_star) {
|
||||||
content = arena_array(&arena, 1);
|
content = arena_array(&arena, 1);
|
||||||
@@ -3199,7 +3198,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line)
|
|||||||
line->special_shift,
|
line->special_shift,
|
||||||
line->level);
|
line->level);
|
||||||
}
|
}
|
||||||
arena_mem_free(arena_finish(&arena), &ui_ext_fixblk);
|
arena_mem_free(arena_finish(&arena));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_ext_cmdline_block_append(size_t indent, const char *line)
|
void ui_ext_cmdline_block_append(size_t indent, const char *line)
|
||||||
|
@@ -413,8 +413,6 @@ output:write([[
|
|||||||
#include "nvim/lua/executor.h"
|
#include "nvim/lua/executor.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
|
|
||||||
static ArenaMem lua_reuse_blk = { 0 };
|
|
||||||
|
|
||||||
]])
|
]])
|
||||||
include_headers(output, headers)
|
include_headers(output, headers)
|
||||||
output:write('\n')
|
output:write('\n')
|
||||||
@@ -496,7 +494,6 @@ local function process_function(fn)
|
|||||||
cparams = cparams .. '&arena, '
|
cparams = cparams .. '&arena, '
|
||||||
write_shifted_output(output, [[
|
write_shifted_output(output, [[
|
||||||
Arena arena = ARENA_EMPTY;
|
Arena arena = ARENA_EMPTY;
|
||||||
arena_start(&arena, &lua_reuse_blk);
|
|
||||||
]])
|
]])
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -536,7 +533,7 @@ local function process_function(fn)
|
|||||||
end
|
end
|
||||||
local free_retval
|
local free_retval
|
||||||
if fn.arena_return then
|
if fn.arena_return then
|
||||||
free_retval = "arena_mem_free(arena_finish(&arena), &lua_reuse_blk);"
|
free_retval = "arena_mem_free(arena_finish(&arena));"
|
||||||
else
|
else
|
||||||
free_retval = "api_free_"..return_type:lower().."(ret);"
|
free_retval = "api_free_"..return_type:lower().."(ret);"
|
||||||
end
|
end
|
||||||
|
@@ -1303,7 +1303,7 @@ void free_highlight(void)
|
|||||||
{
|
{
|
||||||
ga_clear(&highlight_ga);
|
ga_clear(&highlight_ga);
|
||||||
map_destroy(cstr_t, int)(&highlight_unames);
|
map_destroy(cstr_t, int)(&highlight_unames);
|
||||||
arena_mem_free(arena_finish(&highlight_arena), NULL);
|
arena_mem_free(arena_finish(&highlight_arena));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1093,7 +1093,7 @@ static int nlua_rpc(lua_State *lstate, bool request)
|
|||||||
Object result = rpc_send_call(chan_id, name, args, &res_mem, &err);
|
Object result = rpc_send_call(chan_id, name, args, &res_mem, &err);
|
||||||
if (!ERROR_SET(&err)) {
|
if (!ERROR_SET(&err)) {
|
||||||
nlua_push_Object(lstate, result, false);
|
nlua_push_Object(lstate, result, false);
|
||||||
arena_mem_free(res_mem, NULL);
|
arena_mem_free(res_mem);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!rpc_send_event(chan_id, name, args)) {
|
if (!rpc_send_event(chan_id, name, args)) {
|
||||||
|
@@ -60,6 +60,8 @@ void try_to_free_memory(void)
|
|||||||
// Try to save all buffers and release as many blocks as possible
|
// Try to save all buffers and release as many blocks as possible
|
||||||
mf_release_all();
|
mf_release_all();
|
||||||
|
|
||||||
|
arena_free_reuse_blks();
|
||||||
|
|
||||||
trying_to_free = false;
|
trying_to_free = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,23 +530,18 @@ void time_to_bytes(time_t time_, uint8_t buf[8])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define ARENA_BLOCK_SIZE 4096
|
#define ARENA_BLOCK_SIZE 4096
|
||||||
|
#define REUSE_MAX 4
|
||||||
|
|
||||||
void arena_start(Arena *arena, ArenaMem *reuse_blk)
|
static struct consumed_blk *arena_reuse_blk;
|
||||||
|
static size_t arena_reuse_blk_count = 0;
|
||||||
|
|
||||||
|
static void arena_free_reuse_blks(void)
|
||||||
{
|
{
|
||||||
if (reuse_blk && *reuse_blk) {
|
while (arena_reuse_blk_count > 0) {
|
||||||
arena->cur_blk = (char *)(*reuse_blk);
|
struct consumed_blk *blk = arena_reuse_blk;
|
||||||
*reuse_blk = NULL;
|
arena_reuse_blk = arena_reuse_blk->prev;
|
||||||
arena->size = ARENA_BLOCK_SIZE;
|
xfree(blk);
|
||||||
arena->pos = 0;
|
arena_reuse_blk_count--;
|
||||||
|
|
||||||
// address is the same as as (struct consumed_blk *)arena->cur_blk
|
|
||||||
struct consumed_blk *blk = arena_alloc(arena, sizeof(struct consumed_blk), true);
|
|
||||||
assert((char *)blk == (char *)arena->cur_blk);
|
|
||||||
blk->prev = NULL;
|
|
||||||
} else {
|
|
||||||
arena->cur_blk = NULL;
|
|
||||||
arena->size = 0;
|
|
||||||
arena->pos = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,12 +561,18 @@ ArenaMem arena_finish(Arena *arena)
|
|||||||
void alloc_block(Arena *arena)
|
void alloc_block(Arena *arena)
|
||||||
{
|
{
|
||||||
struct consumed_blk *prev_blk = (struct consumed_blk *)arena->cur_blk;
|
struct consumed_blk *prev_blk = (struct consumed_blk *)arena->cur_blk;
|
||||||
|
if (arena_reuse_blk_count > 0) {
|
||||||
|
arena->cur_blk = (char *)arena_reuse_blk;
|
||||||
|
arena_reuse_blk = arena_reuse_blk->prev;
|
||||||
|
arena_reuse_blk_count--;
|
||||||
|
} else {
|
||||||
|
arena_alloc_count++;
|
||||||
arena->cur_blk = xmalloc(ARENA_BLOCK_SIZE);
|
arena->cur_blk = xmalloc(ARENA_BLOCK_SIZE);
|
||||||
|
}
|
||||||
arena->pos = 0;
|
arena->pos = 0;
|
||||||
arena->size = ARENA_BLOCK_SIZE;
|
arena->size = ARENA_BLOCK_SIZE;
|
||||||
struct consumed_blk *blk = arena_alloc(arena, sizeof(struct consumed_blk), true);
|
struct consumed_blk *blk = arena_alloc(arena, sizeof(struct consumed_blk), true);
|
||||||
blk->prev = prev_blk;
|
blk->prev = prev_blk;
|
||||||
arena_alloc_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param size if zero, will still return a non-null pointer, but not a unique one
|
/// @param size if zero, will still return a non-null pointer, but not a unique one
|
||||||
@@ -606,15 +609,17 @@ void *arena_alloc(Arena *arena, size_t size, bool align)
|
|||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arena_mem_free(ArenaMem mem, ArenaMem *reuse_blk)
|
void arena_mem_free(ArenaMem mem)
|
||||||
{
|
{
|
||||||
struct consumed_blk *b = mem;
|
struct consumed_blk *b = mem;
|
||||||
// peel of the first block, as it is guaranteed to be ARENA_BLOCK_SIZE,
|
// peel of the first block, as it is guaranteed to be ARENA_BLOCK_SIZE,
|
||||||
// not a custom fix_blk
|
// not a custom fix_blk
|
||||||
if (reuse_blk && *reuse_blk == NULL && b != NULL) {
|
if (arena_reuse_blk_count < REUSE_MAX && b != NULL) {
|
||||||
*reuse_blk = b;
|
struct consumed_blk *reuse_blk = b;
|
||||||
b = b->prev;
|
b = b->prev;
|
||||||
(*reuse_blk)->prev = NULL;
|
reuse_blk->prev = arena_reuse_blk;
|
||||||
|
arena_reuse_blk = reuse_blk;
|
||||||
|
arena_reuse_blk_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (b) {
|
while (b) {
|
||||||
@@ -815,6 +820,9 @@ void free_all_mem(void)
|
|||||||
|
|
||||||
nlua_free_all_mem();
|
nlua_free_all_mem();
|
||||||
ui_free_all_mem();
|
ui_free_all_mem();
|
||||||
|
|
||||||
|
// should be last, in case earlier free functions deallocates arenas
|
||||||
|
arena_free_reuse_blks();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -52,7 +52,7 @@ typedef struct {
|
|||||||
size_t pos, size;
|
size_t pos, size;
|
||||||
} Arena;
|
} Arena;
|
||||||
|
|
||||||
// inits an empty arena. use arena_start() to actually allocate space!
|
// inits an empty arena.
|
||||||
#define ARENA_EMPTY { .cur_blk = NULL, .pos = 0, .size = 0 }
|
#define ARENA_EMPTY { .cur_blk = NULL, .pos = 0, .size = 0 }
|
||||||
|
|
||||||
#define kv_fixsize_arena(a, v, s) \
|
#define kv_fixsize_arena(a, v, s) \
|
||||||
|
@@ -158,7 +158,7 @@ Object rpc_send_call(uint64_t id, const char *method_name, Array args, ArenaMem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// frame.result was allocated in an arena
|
// frame.result was allocated in an arena
|
||||||
arena_mem_free(frame.result_mem, &rpc->unpacker->reuse_blk);
|
arena_mem_free(frame.result_mem);
|
||||||
frame.result_mem = NULL;
|
frame.result_mem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +244,7 @@ static void parse_msgpack(Channel *channel)
|
|||||||
ui_client_event_raw_line(p->grid_line_event);
|
ui_client_event_raw_line(p->grid_line_event);
|
||||||
} else if (p->ui_handler.fn != NULL && p->result.type == kObjectTypeArray) {
|
} else if (p->ui_handler.fn != NULL && p->result.type == kObjectTypeArray) {
|
||||||
p->ui_handler.fn(p->result.data.array);
|
p->ui_handler.fn(p->result.data.array);
|
||||||
arena_mem_free(arena_finish(&p->arena), &p->reuse_blk);
|
arena_mem_free(arena_finish(&p->arena));
|
||||||
}
|
}
|
||||||
} else if (p->type == kMessageTypeResponse) {
|
} else if (p->type == kMessageTypeResponse) {
|
||||||
ChannelCallFrame *frame = kv_last(channel->rpc.call_stack);
|
ChannelCallFrame *frame = kv_last(channel->rpc.call_stack);
|
||||||
@@ -295,7 +295,7 @@ static void handle_request(Channel *channel, Unpacker *p, Array args)
|
|||||||
if (!p->handler.fn) {
|
if (!p->handler.fn) {
|
||||||
send_error(channel, p->type, p->request_id, p->unpack_error.msg);
|
send_error(channel, p->type, p->request_id, p->unpack_error.msg);
|
||||||
api_clear_error(&p->unpack_error);
|
api_clear_error(&p->unpack_error);
|
||||||
arena_mem_free(arena_finish(&p->arena), &p->reuse_blk);
|
arena_mem_free(arena_finish(&p->arena));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ static void request_event(void **argv)
|
|||||||
|
|
||||||
free_ret:
|
free_ret:
|
||||||
// e->args (and possibly result) are allocated in an arena
|
// e->args (and possibly result) are allocated in an arena
|
||||||
arena_mem_free(arena_finish(&e->used_mem), &channel->rpc.unpacker->reuse_blk);
|
arena_mem_free(arena_finish(&e->used_mem));
|
||||||
channel_decref(channel);
|
channel_decref(channel);
|
||||||
xfree(e);
|
xfree(e);
|
||||||
api_clear_error(&error);
|
api_clear_error(&error);
|
||||||
|
@@ -181,13 +181,11 @@ void unpacker_init(Unpacker *p)
|
|||||||
p->unpack_error = (Error)ERROR_INIT;
|
p->unpack_error = (Error)ERROR_INIT;
|
||||||
|
|
||||||
p->arena = (Arena)ARENA_EMPTY;
|
p->arena = (Arena)ARENA_EMPTY;
|
||||||
p->reuse_blk = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unpacker_teardown(Unpacker *p)
|
void unpacker_teardown(Unpacker *p)
|
||||||
{
|
{
|
||||||
arena_mem_free(p->reuse_blk, NULL);
|
arena_mem_free(arena_finish(&p->arena));
|
||||||
arena_mem_free(arena_finish(&p->arena), NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unpacker_parse_header(Unpacker *p)
|
bool unpacker_parse_header(Unpacker *p)
|
||||||
@@ -308,7 +306,7 @@ bool unpacker_advance(Unpacker *p)
|
|||||||
p->state = 10;
|
p->state = 10;
|
||||||
} else {
|
} else {
|
||||||
p->state = p->type == kMessageTypeResponse ? 1 : 2;
|
p->state = p->type == kMessageTypeResponse ? 1 : 2;
|
||||||
arena_start(&p->arena, &p->reuse_blk);
|
p->arena = (Arena)ARENA_EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +320,7 @@ bool unpacker_advance(Unpacker *p)
|
|||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
// unpack other ui events using mpack_parse()
|
// unpack other ui events using mpack_parse()
|
||||||
arena_start(&p->arena, &p->reuse_blk);
|
p->arena = (Arena)ARENA_EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,13 +414,13 @@ redo:
|
|||||||
if (p->ui_handler.fn != ui_client_event_grid_line) {
|
if (p->ui_handler.fn != ui_client_event_grid_line) {
|
||||||
p->state = 12;
|
p->state = 12;
|
||||||
if (p->grid_line_event) {
|
if (p->grid_line_event) {
|
||||||
arena_mem_free(arena_finish(&p->arena), &p->reuse_blk);
|
arena_mem_free(arena_finish(&p->arena));
|
||||||
p->grid_line_event = NULL;
|
p->grid_line_event = NULL;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
p->state = 13;
|
p->state = 13;
|
||||||
arena_start(&p->arena, &p->reuse_blk);
|
p->arena = (Arena)ARENA_EMPTY;
|
||||||
p->grid_line_event = arena_alloc(&p->arena, sizeof *p->grid_line_event, true);
|
p->grid_line_event = arena_alloc(&p->arena, sizeof *p->grid_line_event, true);
|
||||||
g = p->grid_line_event;
|
g = p->grid_line_event;
|
||||||
}
|
}
|
||||||
|
@@ -32,8 +32,6 @@ struct Unpacker {
|
|||||||
Error unpack_error;
|
Error unpack_error;
|
||||||
|
|
||||||
Arena arena;
|
Arena arena;
|
||||||
// one length free-list of reusable blocks
|
|
||||||
ArenaMem reuse_blk;
|
|
||||||
|
|
||||||
int nevents;
|
int nevents;
|
||||||
int ncalls;
|
int ncalls;
|
||||||
|
@@ -156,7 +156,6 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
|||||||
if (pum_external) {
|
if (pum_external) {
|
||||||
if (array_changed) {
|
if (array_changed) {
|
||||||
Arena arena = ARENA_EMPTY;
|
Arena arena = ARENA_EMPTY;
|
||||||
arena_start(&arena, &ui_ext_fixblk);
|
|
||||||
Array arr = arena_array(&arena, (size_t)size);
|
Array arr = arena_array(&arena, (size_t)size);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
Array item = arena_array(&arena, 4);
|
Array item = arena_array(&arena, 4);
|
||||||
@@ -168,7 +167,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
|||||||
}
|
}
|
||||||
ui_call_popupmenu_show(arr, selected, pum_win_row, cursor_col,
|
ui_call_popupmenu_show(arr, selected, pum_win_row, cursor_col,
|
||||||
pum_anchor_grid);
|
pum_anchor_grid);
|
||||||
arena_mem_free(arena_finish(&arena), &ui_ext_fixblk);
|
arena_mem_free(arena_finish(&arena));
|
||||||
} else {
|
} else {
|
||||||
ui_call_popupmenu_select(selected);
|
ui_call_popupmenu_select(selected);
|
||||||
return;
|
return;
|
||||||
|
@@ -1094,7 +1094,6 @@ void draw_tabline(void)
|
|||||||
static void ui_ext_tabline_update(void)
|
static void ui_ext_tabline_update(void)
|
||||||
{
|
{
|
||||||
Arena arena = ARENA_EMPTY;
|
Arena arena = ARENA_EMPTY;
|
||||||
arena_start(&arena, &ui_ext_fixblk);
|
|
||||||
|
|
||||||
size_t n_tabs = 0;
|
size_t n_tabs = 0;
|
||||||
FOR_ALL_TABS(tp) {
|
FOR_ALL_TABS(tp) {
|
||||||
@@ -1135,7 +1134,7 @@ static void ui_ext_tabline_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ui_call_tabline_update(curtab->handle, tabs, curbuf->handle, buffers);
|
ui_call_tabline_update(curtab->handle, tabs, curbuf->handle, buffers);
|
||||||
arena_mem_free(arena_finish(&arena), &ui_ext_fixblk);
|
arena_mem_free(arena_finish(&arena));
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_trans_bufname(buf_T *buf)
|
void get_trans_bufname(buf_T *buf)
|
||||||
|
@@ -238,7 +238,7 @@ static void tinput_wait_enqueue(void **argv)
|
|||||||
ArenaMem res_mem = NULL;
|
ArenaMem res_mem = NULL;
|
||||||
Object result = rpc_send_call(ui_client_channel_id, "nvim_input", args, &res_mem, &err);
|
Object result = rpc_send_call(ui_client_channel_id, "nvim_input", args, &res_mem, &err);
|
||||||
consumed = result.type == kObjectTypeInteger ? (size_t)result.data.integer : 0;
|
consumed = result.type == kObjectTypeInteger ? (size_t)result.data.integer : 0;
|
||||||
arena_mem_free(res_mem, NULL);
|
arena_mem_free(res_mem);
|
||||||
} else {
|
} else {
|
||||||
consumed = input_enqueue(keys);
|
consumed = input_enqueue(keys);
|
||||||
}
|
}
|
||||||
|
@@ -517,11 +517,10 @@ void ui_flush(void)
|
|||||||
}
|
}
|
||||||
if (pending_mode_info_update) {
|
if (pending_mode_info_update) {
|
||||||
Arena arena = ARENA_EMPTY;
|
Arena arena = ARENA_EMPTY;
|
||||||
arena_start(&arena, &ui_ext_fixblk);
|
|
||||||
Array style = mode_style_array(&arena);
|
Array style = mode_style_array(&arena);
|
||||||
bool enabled = (*p_guicursor != NUL);
|
bool enabled = (*p_guicursor != NUL);
|
||||||
ui_call_mode_info_set(enabled, style);
|
ui_call_mode_info_set(enabled, style);
|
||||||
arena_mem_free(arena_finish(&arena), &ui_ext_fixblk);
|
arena_mem_free(arena_finish(&arena));
|
||||||
pending_mode_info_update = false;
|
pending_mode_info_update = false;
|
||||||
}
|
}
|
||||||
if (pending_mode_update && !starting) {
|
if (pending_mode_update && !starting) {
|
||||||
|
@@ -47,8 +47,6 @@ enum {
|
|||||||
|
|
||||||
typedef int LineFlags;
|
typedef int LineFlags;
|
||||||
|
|
||||||
EXTERN ArenaMem ui_ext_fixblk INIT(= NULL);
|
|
||||||
|
|
||||||
struct ui_t {
|
struct ui_t {
|
||||||
bool rgb;
|
bool rgb;
|
||||||
bool override; ///< Force highest-requested UI capabilities.
|
bool override; ///< Force highest-requested UI capabilities.
|
||||||
|
Reference in New Issue
Block a user