refactor: change event_create() to a macro (#26343)

A varargs functions can never be inlined, so a macro is faster.
This commit is contained in:
zeertzjq 2023-12-01 15:22:22 +08:00 committed by GitHub
parent 130cb4815a
commit 548f03c66c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 49 additions and 75 deletions

View File

@ -2564,7 +2564,7 @@ void may_trigger_vim_suspend_resume(bool suspend)
pending_vimresume = kTrue;
} else if (!suspend && pending_vimresume == kTrue) {
pending_vimresume = kNone;
multiqueue_put(main_loop.events, vimresume_event, 0);
multiqueue_put(main_loop.events, vimresume_event, NULL);
}
}

View File

@ -244,7 +244,7 @@ void channel_decref(Channel *chan)
{
if (!(--chan->refcount)) {
// delay free, so that libuv is done with the handles
multiqueue_put(main_loop.events, free_channel_event, 1, chan);
multiqueue_put(main_loop.events, free_channel_event, chan);
}
}
@ -293,7 +293,7 @@ static void channel_destroy_early(Channel *chan)
}
// uv will keep a reference to handles until next loop tick, so delay free
multiqueue_put(main_loop.events, free_channel_event, 1, chan);
multiqueue_put(main_loop.events, free_channel_event, chan);
}
static void close_cb(Stream *stream, void *data)
@ -657,7 +657,7 @@ static void schedule_channel_event(Channel *chan)
{
if (!chan->callback_scheduled) {
if (!chan->callback_busy) {
multiqueue_put(chan->events, on_channel_event, 1, chan);
multiqueue_put(chan->events, on_channel_event, chan);
channel_incref(chan);
}
chan->callback_scheduled = true;
@ -682,7 +682,7 @@ static void on_channel_event(void **args)
chan->callback_busy = false;
if (chan->callback_scheduled) {
// further callback was deferred to avoid recursion.
multiqueue_put(chan->events, on_channel_event, 1, chan);
multiqueue_put(chan->events, on_channel_event, chan);
channel_incref(chan);
}
@ -812,7 +812,7 @@ static inline void term_delayed_free(void **argv)
{
Channel *chan = argv[0];
if (chan->stream.proc.in.pending_reqs || chan->stream.proc.out.pending_reqs) {
multiqueue_put(chan->events, term_delayed_free, 1, chan);
multiqueue_put(chan->events, term_delayed_free, chan);
return;
}
@ -826,7 +826,7 @@ static void term_close(void *data)
{
Channel *chan = data;
process_stop(&chan->stream.proc);
multiqueue_put(chan->events, term_delayed_free, 1, data);
multiqueue_put(chan->events, term_delayed_free, data);
}
void channel_info_changed(Channel *chan, bool new_chan)
@ -834,7 +834,7 @@ void channel_info_changed(Channel *chan, bool new_chan)
event_T event = new_chan ? EVENT_CHANOPEN : EVENT_CHANINFO;
if (has_event(event)) {
channel_incref(chan);
multiqueue_put(main_loop.events, set_info_event, 2, chan, event);
multiqueue_put(main_loop.events, set_info_event, chan, (void *)(intptr_t)event);
}
}

View File

@ -6,29 +6,9 @@
enum { EVENT_HANDLER_MAX_ARGC = 10, };
typedef void (*argv_callback)(void **argv);
typedef struct message {
typedef struct {
argv_callback handler;
void *argv[EVENT_HANDLER_MAX_ARGC];
} Event;
#define VA_EVENT_INIT(event, h, a) \
do { \
assert(a <= EVENT_HANDLER_MAX_ARGC); \
(event)->handler = h; \
if (a) { \
va_list args; \
va_start(args, a); \
for (int i = 0; i < a; i++) { \
(event)->argv[i] = va_arg(args, void *); \
} \
va_end(args); \
} \
} while (0)
static inline Event event_create(argv_callback cb, int argc, ...)
{
assert(argc <= EVENT_HANDLER_MAX_ARGC);
Event event;
VA_EVENT_INIT(&event, cb, argc);
return event;
}
#define event_create(cb, ...) ((Event){ .handler = cb, .argv = { __VA_ARGS__ } })

View File

@ -111,7 +111,7 @@ void loop_schedule_deferred(Loop *loop, Event event)
{
Event *eventp = xmalloc(sizeof(*eventp));
*eventp = event;
loop_schedule_fast(loop, event_create(loop_deferred_event, 2, loop, eventp));
loop_schedule_fast(loop, event_create(loop_deferred_event, loop, eventp));
}
static void loop_deferred_event(void **argv)
{

View File

@ -44,12 +44,12 @@ typedef struct loop {
bool closing; ///< Set to true if loop_close() has been called
} Loop;
#define CREATE_EVENT(multiqueue, handler, argc, ...) \
#define CREATE_EVENT(multiqueue, handler, ...) \
do { \
if (multiqueue) { \
multiqueue_put((multiqueue), (handler), argc, __VA_ARGS__); \
multiqueue_put((multiqueue), (handler), __VA_ARGS__); \
} else { \
void *argv[argc] = { __VA_ARGS__ }; \
void *argv[] = { __VA_ARGS__ }; \
(handler)(argv); \
} \
} while (0)

View File

@ -260,7 +260,7 @@ Event event_create_oneshot(Event ev, int num)
data->event = ev;
data->fired = false;
data->refcount = num;
return event_create(multiqueue_oneshot_event, 1, data);
return event_create(multiqueue_oneshot_event, data);
}
static void multiqueue_oneshot_event(void **argv)
{

View File

@ -9,7 +9,9 @@ typedef struct multiqueue MultiQueue;
typedef void (*PutCallback)(MultiQueue *multiq, void *data);
#define multiqueue_put(q, h, ...) \
multiqueue_put_event(q, event_create(h, __VA_ARGS__));
do { \
multiqueue_put_event(q, event_create(h, __VA_ARGS__)); \
} while (0)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/multiqueue.h.generated.h"

View File

@ -132,7 +132,7 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
Process *proc = (*current)->data;
if (proc->detach || proc->type == kProcessTypePty) {
// Close handles to process without killing it.
CREATE_EVENT(loop->events, process_close_handles, 1, proc);
CREATE_EVENT(loop->events, process_close_handles, proc);
} else {
process_stop(proc);
}
@ -300,7 +300,7 @@ static void decref(Process *proc)
}
assert(node);
kl_shift_at(WatcherPtr, loop->children, node);
CREATE_EVENT(proc->events, process_close_event, 1, proc);
CREATE_EVENT(proc->events, process_close_event, proc);
}
static void process_close(Process *proc)
@ -395,7 +395,7 @@ static void process_close_handles(void **argv)
static void exit_delay_cb(uv_timer_t *handle)
{
uv_timer_stop(&main_loop.exit_delay_timer);
multiqueue_put(main_loop.fast_events, exit_event, 1, main_loop.exit_delay_timer.data);
multiqueue_put(main_loop.fast_events, exit_event, main_loop.exit_delay_timer.data);
}
static void exit_event(void **argv)
@ -420,7 +420,7 @@ static void exit_event(void **argv)
void exit_from_channel(int status)
{
multiqueue_put(main_loop.fast_events, exit_event, 1, status);
multiqueue_put(main_loop.fast_events, exit_event, (void *)(intptr_t)status);
}
static void on_process_exit(Process *proc)
@ -438,7 +438,7 @@ static void on_process_exit(Process *proc)
// more data directly. Instead delay the reading after the libuv loop by
// queueing process_close_handles() as an event.
MultiQueue *queue = proc->events ? proc->events : loop->events;
CREATE_EVENT(queue, process_close_handles, 1, proc);
CREATE_EVENT(queue, process_close_handles, proc);
}
static void on_process_stream_close(Stream *stream, void *data)

View File

@ -200,10 +200,6 @@ static void invoke_read_cb(Stream *stream, size_t count, bool eof)
// Don't let the stream be closed before the event is processed.
stream->pending_reqs++;
CREATE_EVENT(stream->events,
read_event,
3,
stream,
(void *)(uintptr_t *)count,
(void *)(uintptr_t)eof);
CREATE_EVENT(stream->events, read_event,
stream, (void *)(uintptr_t *)count, (void *)(uintptr_t)eof);
}

View File

@ -47,7 +47,7 @@ static void signal_event(void **argv)
static void signal_watcher_cb(uv_signal_t *handle, int signum)
{
SignalWatcher *watcher = handle->data;
CREATE_EVENT(watcher->events, signal_event, 1, watcher);
CREATE_EVENT(watcher->events, signal_event, watcher);
}
static void close_cb(uv_handle_t *handle)

View File

@ -174,8 +174,7 @@ static void connection_event(void **argv)
static void connection_cb(uv_stream_t *handle, int status)
{
SocketWatcher *watcher = handle->data;
CREATE_EVENT(watcher->events, connection_event, 2, watcher,
(void *)(uintptr_t)status);
CREATE_EVENT(watcher->events, connection_event, watcher, (void *)(uintptr_t)status);
}
static void close_cb(uv_handle_t *handle)

View File

@ -52,7 +52,7 @@ static void time_watcher_cb(uv_timer_t *handle)
// the timer blocked and there already is an unprocessed event waiting
return;
}
CREATE_EVENT(watcher->events, time_event, 1, watcher);
CREATE_EVENT(watcher->events, time_event, watcher);
}
static void close_event(void **argv)
@ -66,6 +66,6 @@ static void close_cb(uv_handle_t *handle)
{
TimeWatcher *watcher = handle->data;
if (watcher->close_cb) {
CREATE_EVENT(watcher->events, close_event, 1, watcher);
CREATE_EVENT(watcher->events, close_event, watcher);
}
}

View File

@ -208,7 +208,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags
const char *error = lua_tostring(lstate, -1);
multiqueue_put(main_loop.events, nlua_luv_error_event,
2, xstrdup(error), (intptr_t)kCallback);
xstrdup(error), (void *)(intptr_t)kCallback);
lua_pop(lstate, 1); // error message
retval = -status;
} else { // LUA_OK
@ -266,11 +266,11 @@ static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nres
const char *error = lua_tostring(lstate, -1);
loop_schedule_deferred(&main_loop,
event_create(nlua_luv_error_event, 2,
event_create(nlua_luv_error_event,
xstrdup(error),
is_callback
? (intptr_t)kThreadCallback
: (intptr_t)kThread));
(void *)(intptr_t)(is_callback
? kThreadCallback
: kThread)));
lua_pop(lstate, 1); // error message
retval = -status;
} else { // LUA_OK
@ -379,8 +379,7 @@ static int nlua_schedule(lua_State *const lstate)
LuaRef cb = nlua_ref_global(lstate, 1);
multiqueue_put(main_loop.events, nlua_schedule_event,
1, (void *)(ptrdiff_t)cb);
multiqueue_put(main_loop.events, nlua_schedule_event, (void *)(ptrdiff_t)cb);
return 0;
}
@ -1022,15 +1021,14 @@ static int nlua_print(lua_State *const lstate)
if (is_thread) {
loop_schedule_deferred(&main_loop,
event_create(nlua_print_event, 2,
event_create(nlua_print_event,
msg_ga.ga_data,
(intptr_t)msg_ga.ga_len));
(void *)(intptr_t)msg_ga.ga_len));
} else if (in_fast_callback) {
multiqueue_put(main_loop.events, nlua_print_event,
2, msg_ga.ga_data, (intptr_t)msg_ga.ga_len);
msg_ga.ga_data, (void *)(intptr_t)msg_ga.ga_len);
} else {
nlua_print_event((void *[]){ msg_ga.ga_data,
(void *)(intptr_t)msg_ga.ga_len });
nlua_print_event((void *[]){ msg_ga.ga_data, (void *)(intptr_t)msg_ga.ga_len });
}
return 0;

View File

@ -871,7 +871,7 @@ void msg_schedule_semsg(const char *const fmt, ...)
va_end(ap);
char *s = xstrdup(IObuff);
loop_schedule_deferred(&main_loop, event_create(msg_semsg_event, 1, s));
loop_schedule_deferred(&main_loop, event_create(msg_semsg_event, s));
}
static void msg_semsg_multiline_event(void **argv)
@ -889,7 +889,7 @@ void msg_schedule_semsg_multiline(const char *const fmt, ...)
va_end(ap);
char *s = xstrdup(IObuff);
loop_schedule_deferred(&main_loop, event_create(msg_semsg_multiline_event, 1, s));
loop_schedule_deferred(&main_loop, event_create(msg_semsg_multiline_event, s));
}
/// Like msg(), but truncate to a single line if p_shm contains 't', or when

View File

@ -404,7 +404,7 @@ static void handle_request(Channel *channel, Unpacker *p, Array args)
if (is_get_mode && !input_blocking()) {
// Defer the event to a special queue used by os/input.c. #6247
multiqueue_put(ch_before_blocking_events, request_event, 1, evdata);
multiqueue_put(ch_before_blocking_events, request_event, evdata);
} else {
// Invoke immediately.
request_event((void **)&evdata);
@ -412,12 +412,11 @@ static void handle_request(Channel *channel, Unpacker *p, Array args)
} else {
bool is_resize = p->handler.fn == handle_nvim_ui_try_resize;
if (is_resize) {
Event ev = event_create_oneshot(event_create(request_event, 1, evdata),
2);
Event ev = event_create_oneshot(event_create(request_event, evdata), 2);
multiqueue_put_event(channel->events, ev);
multiqueue_put_event(resize_events, ev);
} else {
multiqueue_put(channel->events, request_event, 1, evdata);
multiqueue_put(channel->events, request_event, evdata);
DLOG("RPC: scheduled %.*s", (int)p->method_name_len, p->handler.name);
}
}
@ -484,7 +483,7 @@ static bool channel_write(Channel *channel, WBuffer *buffer)
if (channel->streamtype == kChannelStreamInternal) {
channel_incref(channel);
CREATE_EVENT(channel->events, internal_read_event, 2, channel, buffer);
CREATE_EVENT(channel->events, internal_read_event, channel, buffer);
success = true;
} else {
Stream *in = channel_instream(channel);

View File

@ -88,7 +88,7 @@ static void create_cursorhold_event(bool events_enabled)
// TODO(tarruda): Cursorhold should be implemented as a timer set during the
// `state_check` callback for the states where it can be triggered.
assert(!events_enabled || multiqueue_empty(main_loop.events));
multiqueue_put(main_loop.events, cursorhold_event, 0);
multiqueue_put(main_loop.events, cursorhold_event, NULL);
}
static void restart_cursorhold_wait(int tb_change_cnt)

View File

@ -742,7 +742,7 @@ static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *da
TermInput *input = data;
if (eof) {
loop_schedule_fast(&main_loop, event_create(tinput_done_event, 0));
loop_schedule_fast(&main_loop, event_create(tinput_done_event, NULL));
return;
}

View File

@ -276,7 +276,7 @@ static void ui_refresh_event(void **argv)
void ui_schedule_refresh(void)
{
multiqueue_put(resize_events, ui_refresh_event, 0);
multiqueue_put(resize_events, ui_refresh_event, NULL);
}
void ui_default_colors_set(void)

View File

@ -6,7 +6,7 @@
void ut_multiqueue_put(MultiQueue *self, const char *str)
{
multiqueue_put(self, NULL, 1, str);
multiqueue_put(self, NULL, (void *)str);
}
const char *ut_multiqueue_get(MultiQueue *self)